カーネルパニックが発生した瞬間、サーバーは沈黙する。SSH接続は途切れ、コンソールには大量のスタックトレースが流れ、再起動後には何が起きたかを追う手がかりが消えてしまう。
「せめてクラッシュ直前のカーネル状態を記録できていたら」。この痛みを知っているエンジニアは少なくないはずだ。
この記事では、カーネルパニックが発生した直後に kdump でvmcoreを採取し、crashコマンドで初動解析するまでの一連の流れを解説する。対象環境はRHEL 9.x / Rocky Linux 9(RHEL 8系でも基本手順は同様)。kexecカーネルの仕組みから設定・テスト・解析まで、重障害調査の全プロセスを体系的に押さえる。
この記事のポイント
・kdumpはkexecで第2カーネルを起動しvmcoreを保存するLinux標準機能
・crashkernel=パラメータとkexec-toolsのインストールで有効化できる
・crashコマンドのbt/log/sysでパニック原因とスタックを特定できる
・本番投入前にsysrq+cでテストクラッシュし動作確認を済ませること
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
カーネルパニックとoopsの違い——重障害を見極める
カーネルパニックとkernel oopsは混同されやすいが、その性質はまったく異なる。・Kernel Oops:カーネルがエラーを検出したが処理を継続できると判断した診断メッセージ。プロセスが終了することもあるが、カーネル自体は動き続ける。
・Kernel Panic:カーネルが「これ以上安全に動作できない」と判断し、処理を即座に停止する致命的エラー。
panic()関数が呼ばれると、その後の回復は不可能だ。カーネルパニックが発生する主な原因を挙げる。
・ハードウェア障害(メモリ不良・CPUエラー・PCIeバスエラー)
・ドライバの
BUG()マクロ呼び出し(NULLポインタ参照・配列境界超え)・NMI watchdog によるCPU stall検出(22秒以上CPUが応答しない場合)
・カーネル空間での無効メモリアクセス(ページフォルトのハンドル不能)
・ext4/XFSなどのファイルシステムが内部矛盾を検出した場合
パニック後に自動再起動させるには
/proc/sys/kernel/panic に秒数を設定するが、vmcoreを採取したい場合は後述のkdumpとの組み合わせが必要だ。dmesgとシリアルコンソールで初期ログを確保する
kdumpが未設定の環境でパニックが発生した場合も、次の2つの手がかりが残ることがある。1. 再起動後のdmesg / journald確認
再起動後にpstoreやRAMのリングバッファが残っている場合は、以下で素早く絞り込める。dmesg | grep -E 'panic|Oops|BUG|Call Trace|RIP:|RSP:' | head -50
# /var/log/journal を作成してpersistentモードに切り替える mkdir -p /var/log/journal systemd-tmpfiles --create --prefix /var/log/journal systemctl restart systemd-journald # 再起動後に前回ブートのパニックログを参照 journalctl -b -1 | grep -E 'panic|Oops|BUG|Call Trace'
Storage=persistent を設定することで、以後も自動的に永続化される。2. シリアルコンソールへのパニック出力設定
物理サーバーやIPMI/BMC環境では、シリアルコンソールへのパニックメッセージ出力を設定しておくと確実だ。/etc/default/grub の GRUB_CMDLINE_LINUX に以下を追加してGRUBを再生成する。# /etc/default/grub — GRUB_CMDLINE_LINUX に追記 # console=tty0 の前に console=ttyS0,115200n8 を追加する例: # GRUB_CMDLINE_LINUX="... console=tty0 console=ttyS0,115200n8" # UEFI環境でのgrub.cfg再生成 grub2-mkconfig -o /boot/grub2/grub.cfg
kdumpの仕組み——kexecカーネルが担う役割
kdumpはLinuxカーネルのkexec機能を利用して実現される。通常のブートとの違いを整理しておく。通常の起動フロー
BIOS/UEFI > GRUB > メインカーネル > systemd > 通常運用
パニック発生時のkdumpフロー
メインカーネルがパニック > kexecが事前にメモリ配置済みの「キャプチャカーネル」を即時ロード > キャプチャカーネルが起動 > クラッシュしたカーネルのメモリ(vmcore)をファイルに保存 > 再起動
ポイントは「GRUBを経由しない」点だ。kexecはBIOS/UEFIのPOSTをスキップして直接カーネルをロードするため、パニックからvmcore保存までが短時間で完了する。
キャプチャカーネル用のメモリ予約(crashkernel=)
メインカーネルの起動時に、キャプチャカーネル専用のメモリを事前に予約しておく必要がある。これが
crashkernel= カーネルパラメータだ。RHEL 9 / Rocky Linux 9 では以下のサイズが推奨されている。# メモリ容量に応じた自動割り当て(RHEL 9推奨値) # crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M # autoに任せる(RHEL 8以降で利用可能) crashkernel=auto
crashkernel reservation failed と出る)ため、物理メモリ容量に合わせて適切に設定する。kdumpのインストールと設定(crashkernel= と /etc/kdump.conf)
1. kexec-toolsのインストール
# RHEL 9 / Rocky Linux 9 dnf install -y kexec-tools systemctl enable --now kdump
crashkernel= が設定されていなければkdumpサービスはinactive(dead)のままになる。次ステップでパラメータを設定すれば active になる。2. crashkernel= パラメータの設定
# 現在のカーネルパラメータを確認 cat /proc/cmdline # crashkernelが含まれていない場合、grubに追記 vi /etc/default/grub # GRUB_CMDLINE_LINUX の末尾に crashkernel=auto を追加 # UEFI環境でのgrub.cfg再生成 grub2-mkconfig -o /boot/grub2/grub.cfg # BIOS(MBR)環境の場合は以下のパスになることがある # grub2-mkconfig -o /boot/grub2/grub.cfg ← 同じパスで可
# crashkernelが含まれていることを確認 cat /proc/cmdline | grep crashkernel # 出力例: ... crashkernel=auto ... # kdumpサービスの状態確認 systemctl status kdump # Active: active (exited) ← これが正常状態
3. /etc/kdump.conf の設定
保存先やコアコレクタのオプションを制御するメイン設定ファイルだ。# /etc/kdump.conf (主要設定項目) # vmcoreの保存先(デフォルト: /var/crash) path /var/crash # makedumpfile: 圧縮とフィルタリング # -l: LZO圧縮 --message-level 1: 最小限のメッセージ # -d 31: ゼロページ・キャッシュ・空きページ・ユーザーデータ・HugePage除外 core_collector makedumpfile -l --message-level 1 -d 31 # NFS保存の例(オプション) # nfs 192.168.1.10:/export/kdump # ssh user@192.168.1.10
-d 31 はvmcoreのサイズを大幅に削減できる。ただし、ユーザー空間の情報が必要な解析では除外するか値を小さくすること。設定変更後はkdumpを再起動する。
systemctl restart kdump systemctl status kdump
4. 保存先ディレクトリの空き容量確認
makedumpfileで圧縮してもvmcoreは数GB規模になることがある。/var/crash の空き容量を確認しておく。df -h /var/crash
vmcoreの採取確認——sysrqによるテストクラッシュ
本番環境に組み込む前に、必ずテストクラッシュを実施すること。 kdumpの設定が正しくても、保存先の容量不足やNFS未マウントなどで実際の採取に失敗するケースがある。事前検証が後の分水嶺になる。【注意】 以下のコマンドは即座にカーネルをクラッシュさせる。テスト環境または作業ウィンドウを確保した本番環境でのみ実施すること。
# sysrqを有効化 echo 1 > /proc/sys/kernel/sysrq # 強制クラッシュ(実行直後にSSH接続は切れる) echo c > /proc/sysrq-trigger
# 保存先ディレクトリの確認 ls -lh /var/crash/ # 出力例: # drwxr-x--- 2 root root 4.0K Jul 25 10:23 127.0.0.1-2026-07-25-10:23:14/ ls -lh /var/crash/127.0.0.1-2026-07-25-10:23:14/ # 出力例: # -rw------- 1 root root 312M Jul 25 10:23 vmcore # -rw-r--r-- 1 root root 1.6K Jul 25 10:23 vmcore-dmesg.txt
vmcore-dmesg.txt にはクラッシュ時点のカーネルメッセージが保存されており、vmcoreを開く前の最初の手がかりになる。cat /var/crash/127.0.0.1-2026-07-25-10:23:14/vmcore-dmesg.txt | tail -50
crashコマンドによる初動解析——bt・log・vmの実践
1. crashパッケージとデバッグシンボルのインストール
# crashコマンド本体 dnf install -y crash # カーネルデバッグシンボル(uname -r と完全一致するものが必要) dnf install -y kernel-debuginfo-$(uname -r)
debuginfo-install コマンドまたはRed Hat CDN / Rocky Linuxのdebuginfodから取得する。2. crashの起動
crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/127.0.0.1-2026-07-25-10:23:14/vmcore
crash> プロンプトが表示される。以下のコマンドで解析を進める。3. sys——パニック原因を最初に確認する
crash> sys NODENAME: rocky9.localdomain RELEASE: 5.14.0-362.8.1.el9_3.x86_64 VERSION: #1 SMP PREEMPT_DYNAMIC ... MACHINE: x86_64 (2800 Mhz) MEMORY: 8 GB PANIC: "sysrq: Trigger a crash" PID: 1234 COMMAND: "bash" DATE: Fri Jul 25 10:23:10 2026 UPTIME: 00:05:14
PANIC: 行がパニックの原因文字列そのものだ。ここを最初に確認することで解析の方向性が定まる。4. log——パニック直前のカーネルメッセージ
# リングバッファ全体を表示 crash> log # 直前の30行に絞る(BUG: や Kernel panic - の行を探す) crash> log | tail -30
5. bt——クラッシュ時のバックトレース
どの関数でパニックが発生したかが一目でわかる。crash> bt PID: 0 TASK: ffffffff826183c0 CPU: 0 COMMAND: "swapper/0" #0 [fffffe0000008e40] machine_kexec at ffffffff810665cf #1 [fffffe0000008ea0] __crash_kexec at ffffffff81120001 #2 [fffffe0000008f68] panic at ffffffff8118a5b7 #3 [fffffe0000008ff0] sysrq_handle_crash at ffffffff81a2fe34
# 特定PIDのbt crash> bt 1234 # 全タスクのbtを一括表示(大規模サーバーでは時間がかかる) crash> bt -a
6. vm——仮想メモリと不正アドレスの確認
# カレントタスクのvm情報 crash> vm # 特定プロセスのvm情報 crash> vm 1234
7. ps——クラッシュ時点のプロセス一覧
# 全プロセス一覧 crash> ps # 実行中(RU状態)のプロセスを絞る crash> ps | grep RU
8. crashの終了
crash> quit
パニック原因の類型とトラブルシュートの要点
カーネルパニックのメッセージはパターン化されており、ある程度原因を絞り込める。パターン1: NULLポインタ参照 / 不正メモリアクセス
BUG: kernel NULL pointer dereference, address: 0000000000000000
・ECC RAMサーバーではIPMIのSEL(システムイベントログ)でメモリ訂正エラーが積み重なっていないか確認する。サーバーのメモリ/ハードウェア情報確認にはdmidecodeコマンドでハードウェア情報を取得する方法が参考になる
パターン2: NMI watchdog / soft lockup
watchdog: BUG: soft lockup - CPU#0 stuck for 22s! Kernel panic - not syncing: hung_task: blocked tasks
・/var/log/messages(または
journalctl)でI/Oエラーが先行して発生していないか確認する・ストレージのI/Oタイムアウトが引き金になるケースが現場では頻出だ
パターン3: ファイルシステムBUG
kernel BUG at fs/ext4/inode.c:1234!
・
fsck でファイルシステム整合性を確認し、ディスクのS.M.A.R.T.値もチェックするパターン4: スタックオーバーフロー
Kernel panic - not syncing: stack-protector: Kernel stack is corrupted
・btを取得し、再帰している関数を特定する
kdump設定後にシステム起動時間がどう変化したかを確認したい場合は、systemd-analyzeで起動時間を計測する方法が役に立つ。
本記事のまとめ
重障害の現場では、vmcoreの有無が「解析できるか否か」の分水嶺になる。kdumpの設定はパニックが起きてからでは間に合わない。本番投入前にテストクラッシュで動作確認まで完了させておくことを強く推奨する。| やりたいこと | コマンド / 手順 |
|---|---|
| kdumpインストール | dnf install -y kexec-tools |
| kdumpサービス起動・有効化 | systemctl enable --now kdump |
| crashkernel=確認 | cat /proc/cmdline |
| grub再生成(UEFI) | grub2-mkconfig -o /boot/grub2/grub.cfg |
| kdump設定再読み込み | systemctl restart kdump |
| テストクラッシュ実施 | echo c > /proc/sysrq-trigger |
| vmcore保存確認 | ls -lh /var/crash/ |
| crash起動 | crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/.../vmcore |
| パニック原因確認 | crash> sys |
| バックトレース表示 | crash> bt |
| カーネルログ確認 | crash> log |
上位サービスの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:Linuxでコアダンプを取得・解析する方法|systemd-coredumpとcoredumpctlでプロセス異常終了を調査する
- この記事の属するカテゴリ:Linuxトラブルシューティングへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます