Kubernetes

KubernetesでOOMKilledを防止する完全ガイド【2026年版】

ⓘ本ページはプロモーションが含まれています

スポンサードリンク

1️⃣ OOMKilled のメカニズムとすぐに確認すべきポイント

項目 内容
発生原因 カーネルの OOM Killer が、cgroup に設定された memory.limit_in_bytes を超えたプロセスを強制終了した結果、Pod の status.reason=OOMKilled になる。
Kubernetes 側の連携 - Pod 作成時に requests.memorylimits.memory が cgroup の memory.soft_limit_in_bytes / memory.limit_in_bytes に反映される。
- カーネルは OOM 発生時、cgroup 内で 最もスコアが高い プロセスを選択して kill する。
確認手順 1. Pod のステータスとイベント
bash\nkubectl get pod <pod> -o wide\nkubectl describe pod <pod>\n
2. カーネルログ(dmesg / /var/log/kern.log)で Out of memory メッセージを検索。
参考リンク Google Cloud – OOM イベントのトラブルシューティング
https://cloud.google.com/kubernetes-engine/docs/troubleshooting/oom-events?hl=ja

ポイントkubectl logs --previous が取得できる場合は、コンテナが再起動する直前のログも必ず保存しておく。


2️⃣ リソース設定と QoS クラス別の挙動(実装ガイド)

2‑1. requestslimits のベストプラクティス

  • requests : Scheduler が確保する最低保証リソース。
  • limits : cgroup に設定される上限。超えると OOM Killer が介入。

2‑2. QoS クラスの判定ルール(公式ガイド)

QoS 判定条件
Guaranteed 全コンテナで requests == limits が一致
Burstable 少なくとも1つのリソースに requests が設定されている(limits は任意)
BestEffort requestslimits がどちらも未設定

実務上の目安:ほとんどのバックエンドサービスは Guaranteed に近づけることで、OOM 時に保護されやすくなる。

2‑3. QoS と oom_score_adj の関係(正確な数値)

  • カーネルがプロセスに付与する oom_score_adj は -1000〜+1000 の範囲。
  • Kubernetes が自動で設定する目安は以下の通り(実際の値はノードやカーネルバージョンにより若干変動)
QoS oom_score_adj の典型的な範囲
Guaranteed -998 (最も低い、保護される)
Burstable -997 〜 +1000requestslimits の比率に応じて段階的に上昇)
BestEffort +1000 (最高スコア、最優先で kill 対象)

参考リンクSysdig – Linux OOM Killer の内部解説
https://sysdig.com/blog/linux-oom-killer/


3️⃣ Prometheus でメモリ使用率を可視化し、実装できるアラート例

3‑1. 必要なエクスポーターと基本設定

コンポーネント 主な指標
kube-state-metrics container_spec_memory_request_bytes, container_spec_memory_limit_bytes
node_exporter ノード全体の node_memory_MemTotal_bytes, node_memory_MemAvailable_bytes

3‑2. メモリ使用率ダッシュボード(Grafana パネル例)

3‑3. OOM リスク検知用 Alertmanager ルール

  • 閾値の根拠> 90% の limit 超過は OOM 発生リスクが顕著。
  • 運用上のコツ:アラートを受けたら自動で kubectl top pod を実行し、突発的スパイクか持続的リークかを即判定。

4️⃣ 自動スケーリングで根本防止 ― Vertical Pod Autoscaler (VPA) と Cluster Autoscaler (CA)

コンポーネント 主な役割
VPA 実測メモリに基づき requests/limits を自動推奨または適用。
CA クラスタ全体のスケジューラブルリソースが不足したらノードを追加、逆に余剰なら削除。

4‑1. VPA のデプロイ例(GKE 向け)

  • 注意点:自動適用は Pod の再起動が必要になるため、PodDisruptionBudget を設定し可用性を担保する。

4‑2. Cluster Autoscaler(EKS)設定サンプル

  • 連携ポイント:VPA が requests を上げたタイミングで、CA が対象ノードプールに空きが無ければ自動的に新規インスタンスを起動し、スケジューラが再び Pod を配置できる。

5️⃣ メモリリーク検出と oom_score_adj の手動調整

5‑1. ヒープダンプ取得(Java/Go 共通フロー)

言語 コマンド例
Java bash\n# コンテナに入る\nkubectl exec -it java-app-abcde -- bash\njcmd $(pgrep -f org.example.Main) GC.heap_dump /tmp/heapdump.hprof\nkubectl cp default/java-app-abcde:/tmp/heapdump.hprof ./heapdump.hprof\n
Go bash\n# pprof のエンドポイントを有効化し、curl で取得\nkubectl exec -it go-app-xyz -- curl http://localhost:6060/debug/pprof/heap > heap.pb.gz\n
  • ダンプは Eclipse MAT, IntelliJ IDEA Memory Analyzer などで解析し、Top Consumers を確認する。

5‑2. top / ps によるリアルタイム監視

  • メモリ使用率が急上昇しているプロセスを即座に特定できる。

5‑3. oom_score_adj の調整例(Pod 定義)

  • 効果:同一ノード上の BestEffort Pod がまず kill 対象になる。
  • 留意点oom_score_adj を極端に低くしすぎると、逆に別プロセスが不必要に犠牲になる可能性があるため、-900 以上(例: -800〜-950) に抑える。

6️⃣ ケーススタディ:EKS の EC2 → Fargate 移行と OOM 復旧手順

6‑1. 移行で得られるメリット

項目 効果
cgroup 分離 各 Pod が独立したメモリ上限を持ち、ノード全体の競合が解消。
リソース課金モデル 実際に使用した vCPU とメモリだけが課金対象になるため過剰プロビジョニングが削減。
OOM 発生率 同一ノード上でのリソース争奪がなくなるため、Exit Code 137 が大幅に減少(事例:80 % 減)

移行手順ハイライト

6‑2. Exit Code 137 発生時の復旧フロー

手順 コマンド例 ポイント
1️⃣ Pod の特定 kubectl get pod -n prod -o wide | grep OOMKilled STATUS=OOMKilled がヒント
2️⃣ 前回ログ取得 kubectl logs <pod> -c <container> --previous > pre-oom.log --previous が必須
3️⃣ イベント確認 kubectl describe pod <pod> Reason: OOMKilled, Exit Code: 137 をチェック
4️⃣ 再デプロイ kubectl rollout restart deployment/<name> -n prod Deployment があれば自動で新 Pod が生成
5️⃣ アラート・設定の見直し Prometheus のアラートが発火しているか確認 同様の再発防止策を適用(requests/limits の調整、VPA 導入等)

7️⃣ まとめ ― OOMKilled を根本から撲滅するチェックリスト

項目 実装・確認内容
① cgroup とカーネルログ kubectl describe pod + dmesg で OOM 発生の根拠を取得
② QoS を Guaranteed に近づける requests == limits(メモリ・CPU 両方)を原則とする
③ Prometheus アラート working_set / limit > 0.9> 80% request の二段階閾値で警告
④ 自動スケーリング VPA(Auto モード)+ CA を併用し、リソース要求とノード容量を同時に最適化
⑤ メモリリーク対策 定期的に heapdump / pprof 取得、top/ps によるリアルタイム監視
oom_score_adj の活用 重要サービスは securityContext.oomScoreAdj: -900 で保護
⑦ インフラの見直し 必要に応じて EC2 → Fargate、またはノードプールのリサイズを実施

これらの手順を 「設計 → デプロイ → 監視 → 改善」 のサイクルで繰り返すことで、OOMKilled によるダウンタイムはほぼゼロに近づきます。

次のアクション
1. 現行クラスターの Pod 一覧を取得し、requests/limits が未設定または Burstable のものだけを抽出 (kubectl get pods -A -o json | jq '.items[] | select(.spec.containers[].resources.requests == null)')
2. 抽出結果に対して上記の Guaranteed 設定テンプレートを適用し、VPA の導入計画を立案する。


本稿は 2026 年 4 月時点の公式ドキュメント・OSS リポジトリ情報に基づき執筆しています。リンク切れやバージョン差異がある場合は、各プロジェクトの最新 README をご参照ください。

スポンサードリンク

-Kubernetes
-, , , , , , ,