systemd-oomd とカーネル OOM キラーの役割分担を理解する
Linux のメモリ枯渇対策として長年使われてきたカーネル OOM キラーは、物理メモリとスワップの両方が枯渇した後に初めて介入します。このタイミングはすでに「手遅れ」に近く、カーネルが独自のスコアリングでプロセスを強制終了するまでシステムが数秒〜数十秒間フリーズするケースが珍しくありません。
systemd-oomd(systemd v247 以降同梱)は、このギャップを埋めるユーザースペースの OOM デーモンです。カーネルが動く前に PSI(Pressure Stall Information)を監視し、メモリプレッシャーがしきい値を超えた時点で cgroup 単位でサービスを kill します。プロセス単位ではなく cgroup(=サービス)単位でまとめて終了させることで、残留したゾンビプロセスによる二次障害を防ぎやすくなります。
両者の役割を整理すると、systemd-oomd は「メモリ逼迫が深刻化する手前で特定スコープを止める」予防的アクション、カーネル OOM キラーは「すべてのメモリが尽きたときの最後の砦」という位置づけになります。systemd-oomd を導入しても、カーネル OOM キラー自体が無効になるわけではありません。
本番環境への有効化と oom.conf の基本設定
まず PSI が利用可能かを確認します。PSI は Linux 4.20 以降でサポートされており、cgroup v2 が必要です。
# PSI ファイルの存在確認
ls /proc/pressure/
# 出力例(cpu io memory が表示されれば有効)
cpu io memory
# cgroup v2 マウント確認
mount | grep cgroup2
確認できたら systemd-oomd を起動・有効化します。
sudo systemctl enable --now systemd-oomd
systemctl status systemd-oomd
次に /etc/systemd/oomd.conf を編集します。デフォルト値のままでも動作しますが、本番投入前に主要パラメーターを把握しておくことが重要です。
[OOM]
# スワップ使用率がこの値を超えたら介入候補とする(デフォルト 90%)
SwapUsedLimitPercent=90
# メモリプレッシャーのしきい値(デフォルト 60%)
DefaultMemoryPressureLimitPercent=60
# プレッシャーがしきい値を超え続ける時間(デフォルト 30s)
DefaultMemoryPressureDurationSec=30
DefaultMemoryPressureDurationSec を短くすると応答は速くなりますが、一時的なスパイクでサービスが kill される誤動作リスクが上がります。最初は 60s 程度に設定して様子を見るのが安全です。設定変更後は sudo systemctl restart systemd-oomd で反映します。
cgroup v2 スコープでの ManagedOOM 設定
systemd-oomd は全サービスを一律に監視するわけではありません。各ユニットファイルの ManagedOOMSwap= と ManagedOOMMemoryPressure= ディレクティブで対象を明示的に指定します。
# /etc/systemd/system/myapp.service の [Service] セクションに追記
[Service]
ManagedOOMSwap=kill
ManagedOOMMemoryPressure=kill
ManagedOOMMemoryPressureLimit=70%
kill を指定したスコープが候補リストに載り、しきい値を超えると systemd-oomd がそのスコープ全体を終了させます。auto(デフォルト)はディストリビューション側の設定に従い、omit は除外します。重要度の高いデータベースサービスなどは omit に設定して誤 kill を防ぐことを検討してください。
設定変更後はユニットをリロードします。
sudo systemctl daemon-reload
sudo systemctl restart myapp.service
動作検証フロー:PSI 監視から kill ログ確認まで
本番投入前にステージング環境で kill が実際に発生するかを確認します。以下は検証の一般的なフローです。
oomctl で監視対象スコープを確認する
oomctl
出力に ManagedOOMSwap / ManagedOOMMemoryPressure の設定値と現在のメモリプレッシャー値が表示されます。監視対象として登録されているスコープを事前に把握しておくことで、想定外のサービスが kill される事態を防げます。
stress-ng でプレッシャーを発生させて kill を確認する
ステージング環境での想定例として、stress-ng を使ってメモリを意図的に逼迫させ、systemd-oomd が介入するかをテストする方法があります。
# stress-ng でメモリを消費(実行環境のメモリ量に合わせて調整)
sudo stress-ng --vm 2 --vm-bytes 80% --timeout 120s
別ターミナルで journald を追いかけながら、systemd-oomd のログを確認します。
journalctl -u systemd-oomd -f
kill が発生すると Killed cgroup ... due to memory pressure などのメッセージが記録されます。カーネル OOM キラーが先に動いた場合は journalctl -k | grep -i oom でカーネルログを確認し、systemd-oomd が介入できなかった原因(しきい値設定・対象スコープの未登録など)を特定します。
切り戻し手順と運用上の注意点
本番で問題が発生した場合、即時の切り戻しは以下のコマンドで行えます。
# 即時停止(再起動後も無効)
sudo systemctl disable --now systemd-oomd
停止後もカーネル OOM キラーは引き続き動作するため、システムが完全にノーガードになるわけではありません。ただしカーネル OOM キラーの動作が以前より遅れて起きるように見えることがあります。これは systemd-oomd が止めていたはずのプロセスが残り続け、最終的に物理メモリを使い切るまで介入されなくなるためです。
運用上よくあるつまずきとして、以下の点に注意が必要です。
- cgroup v1 環境では動作しない:コンテナ環境や古い RHEL 7 系など、cgroup v2 が無効な環境では systemd-oomd は起動しても何も kill しません。
cat /sys/fs/cgroup/cgroup.controllersでコントローラー一覧が表示されるかを確認してください。 - コンテナ内での動作:Docker / containerd 上のコンテナ内から見えるのはホスト側の cgroup です。コンテナ内で systemd-oomd を動かしても、ホストの cgroup 階層全体を kill できるわけではないため、設計を混在させないよう注意してください。
- スワップ無効環境での挙動:スワップが存在しない環境では
SwapUsedLimitPercentのしきい値は永遠に超えません。メモリプレッシャー側(ManagedOOMMemoryPressure)の設定に重心を置いてください。 - OOMPolicy との競合:ユニットファイルに
OOMPolicy=continueが設定されているサービスは、カーネル OOM キラーによる kill を無視しますが、systemd-oomd による kill には別途ManagedOOM=omitが必要です。混在設定は意図しない動作につながります。
2026 年現行ディストリビューションの対応状況と差分
2026 年時点での主要ディストリビューションにおける systemd-oomd の対応状況には差があります。本番環境を選定する際の参考としてください。
Ubuntu 24.04 LTS(Noble)
systemd 255 系が採用されており、systemd-oomd はインストール済みですがデフォルトでは有効化されていません。systemctl enable --now systemd-oomd で手動起動が必要です。cgroup v2 はデフォルトで有効のため、PSI の準備は整っています。
RHEL 9 系(AlmaLinux 9 / Rocky Linux 9 含む)
systemd 252 以降が利用可能で、systemd-oomd パッケージは標準リポジトリに含まれます。ただし RHEL 9.x ではデフォルトで無効のため、dnf install systemd-oomd(パッケージが分離されている場合)と有効化コマンドが必要です。SELinux との組み合わせでラベルエラーが出るケースも報告されており、ausearch -c oomd で AVC 拒否ログを確認することをお勧めします。
Fedora 40 以降
Fedora は早期から systemd-oomd を積極的に採用しており、デフォルトで有効化されています。DefaultMemoryPressureLimitPercent の値も他ディストリビューションより低め(50%前後)に設定されていることがあるため、他環境からの移植時はデフォルト値の差異に注意してください。
Debian 12(Bookworm)
systemd 252 系が採用されており、systemd-oomd は利用可能ですが有効化はオプションです。Debian 12 では cgroup v2 がデフォルトになっているため、PSI 対応の前提条件は満たされています。
各ディストリビューションで共通して言えるのは、デフォルト設定のまま本番投入するのではなく、oomctl で監視対象スコープを確認し、ステージング環境での kill テストを経てから本番に適用するという順序が重要だという点です。PSI のしきい値は環境ごとにワークロードの特性が異なるため、モニタリングツール(Prometheus + node_exporter の PSI メトリクスなど)と組み合わせながら段階的にチューニングしていくアプローチが現実的です。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
PR・広告
[試して理解]Linuxのしくみ 増補改訂版(Amazon)
プロセス・権限・ファイルシステムなどLinux内部を図解で理解できる一冊。運用判断の勘所に。
※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。
