午前2時のページャー呼び出し深夜2時に電話が鳴り響きます。本番ノードがダウンしています。SSHは繋がらず、Webコンソールはフリーズしたテキストの壁となっています。ログの最後をよく見ると、おそらく次のような犯人が見つかるはずです:
kernel: NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s!
要するに、CPUコアがカーネルレベルのループに長時間陥った状態です。デフォルトでは、Linuxは20秒経過すると痺れを切らします。それまでにタスクがCPUを解放しない場合、ウォッチドッグが警告を発します。シングルコアのVPSではシステムが完全にフリーズし、大規模なマシンでは全体が動かなくなる前に深刻なレイテンシのスパイクが発生します。
TL;DR: 緊急パッチまだコマンドを入力できる状態であれば、カーネルに余裕を持たせてください。ウォッチドッグのしきい値を上げても根本的なバグは治りませんが、即座のクラッシュを防ぐことができます。これにより、サーバーが再起動を繰り返すことなく調査を行う時間を稼げます。
# 現在の制限値を確認(通常は20秒)
cat /proc/sys/kernel/softlockup_thresh
# 即座に60秒まで引き上げる
sudo sysctl -w kernel.softlockup_thresh=60
激しく動作が不安定なシステムの制御を取り戻すには、一時的にバックトレースを無効化する必要があるかもしれません:
sudo sysctl -w kernel.softlockup_all_cpu_backtrace=0
sudo sysctl -w kernel.watchdog_thresh=0
実際に何がCPUを拘束しているのか?ソフトロックアップは、スケジューラを動作させずにカーネルが「クリティカルセクション」に長時間留まることで発生します。一般的な原因には以下が含まれます:
- NFS/ネットワーク遅延: リモートマウントがハングし、レスポンスを待つ間にカーネルがブロックされる。
- クラウドのオーバーサブスクリプション: AWSやAzureなどで「うるさい隣人(Noisy Neighbors)」が物理CPUサイクルを奪い、VMがフリーズしたように感じる。
- 過度な割り込み負荷: 故障したNICが毎秒50,000回以上の割り込みをシステムに送り続ける。
- マイクロバーストトラフィック: データベースクエリが瞬時に10倍に急増し、I/Oスタックが即座にパンクする。
ステップ1:残骸を調査するロックアップが検出されると、通常カーネルは dmesg にスタックトレースを出力します。タイマーが切れた瞬間に実行されていた特定のプロセスを特定する必要があります。
dmesg | grep -C 5 "soft lockup"
CPU: 0 PID: 1234 Comm: ... と記された行を探してください。Comm の値が java や python であれば、アプリケーションコードが重いシステムコールをトリガーしている可能性があります。kworker であれば、ほぼ確実にディスクI/Oまたはドライバのボトルネックに対処しています。
ステップ2:修正を永続化するワークロードに強度の高いバーストが頻繁に含まれる場合は、恒久的に制限を引き上げるべきです。/etc/sysctl.conf を編集して、再起動後も設定が維持されるようにします:
# 激しい負荷スパイクに対応するためしきい値を引き上げる
kernel.softlockup_thresh = 60
kernel.watchdog_thresh = 30
設定変更を適用します:
sudo sysctl -p
ステップ3:仮想化による遅延を確認する仮想マシンでは「Clocksource(クロックソース)」が重要です。ホストとゲストのクロックがずれると、カーネルパニックが発生します。現在のソースを確認してください:
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
VMを使用していて tsc と表示される場合は、利用可能であれば kvm-clock への切り替えを試してください。また、top を実行して %st(スティールタイム)列を監視してください。スティールタイムが継続的に5%を超える場合、クラウドプロバイダーがハードウェアをオーバーブッキングしています。VMを別のホストに移行するか、インスタンスタイプをアップグレードする必要があります。
ステップ4:割り込みストーム(Interrupt Storm)の特定バグのあるハードウェアがCPUにリクエストを溢れさせることがあります。cat /proc/interrupts を使用して、特定のIRQが急増していないか確認します:
watch -n 1 "cat /proc/interrupts"
数値に注目してください。システムが不安定な間に特定のIRQが数秒で数万回も跳ね上がるようであれば、ハードウェアまたはドライバの障害が見つかったことになります。
検証:修正の負荷テストチューニング後は、24時間ログを監視してください。stress ツールを使用して重いワークロードをシミュレートし、新しいしきい値が負荷に耐えられるか確認できます。
# stress ユーティリティをインストール
sudo apt install stress
# 注意:本番環境では実行しないでください!
# 4つのCPUコアに60秒間負荷をかける
stress --cpu 4 --timeout 60
このテスト中に dmesg に何も出力されなければ、新しいしきい値は適切です。もしエラーが再発する場合は、sysctlの調整を止め、iostat -xz 1 などでI/Oサブシステムを監査し、なぜディスクが詰まっているのかを特定し始めてください。

