0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Linuxカーネルパニックを防ぐ。OOM Killerの優先度調整(oom_score_adj)とスワップ調律で重要サービスを死守する設計

0
Last updated at Posted at 2026-11-05

はじめに:メモリが枯渇したとき、OSは「誰」を停止するのか?

物理メモリの完全枯渇

オンプレミスサーバーや限られたメモリ(4GB〜16GB)のミニPCで、DockerコンテナやローカルLLM、データベースを動かしていると、いつか必ず 「物理メモリの完全枯渇」 に直面します。

その極限状態に達した瞬間、Linuxカーネルの最終防衛機構 oom_score_adj によるプロセスの停止優先度コントロールを実行し、最悪の悲劇が起こります。

  • 「なぜかメモリを食っている元凶ではなく、命綱である SSHデーモン(sshd)やデータベース(MySQL)が倒された!」
  • 「リモートからSSHログインすらできなくなり、サーバールームに走って物理電源長押しする羽目になった」

なぜカーネルは一番倒してはいけない重要プロセスを停止してしまうのか?
どうすれば、元凶のバッチ処理や開発コンテナだけを狙い撃ちで倒させ、管理基盤を守り抜けるのか?

本記事では、oom_score_adj によるプロセスの停止優先度コントロールと、vm.swappiness の最適調律 を解説します。


1. OOM Killerの採点ロジック:oom_score の真実

カーネルは、各プロセスの「悪質度(Badness)」を 0 〜 1000 のスコアで計算します。
基本的には「多くのメモリを消費しているプロセス」ほど高得点になりますが、プロセスの生存期間や権限によってもブレが生じます。

現在の各プロセスのスコアは、/proc から直接確認できます。

# (要点抜粋)
# (Source: https://github.com/ojisantech/)
# プロセス 1234 の現在の停止スコアを確認
cat /proc/1234/oom_score

# システム内で「今一番倒されそうなプロセス TOP 5」を表示
ps -eo pid,comm,pmem --sort=-pmem | head -n 6

2. 重要プロセスを「絶対不可侵」にする:oom_score_adj = -1000

Linuxカーネルは、ユーザーが各プロセスの停止優先度を -1000(絶対に倒すな) から +1000(真っ先に倒せ) の範囲で調整できるフックを用意しています。

① SSHデーモンを絶対不可侵にする

SSHが停止するとリモート復旧が不可能になるため、-1000 を設定して停止対象から完全除外します。

# (要点抜粋)
# (Source: https://github.com/ojisantech/)
# sshd プロセスのPIDを取得して絶対保護
sudo echo -1000 > /proc/$(pgrep -o sshd)/oom_score_adj

② systemd サービス単位で恒久設定する

サービス定義ファイル(Unitファイル)に OOMScoreAdjust を1行書くだけで、再起動後も永続的に保護されます。

逆に、メモリ暴走の危険がある自作バッチやテストスクリプトには OOMScoreAdjust=1000 を指定しておけば、メモリ逼迫時に真っ先に身代わりとして停止され、他の重要サービスを守ってくれます。


3. Docker コンテナ単位での優先度制御

Docker Composeでも、コンテナごとに oom_score_adj を設定できます。


4. カーネルスワップ調律:vm.swappiness の最適解

メモリが残り少なくなったときのカーネルの挙動を、/etc/sysctl.conf で最適化します。

# (要点抜粋)
# (Source: https://github.com/ojisantech/)
sudo sysctl --system

💻 コア実装・設定スニペット(抜粋)

# (要点抜粋)
# /etc/sysctl.d/99-memory-tuning.conf

# 既定値 60 -> 10 に引き下げ。
# 物理メモリをギリギリまで使い倒し、無駄なNVMe/SSDへのスワップアウト(速度低下)を防ぐ
vm.swappiness = 10

# メモリの過剰コミット(Overcommit)の挙動調整 (既定: 0 = ヒューリスティック)
vm.overcommit_memory = 0

# パニック時の自動再起動 (万が一カーネルパニックが起きたら 10秒後に自動リブート)
kernel.panic = 10

まとめ:OOM Killerと戦うな、飼いならせ

メモリ枯渇は、アクセス集中やデータ肥大化によってどんなシステムでも起こり得ます。

  • SSHやデータベースには OOMScoreAdjust=-1000 を与えて不可侵にする
  • 重たい推論モデルやバッチには正のスコアを与えて「身代わり」にする
  • vm.swappiness=10 で不必要なディスクI/Oスラッシングを防ぐ

このカーネルチューニングを施しておくことで、メモリ限界時でも「重要な管理画面やSSHはピンピン生きており、原因のプロセスだけが綺麗に切断されて即座に原因調査できる」という極めて強靭なインフラが完成します!


📚 さらに詳しいアーキテクチャ設計・パラメータ表・トラブルシューティング

最後までお読みいただきありがとうございます!
本記事が少しでも「役に立った」「あとで試したい」と感じていただけましたら、ぜひQiitaの 「いいね(♡)」 と 「ストック」、および アカウントのフォロー をいただけると今後の検証・執筆の大きな励みになります!

また、本記事のさらに踏み込んだ 「深層アーキテクチャ解説」「主要パラメータの技術的根拠」「現場アンチパターン・トラブルシューティング対応表」 は、以下のGitHub技術リファレンスにて公開しています。

👉 【第37弾 詳細技術リファレンス (QIITA_ARTICLE_DETAIL_37.md)】

⭐ 全14層・200パターンの自立型インフラ&オンプレAIリファレンス集(おじさんの武器庫)を順次公開中です。ぜひGitHubリポジトリへの Star (★) と X (@OjisanTechnical) のフォローもお願いいたします!
👉 GitHub リポジトリ: ojisantech/ojisan-arsenal

💡 【検証環境・個人研究(PoC)に関する注記】
本記事は、筆者個人の自宅検証環境(ホームラボ/仮想環境)において、公開情報およびOSS(オープンソースソフトウェア)を用いて独自に構築・検証した個人研究(PoC)の記録です。特定の企業・団体の実環境や業務上の非公開情報とは一切関係ありません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?