Linuxシステムの運用において、トラブルシューティングは避けて通れないスキルです。サービスが突然停止した、ディスク容量が枯渇した、ネットワーク接続が不安定になったなど、さまざまな問題に直面することがあります。しかし、闘雲に対処するのではなく、論理的なアプローチで問題を切り分けることで、効率的に原因を特定し解決できるようになります。

この記事では、Linuxトラブルシューティングの基本的な考え方、情報収集の手法、よくあるエラーパターンと対処法、そして問題を再現して原因を特定するまでの一連の手順を解説します。

前提条件と動作確認環境

本記事の内容は以下の環境で動作確認しています。

項目 内容
OS Ubuntu 24.04 LTS / AlmaLinux 9
systemd 255以上
シェル bash 5.2
権限 一部コマンドでsudo権限が必要

基本的なLinuxコマンドライン操作(ファイル操作、プロセス確認、ログ閲覧など)ができることを前提としています。

Linuxトラブルシューティングの基本アプローチ

効果的なトラブルシューティングには、体系的なアプローチが不可欠です。問題に直面したとき、以下のフレームワークに従って進めることで、見落としを防ぎ、効率的に原因を特定できます。

トラブルシューティングの5ステップ

flowchart TD
    A[1. 問題の定義] --> B[2. 情報収集]
    B --> C[3. 仮説の立案]
    C --> D[4. 仮説の検証]
    D --> E{原因特定?}
    E -->|No| C
    E -->|Yes| F[5. 解決と記録]
    
    style A fill:#e1f5fe
    style B fill:#fff3e0
    style C fill:#f3e5f5
    style D fill:#e8f5e9
    style F fill:#fce4ec
ステップ 内容 重要なポイント
1. 問題の定義 何が起きているか明確にする 「動かない」ではなく具体的な症状を特定
2. 情報収集 ログ、エラー、システム状態を確認 変更履歴、発生時刻、影響範囲を把握
3. 仮説の立案 収集した情報から原因を推測 最も可能性の高いものから検証
4. 仮説の検証 仮説が正しいか確認する 一度に一つの変更のみ実施
5. 解決と記録 問題を修正し、文書化する 再発防止策も検討

問題を正確に定義する

「サーバーが動かない」という曖昧な報告では、効果的なトラブルシューティングは困難です。問題を正確に定義するために、以下の質問に答えられるようにしましょう。

1
2
3
4
5
6
7
8
# 問題定義のためのチェックリスト
# - いつから発生しているか?
# - 何が動かない/遅いのか?(具体的なサービス、機能)
# - どの環境で発生しているか?(本番、ステージング、特定サーバー)
# - 誰が影響を受けているか?(全ユーザー、特定ユーザー)
# - どのような操作をしたときに発生するか?
# - エラーメッセージは出ているか?
# - 最近システムに変更を加えたか?

変更管理の重要性

多くの障害は、システム変更後に発生します。問題発生時には、最近の変更を確認することが重要です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# パッケージの更新履歴を確認(Debian/Ubuntu系)
cat /var/log/apt/history.log | tail -50

# パッケージの更新履歴を確認(RHEL/AlmaLinux系)
sudo dnf history
sudo dnf history info <transaction-id>

# 最近変更されたファイルを確認
find /etc -type f -mtime -1 -ls 2>/dev/null

# 最近のシステム起動を確認
who -b
uptime

期待される出力:

# dnf historyの出力例
ID     | Command line             | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
    15 | install nginx            | 2026-01-08 10:30 | Install        |   1
    14 | update                   | 2026-01-07 09:00 | Upgrade        |  23

情報収集の方法

トラブルシューティングで最も重要なのは、適切な情報を収集することです。闇雲にコマンドを実行するのではなく、目的を持って情報を集めましょう。

ログからの情報収集

Linuxシステムでは、ほぼすべてのサービスがログを出力しています。ログは問題解決の最も重要な手がかりとなります。

systemd journalによるログ確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# システム全体の最新ログを確認
journalctl -xe

# 特定サービスのログを確認
journalctl -u nginx.service --since "1 hour ago"

# エラーレベル以上のログのみ表示
journalctl -p err --since today

# リアルタイムでログを監視
journalctl -f

