沈黙するサーバーフリーズという悪夢
かつて私は、1万件以上の同時接続を処理する本番データベースを管理していましたが、ある時システムが突然停止してしまいました。アラートも「Connection Refused」もなく、ただ完全な沈黙だけが残りました。ハードリセット後、/var/log/messages や <a href="https://itnotes.dev/ja/linux%e3%81%a7sysstat%e3%82%92%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%e3%81%99%e3%82%8b%ef%bc%9asar%e3%83%bbiostat%e3%83%bbmpstat%e3%81%a7%e6%96%ad%e7%b6%9a%e7%9a%84%e3%81%aa%e3%83%91%e3%83%95%e3%82%a9/">/var/log/syslog</a> を徹底的に調べましたが、何も見つかりませんでした。ログは14:02:15で途切れ、再起動後の14:05:40から再開されていたのです。その失われた3分間にこそ、答えがありました。
これがカーネルパニック(Kernel Panic)の厄介な点です。Linuxカーネルが致命的なエラーに遭遇すると、データを保護するために即座にフリーズします。カーネル自体が壊れているため、標準のログを書き出すことができません。5,000ドルのマザーボードが故障したのか、それともバグのあるドライバコード1行が原因なのか、見当もつかない状態に陥ります。多くの高トラフィックインスタンスを管理してきた経験から、私は「見えないものは直せない」ということを学びました。Kdumpは、ついにその中身を可視化してくれるツールです。
カーネル停止時に標準ログが機能しない理由
Kdumpが必要な理由を理解するには、クラッシュの構造を見る必要があります。標準的なアプリケーションが失敗した場合、カーネルは正常なままでコアダンプを書き出します。しかし、カーネルがクラッシュすると、システムの「脳」が機能しなくなります。CPUサイクルやディスクI/Oを管理できなくなるのです。ログを書き込むには、機能しているファイルシステムドライバが必要ですが、もしそのドライバ自体がクラッシュの原因だった場合、ログを書こうとすることでさらにデータを破損させる恐れがあります。
ほとんどのパニックは、以下の3つの要因から発生します:
- ハードウェア障害: 32GBのRAMスティックにおける1ビットの反転や、CPUの電圧降下。
- バグのあるカーネルモジュール: 特殊なNICやGPU用のサードパーティ製ドライバは、これらを引き起こすことで有名です。
- メモリのデッドロック: カーネルが動作を維持するために必要な特定のメモリ構造が不足する稀なシナリオ。
クラッシュキャプチャの選択肢を比較する
Kdumpにたどり着く前に、いくつかの方法を検討しました。それぞれに一長一短がありますが、現代のクラウド環境ではほとんどが通用しません。
- シリアルコンソール: 2台の物理マシンをケーブルで接続します。非常に堅牢ですが、500マイル離れたデータセンターにあるリモートVPSでは使用不可能です。
- Netconsole: UDP経由でカーネルログをブロードキャストします。何もないよりはマシですが、UDPは配信を保証しないため、システムが停止する直前の最も重要なパケットを失うことがよくあります。
- Kdump: これがゴールドスタンダード(標準)です。
<a href="https://itnotes.dev/ja/linux%e3%82%92%e6%95%b0%e7%a7%92%e3%81%a7%e5%86%8d%e8%b5%b7%e5%8b%95%e3%81%99%e3%82%8b%ef%bc%9akexec%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6bios%e3%81%a8post%e3%82%92%e3%82%b9%e3%82%ad%e3%83%83%e3%83%97/">kexec</a>を使用して、クラッシュ直後に2番目の「キャプチャ用カーネル」を起動します。この2番目のカーネルは、最初のカーネルが触れることのできなかった予約済みの小さなRAM領域で動作するため、システム全体のステート(vmcore)をディスクに保存できるほど安定しています。
セットアップ:Kdumpを正しく実装する
Kdumpが強力なのは、クラッシュしたカーネルに助けを求めないからです。調査のために古いメモリを保持したまま、オペレーティング環境全体を新しいものに置き換えます。AlmaLinux、CentOS、Ubuntuでの設定方法は以下の通りです。
ステップ1:kexec-toolsのインストール
BIOS/UEFIのハードウェア初期化を経由せずに新しいカーネルをロードするには、kexec-tools パッケージが必要です。
# RHEL/AlmaLinux/Fedoraの場合
sudo dnf install kexec-tools -y
# Debian/Ubuntuの場合
sudo apt update && sudo apt install kexec-tools -y
Ubuntuユーザーの場合:Kdumpを自動的に有効にするかどうかを確認するプロンプトが表示されることがあります。「Yes」を選択すると、基本的なサービス設定が自動で行われます。
ステップ2:クラッシュカーネル用のメモリを確保する
このステップは、最も設定に失敗しやすい場所です。キャプチャ用カーネルには専用のRAMが必要です。crashkernel=auto というオプションもありますが、4GB未満のRAMを搭載したシステムでは不安定になることがわかりました。私は 256M のように固定値を設定することを好みます。
RHELベースのシステムでは、grubby ユーティリティを使用して起動引数を更新します:
sudo grubby --update-kernel=ALL --args="crashkernel=256M"
Ubuntuでは、/etc/default/grub を手動で編集する必要があります:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash crashkernel=256M"
ここで再起動が必要です。メインカーネルが既に使用しているメモリを予約することはできないからです。
sudo update-grub # Ubuntuのみ
sudo reboot
ステップ3:ダンプの保存先を定義する
次に、Kdumpに vmcore の出力先を指定します。これは /etc/kdump.conf (RHEL) または /etc/default/kdump-tools (Ubuntu) で設定します。
デフォルトのパスは /var/crash/ です。ルートパーティションが満杯に近い場合は、セカンダリディスクを指定することを検討してください。64GBのRAMを搭載したサーバーは、理論上64GBのダンプファイルを生成する可能性がありますが、圧縮機能により大幅にサイズを抑えられます。
サービスが有効であることを確認します:
# RHELでステータスを確認
kdumpctl status
# Ubuntuでステータスを確認
kdump-config status
出力に「ready to kdump」または「operational」と表示されれば、セーフティネットの準備は完了です。
ステップ4:手動でパニックを発生させる
設定が機能するかどうかを確認するために、本物の障害を待つ必要はありません。Magic SysRqキーを使用して強制的にクラッシュさせることができます。 警告:これによりサーバーは即座にクラッシュします。必ず計画メンテナンス時間内に行ってください。
sudo sync
echo 1 | sudo tee /proc/sys/kernel/sysrq
echo c | sudo tee /proc/sysrq-trigger
システムがハングアップした後、再起動します。再起動後、/var/crash/ を確認してください。タイムスタンプが付いたフォルダの中に vmcore ファイルがあるはずです。それがあれば、セットアップは成功です。
ステップ5:Vmcoreの解析
vmcore はRAMのバイナリスナップショットです。これを読み取るには、crash ユーティリティと、使用しているカーネルバージョンに対応したデバッグシンボルが必要です。
sudo dnf install crash -y
# ダンプを開く(パスはタイムスタンプによって異なります)
crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/2023-10-27-10:30/vmcore
crash> プロンプト内で log コマンドを実行します。これにより、カーネルの内部メッセージバッファが表示されます。最後の数行を確認してください。通常、そこに「Oops」メッセージと、障害を引き起こした特定の関数が含まれています。
現場で得た教訓
かつて私は「ハードウェアの問題」を1週間追いかけましたが、結局RAIDコントローラのドライバにある小さなバグだったことが判明しました。Kdumpを使えば、わずか5分で見つけることができました。あの vmcore がなければ、数千ドルもする正常なハードウェアを交換していたところでした。
以下の3つのヒントを覚えておいてください:
- ディスク容量に注意: 設定で
core_collector makedumpfile -d 31オプションを使用してください。これによりゼロページやキャッシュが破棄され、16GBのダンプがわずか300MB程度にまで縮小されることがよくあります。 - カーネルのアップデート: カーネルをアップデートするたびに、Kdumpが正常に動作しているか再確認してください。ほとんどのディストリビューションはこれを自動化していますが、アップデート後の
kdumpctl statusによるクイックチェックが予期せぬ事態を防ぎます。 - 圧縮のテスト: サーバーに128GBのRAMが搭載されている場合、クラッシュ用パーティションが圧縮後の出力を処理できる容量であることを確認してください。
推測ではなくデータに基づいたデバッグに移行することで、重大な障害をより迅速に解決し、高い稼働率を維持できるようになります。