# 特定の時間範囲のログを確認
journalctl --since "2026-01-08 10:00:00" --until "2026-01-08 12:00:00"

# ブート関連のログを確認
journalctl -b -1  # 前回起動時のログ

従来のログファイルの確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# システムログの確認(Debian/Ubuntu系)
sudo tail -100 /var/log/syslog

# システムログの確認(RHEL/AlmaLinux系)
sudo tail -100 /var/log/messages

# 認証ログの確認
sudo tail -50 /var/log/auth.log    # Debian/Ubuntu
sudo tail -50 /var/log/secure       # RHEL/AlmaLinux

# アプリケーション固有のログ
sudo tail -100 /var/log/nginx/error.log
sudo tail -100 /var/log/mysql/error.log

ログ検索のテクニック

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 特定のキーワードでフィルタリング
journalctl | grep -i "error\|fail\|warn"

# 特定時刻以降のエラーを抽出
journalctl -p err --since "2026-01-08 09:00:00" --no-pager

# ログをJSON形式で出力(スクリプト処理用)
journalctl -o json-pretty -n 10

# 複数条件でのフィルタリング
journalctl _SYSTEMD_UNIT=sshd.service + _SYSTEMD_UNIT=nginx.service

エラーメッセージの読み解き方

エラーメッセージは問題解決の重要な手がかりです。以下のポイントに注目して読み解きましょう。

flowchart LR
    A[エラーメッセージ] --> B[タイムスタンプ]
    A --> C[重要度レベル]
    A --> D[発生元]
    A --> E[エラー内容]
    A --> F[コンテキスト情報]
    
    B --> G[いつ発生?]
    C --> H[緊急度は?]
    D --> I[どのサービス?]
    E --> J[何が問題?]
    F --> K[関連情報]

エラーメッセージの構造を理解する例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 典型的なエラーメッセージの例
# Jan 08 10:30:45 webserver nginx[1234]: 2026/01/08 10:30:45 [error] 1234#0: 
#   *5678 open() "/var/www/html/missing.html" failed (2: No such file or directory)

# 分解すると:
# - タイムスタンプ: Jan 08 10:30:45
# - ホスト名: webserver
# - サービス名[PID]: nginx[1234]
# - 重要度: [error]
# - 詳細: ファイルが見つからない

システム状態の確認

問題発生時には、システム全体の状態を素早く把握することが重要です。

システムリソースの確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# CPU・メモリの概要を確認
top -bn1 | head -20

# メモリ使用状況の詳細
free -h
cat /proc/meminfo | head -10

# ディスク使用状況
df -h
df -i  # inode使用状況

# ディスクI/O状況
iostat -x 1 3

# 負荷状況の確認
uptime
cat /proc/loadavg

期待される出力(freeコマンド):

              total        used        free      shared  buff/cache   available
Mem:           7.7Gi       2.1Gi       3.2Gi       156Mi       2.4Gi       5.2Gi
Swap:          2.0Gi          0B       2.0Gi

プロセス状態の確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 実行中のプロセス一覧
ps aux --sort=-%mem | head -20  # メモリ使用量順
ps aux --sort=-%cpu | head -20  # CPU使用量順

# 特定サービスのプロセス確認
pgrep -a nginx
pgrep -a mysql

# プロセスツリーの表示
pstree -p

# ゾンビプロセスの確認
ps aux | awk '$8 ~ /Z/'

ネットワーク状態の確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# ネットワークインターフェースの状態
ip addr show
ip link show

# ルーティングテーブル
ip route show

# 接続状況の確認
ss -tuln  # リッスンポート一覧
ss -tunp  # 確立済み接続

# 特定ポートの使用状況
ss -tulnp | grep :80

# DNS解決の確認
dig example.com
nslookup example.com

サービス状態の確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# サービスの状態確認
systemctl status nginx

# 全サービスの状態一覧
systemctl list-units --type=service --state=failed

# サービスの依存関係確認
systemctl list-dependencies nginx

# サービス起動の詳細ログ
journalctl -u nginx --no-pager -n 50

期待される出力(systemctl status):

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-01-08 10:00:00 JST; 2h ago
       Docs: man:nginx(8)
    Process: 1234 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 1235 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 1236 (nginx)
      Tasks: 3 (limit: 9449)
     Memory: 8.5M
        CPU: 52ms
     CGroup: /system.slice/nginx.service
             ├─1236 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             ├─1237 "nginx: worker process"
             └─1238 "nginx: worker process"

よくあるエラーパターンと対処法

Linuxシステムで頻繁に遭遇するエラーパターンと、その対処法を紹介します。

パターン1: Permission denied(権限エラー)

最も一般的なエラーの一つです。ファイルやディレクトリへのアクセス権限が不足している場合に発生します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# エラー例
$ cat /var/log/secure
cat: /var/log/secure: Permission denied

# 対処法1: 権限を確認
ls -la /var/log/secure

# 対処法2: 適切な権限で実行
sudo cat /var/log/secure

# 対処法3: ファイルの所有者・権限を修正(必要な場合)
sudo chown appropriate_user:appropriate_group /path/to/file
sudo chmod 644 /path/to/file

Webサーバーでよく発生するケース:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Nginxがファイルにアクセスできない場合
# エラーログ: open() "/var/www/html/index.html" failed (13: Permission denied)

# ファイルの権限確認
ls -la /var/www/html/

# Nginxの実行ユーザー確認
ps aux | grep nginx

# 権限の修正
sudo chown -R www-data:www-data /var/www/html/
sudo chmod -R 755 /var/www/html/

パターン2: No space left on device(ディスク容量不足)

ディスク容量が枯渇すると、サービスの動作に深刻な影響を与えます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# エラー例
$ touch /var/log/test.log
touch: cannot touch '/var/log/test.log': No space left on device

# ディスク使用状況の確認
df -h

# 大きなファイルの特定
sudo du -sh /* 2>/dev/null | sort -hr | head -20
sudo du -sh /var/* 2>/dev/null | sort -hr | head -10

# 削除済みだがプロセスが掴んでいるファイルを確認
sudo lsof +L1

# 古いログファイルの圧縮・削除
sudo journalctl --vacuum-size=500M
sudo find /var/log -name "*.gz" -mtime +30 -delete

# inode枯渇の確認(小さなファイルが大量にある場合)
df -i

期待される出力(df -h):

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   48G  2.0G  96% /
tmpfs           3.9G     0  3.9G   0% /dev/shm
/dev/sda2       100G   20G   80G  20% /home

パターン3: Connection refused(接続拒否)

サービスが起動していない、またはポートがリッスンされていない場合に発生します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# エラー例
$ curl http://localhost:80
curl: (7) Failed to connect to localhost port 80: Connection refused

# 対処法1: サービスの状態確認
systemctl status nginx

# 対処法2: ポートのリッスン状態確認
ss -tulnp | grep :80

# 対処法3: サービスの起動
sudo systemctl start nginx

# 対処法4: ファイアウォールの確認
sudo iptables -L -n
sudo firewall-cmd --list-all  # firewalldの場合
sudo ufw status               # ufwの場合

パターン4: Name or service not known(DNS解決失敗)

ホスト名が解決できない場合に発生します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# エラー例
$ ping example.com
ping: example.com: Name or service not known

# 対処法1: DNS設定の確認
cat /etc/resolv.conf

# 対処法2: DNS解決のテスト
dig example.com
nslookup example.com

# 対処法3: /etc/hostsの確認
cat /etc/hosts

# 対処法4: 特定のDNSサーバーを指定してテスト
dig @8.8.8.8 example.com

# 対処法5: nsswitch.confの確認
cat /etc/nsswitch.conf | grep hosts

パターン5: Out of memory(メモリ不足・OOMキラー)

メモリが不足すると、OOMキラーがプロセスを強制終了します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# OOMキラーの発動を確認
dmesg | grep -i "out of memory"
journalctl -k | grep -i "oom"

# メモリ使用状況の確認
free -h
cat /proc/meminfo

# メモリを大量消費しているプロセスの特定
ps aux --sort=-%mem | head -10

# スワップ使用状況
swapon --show

# OOMスコアの確認(値が大きいほど終了されやすい)
cat /proc/$(pgrep nginx)/oom_score

パターン6: サービス起動失敗

サービスが起動しない場合の調査手順です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# エラー例
$ sudo systemctl start nginx
Job for nginx.service failed because the control process exited with error code.

# 対処法1: 詳細なステータス確認
systemctl status nginx -l

# 対処法2: ジャーナルログの確認
journalctl -xe -u nginx

# 対処法3: 設定ファイルの文法チェック
sudo nginx -t

# 対処法4: 依存サービスの確認
systemctl list-dependencies nginx

# 対処法5: ポート競合の確認
ss -tulnp | grep :80

問題の再現と原因特定の手順

複雑な問題を解決するには、問題を再現し、系統的に原因を絞り込むことが重要です。

問題再現の重要性

問題が再現できれば、修正の効果を確認できます。再現手順を明確にしましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 再現手順を文書化する例
# 1. 環境情報
cat /etc/os-release
uname -a

# 2. 事前状態の記録
systemctl status myservice
ss -tulnp | grep :8080

# 3. 再現操作
curl -v http://localhost:8080/api/endpoint

# 4. 結果の記録
echo $?  # 終了コード

二分探索による原因特定

変更箇所が多い場合、二分探索で効率的に原因を絞り込みます。

flowchart TD
    A[問題発生] --> B[変更点のリストアップ]
    B --> C[変更を半分に分割]
    C --> D[前半の変更のみ適用]
    D --> E{問題発生?}
    E -->|Yes| F[前半に原因あり]
    E -->|No| G[後半に原因あり]
    F --> H[さらに半分に分割]
    G --> H
    H --> I[原因を特定]

仮説検証のアプローチ

仮説を立てて一つずつ検証することで、効率的に原因を特定できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 仮説1: ディスク容量不足
df -h
# 結果: 容量に余裕あり → 仮説棄却

# 仮説2: メモリ不足
free -h
# 結果: メモリ使用率95% → 仮説採用、詳細調査

# 仮説2の詳細調査
ps aux --sort=-%mem | head -10
# 結果: 特定プロセスがメモリを大量消費

# 対処と検証
sudo systemctl restart problematic-service
free -h
# 結果: メモリ使用率が50%に低下、問題解決

最小再現環境の構築

複雑な問題は、最小限の構成で再現することで原因を特定しやすくなります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 設定ファイルを最小構成にして起動テスト
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
sudo cat > /etc/nginx/nginx.conf.minimal << 'EOF'
events {
    worker_connections 1024;
}

http {
    server {
        listen 80;
        root /var/www/html;
    }
}
EOF

# 最小構成でテスト
sudo nginx -t -c /etc/nginx/nginx.conf.minimal
sudo nginx -c /etc/nginx/nginx.conf.minimal

# テスト後、元に戻す
sudo mv /etc/nginx/nginx.conf.backup /etc/nginx/nginx.conf

トラブルシューティングツールキット

効率的なトラブルシューティングのために、よく使うコマンドをまとめておくと便利です。

情報収集用スクリプト

以下のスクリプトは、障害発生時に必要な情報を一括収集します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/bin/bash
# system-info-collector.sh
# 障害調査用の情報収集スクリプト

OUTPUT_DIR="/tmp/system-info-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$OUTPUT_DIR"

echo "システム情報を収集しています..."

# 基本情報
{
    echo "=== System Info ==="
    date
    hostname
    uname -a
    cat /etc/os-release
} > "$OUTPUT_DIR/system-info.txt"

# リソース情報
{
    echo "=== Memory ==="
    free -h
    echo ""
    echo "=== Disk ==="
    df -h
    echo ""
    echo "=== Load ==="
    uptime
    cat /proc/loadavg
} > "$OUTPUT_DIR/resources.txt"

# プロセス情報
{
    echo "=== Top Processes (CPU) ==="
    ps aux --sort=-%cpu | head -20
    echo ""
    echo "=== Top Processes (Memory) ==="
    ps aux --sort=-%mem | head -20
} > "$OUTPUT_DIR/processes.txt"

# ネットワーク情報
{
    echo "=== Network Interfaces ==="
    ip addr
    echo ""
    echo "=== Listening Ports ==="
    ss -tulnp
    echo ""
    echo "=== Routing Table ==="
    ip route
} > "$OUTPUT_DIR/network.txt"

# サービス状態
{
    echo "=== Failed Services ==="
    systemctl list-units --type=service --state=failed
    echo ""
    echo "=== All Services ==="
    systemctl list-units --type=service
} > "$OUTPUT_DIR/services.txt"

# 最新のログ
journalctl --since "1 hour ago" --no-pager > "$OUTPUT_DIR/journal-1h.txt"
journalctl -p err --since "24 hours ago" --no-pager > "$OUTPUT_DIR/errors-24h.txt"

# アーカイブ作成
tar czf "$OUTPUT_DIR.tar.gz" -C /tmp "$(basename $OUTPUT_DIR)"

echo "情報収集完了: $OUTPUT_DIR.tar.gz"

クイックリファレンス

トラブルシューティングでよく使うコマンドのチートシートです。

カテゴリ コマンド 用途
ログ journalctl -xe システムログの確認
ログ journalctl -u service -f サービスログのリアルタイム監視
ログ dmesg -T カーネルメッセージ
プロセス ps aux --sort=-%mem メモリ使用量順でプロセス一覧
プロセス top -bn1 リソース使用状況のスナップショット
プロセス pgrep -a processname プロセス検索
ディスク df -h ディスク使用状況
ディスク du -sh /* ディレクトリごとのサイズ
ディスク lsof +L1 削除されたが開いているファイル
メモリ free -h メモリ使用状況
メモリ vmstat 1 5 メモリとCPUの統計
ネットワーク ss -tulnp リッスンポート一覧
ネットワーク ip addr IPアドレス確認
ネットワーク ping -c 3 host 疎通確認
サービス systemctl status service サービス状態確認
サービス systemctl list-units --failed 失敗サービス一覧

トラブルシューティングのベストプラクティス

効果的なトラブルシューティングのために、以下のポイントを心がけましょう。

やるべきこと

  1. 落ち着いて対処する: パニックは判断を誤らせます
  2. 変更前にバックアップ: 設定変更前には必ずバックアップを取ります
  3. 一度に一つの変更: 複数の変更を同時に行うと、何が効果があったか分かりません
  4. ドキュメントを残す: 問題、調査内容、解決策を記録します
  5. エスカレーションの判断: 自分で解決できない場合は早めに助けを求めます

避けるべきこと

  1. 闇雲にサービスを再起動: 原因を調査せずに再起動すると、証拠が消えます
  2. 本番環境での実験: テスト環境で確認してから本番に適用します
  3. ログの削除: 問題が解決するまでログは保持します
  4. 根本原因を追わない: 表面的な対処だけでは再発します

障害対応の記録テンプレート

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
## 障害報告書

### 概要
- 発生日時: 2026-01-08 10:30 JST
- 復旧日時: 2026-01-08 11:15 JST
- 影響範囲: Webサービス全体
- 影響ユーザー数: 約1,000名

### 症状
- Webサイトへのアクセスで504エラーが発生
- APIレスポンスタイムが通常の10倍に増加

### 原因
- データベースサーバーのディスク容量が100%に達し、
  トランザクションログの書き込みが失敗

### 対処
1. 不要なログファイルを削除(20GB確保)
2. データベースサービスを再起動
3. アプリケーションサーバーを再起動

### 再発防止策
1. ディスク使用率80%でアラート設定
2. ログローテーション設定の見直し
3. ディスク容量の週次レポート作成

まとめ

Linuxトラブルシューティングは、体系的なアプローチと適切なツールの知識があれば、効率的に問題を解決できます。本記事で解説した内容を振り返ります。

  1. 基本アプローチ: 問題定義、情報収集、仮説立案、検証、解決の5ステップで進めます
  2. 情報収集: ログ、システム状態、エラーメッセージから手がかりを集めます
  3. よくあるパターン: 権限エラー、ディスク容量不足、接続拒否などの対処法を知っておきます
  4. 原因特定: 問題を再現し、二分探索や仮説検証で効率的に絞り込みます

トラブルシューティングスキルは、実践を通じて向上します。日頃からログの見方やコマンドの使い方に慣れておくことで、いざというときに冷静に対処できるようになります。

参考リンク