Kubernetes

Kubernetes の OOMKilled 対策とリソース設定・QoS 完全ガイド

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

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

OOMKilled の概要と Kubernetes におけるステータス表示

Kubernetes 上でコンテナがメモリ上限を超えて強制終了されると、Pod の status.reasonOOMKilled が記録されます。この情報はカーネルの OOM Killer がプロセスを殺した事実を Kubelet が取得し、API サーバーに返す仕組みです。本節では、OOMKilled がどのように生成されるかと、ステータスを見る際のポイントを解説します。

OOM Killer と Kubelet の連携

Kubernetes は各コンテナに cgroup を割り当て、memory.limit_in_bytes で上限を設定します。メモリが不足するとカーネルは OOM Killer を起動し対象プロセスを終了させます。その直後、Kubelet が cgroup.events 等から OOM イベントを取得し、Pod のステータスに反映させます。

Pod が OOMKilled になる条件

  • コンテナの cgroup メモリ上限 (memory.limit_in_bytes) を実際使用量が超える。
  • ノード全体でメモリ圧迫が発生し、Kubelet の eviction ポリシーに従って対象 Pod が選択される。
  • kubectl get pod … -o jsonpath='{.status.containerStatuses[0].state.terminated.reason}'OOMKilled を返す場合は、上記いずれかが起因しています。

詳細なトラブルシューティング手順は GKE 公式ドキュメント(2026年3月版)をご参照ください → https://cloud.google.com/kubernetes-engine/docs/troubleshooting/oom-events?hl=ja


Pod のリソース設定と QoS クラスの関係

Pod が OOMKilled になるか否かは、requests / limitsQoS(Quality of Service)クラス の組み合わせで決まります。本節ではそれぞれの役割と相互作用を整理し、実務で陥りがちな落とし穴を具体例と共に示します。

resources.requests と resources.limits の役割

requests は Scheduler が Pod を配置する際の基準、limits は cgroup に設定されるメモリ上限です。両者が一致していないと QoS が低下し、OOM 発生時に優先度が下がります。

設定例 requests (Mi) limits (Mi) QoS クラス
A 200 400 Burstable
B 300 300 Guaranteed
C - 500 BestEffort*

* requests が未設定の場合は BestEffort とみなされます。

  • リクエスト未設定 → デフォルトは 0(BestEffort)。ノードが過負荷になると最初に対象になります。
  • リミット未設定 → コンテナはノード全体の空きメモリを無制限に使用でき、突発的なスパイクで OOM Killer が介入しやすくなります。

QoS クラス(Guaranteed / Burstable / BestEffort)の判定基準

QoS は requestslimits の有無・一致度で自動的に決まります。クラスごとの特徴は次の通りです。

  • Guaranteed: すべてのコンテナが requests == limits を満たす。メモリ不足時でも最も保護されます。
  • Burstable: 少なくとも一つのコンテナで requests < limits、または一部未設定。通常は保護されますが、スパイクで limits 超過すると対象になります。
  • BestEffort: requestslimits も未設定。ノード圧迫時に最初に削除対象となります。

LimitRange と ResourceQuota による組織全体のリソース上限設定は、公式ドキュメントに従って導入してください。


主な原因別診断手順

OOMKilled が検知されたら、まずは以下のチェックリストを順番に実行します。すべて kubectl とクラスタ内部ツールだけで完結できるよう設計しています。

メモリ上限不足の検証方法

現在設定されている limits.memory が実際の使用量を下回っていないか確認します。

実測使用量 (Mi) 設定上限 (Mi) 判定
450 400 超過 → OOM の可能性
300 500 OK
  • 対策: limits が足りない場合は Pod 定義を更新し、上限値を引き上げます。

リクエスト未設定・過小設定のチェック

requests.memory が未設定または実際の負荷に比して極端に低いと、Scheduler が不適切なノードへ割り当て、結果的に OOM が起きやすくなります。

コンテナ requests (Mi) 実測使用量 (Mi) 判定
web 100 350 過小
worker 200 210 OK
  • 対策: ベンチマーク結果の 1.5 倍程度を目安に requests を設定し直します。

ノード全体のメモリ圧迫と cgroup 設定ミス

ノード自体がメモリ不足になると、Kubelet が QoS の低い Pod を優先的に削除します。まずはノードの使用率を把握しましょう。

ノード 容量 (Gi) 使用率 (%) 判定
gke-node-1 64 92 圧迫
gke-node-2 64 45 OK
  • 対策: Node Auto‑Provisioning を有効にし、スケールアウトで余裕を確保します。

カーネル OOM Killer のログ確認

Kubernetes が取得できない情報(例:他プロセスとの競合)はカーネルログに出力されます。dmesg で直近の OOM エントリを抽出しましょう。

典型的な出力例

  • 対策: memory.limit_in_bytes が期待値より低い場合は、Pod の limits を再評価してください。

診断フローチャート(表形式)

ステップ 実行コマンド 判定基準 次のアクション
1 kubectl describe pod … status.reason=OOMKilled 有無 無 → 別原因調査、終了
2 kubectl top pod … / limits 確認 使用量 > limits limits 増加
3 requests 確認 未設定 or 過小 requests 再設定
4 kubectl top node ノード使用率 > 85% Node Auto‑Provisioning 設定
5 dmesg | grep oom カーネルログに OOM エントリ cgroup 設定見直し

予防策と自動化機能

OOMKilled を根本的に抑えるには、リソース設定の標準化と自動スケーリングの活用が鍵です。本節では組織レベルで有効な制御手段と、ノード・Pod の自動調整機構について具体例を交えて紹介します。

LimitRange と ResourceQuota による組織的制御

Namespace 単位でデフォルトの requestslimits を強制し、BestEffort Pod の作成を防ぎます。以下は典型的な LimitRange 定義です。

この設定により、memory.request が未指定の場合は自動的に 256 Mi が適用されます。さらに ResourceQuota を併用すれば、名前空間全体のメモリ使用上限を管理できます。

Vertical Pod Autoscaler と Node Auto‑Provisioning の活用

VPA は実行中の Pod の CPU・メモリ使用状況を解析し、推奨 requests/limits を自動算出します。Node Auto‑Provisioning(GKE)と組み合わせれば、クラスター全体のリソース需要に応じてノード数が増減します。

ノードレベルの sysctl 設定と OOM Score Adj

Kubernetes のノードでは swap を無効化vm.overcommit_memory=1 を設定することで OOM Killer の挙動が予測しやすくなります。また重要サービスには oom_score_adj を負の値にしてカーネルからの殺害対象外にできます。

  • ポイント: これらのシステムレベル調整はノード全体の安定性を高め、Kubernetes が正確にメモリ圧迫を検知できるようにします。

実践的チェックリストと事例

典型パターン別 OOMKilled 発生シナリオ

以下は現場でよく見られる OOMKilled の原因と、発見手段・推奨対策をまとめた表です。

パターン 主な原因 発見手段 推奨対策
メモリリーク アプリが GC できず徐々に使用量増加 kubectl top pod の時系列推移 + ログ解析 limits 増加、VPA 導入、コード修正
突発的スパイク負荷 バッチ処理や突発トラフィック イベント直後の kubectl describe pod Events Burstable → Guaranteed 変更、HPA と併用
ノード競合 複数高メモリ Pod が同一ノードに集積 kubectl get nodes -o wide + kubectl top node Node Auto‑Provisioning、有効化、PodAntiAffinity 設定
cgroup 設定ミス limits 未設定・単位ミス (Mi vs Gi) YAML 検証ツール(kubeval)で CI に組込む 正しい単位で limits を明示、Lint 導入

対策フローと即適用できる設定サンプル

実際に OOMKilled が発生したら次の手順で迅速に対処します。

  1. リソース定義確認
    bash
    kubectl get pod <pod> -o yaml | grep -A4 resources:
  2. QoS 判定kubectl describe podQoS Class を確認。
  3. ノード状態把握
    bash
    kubectl top node
  4. カーネルログ確認
    bash
    sudo dmesg | grep -i oom | tail -n 10
  5. 修正例(Limits と Requests の統一)

yaml
resources:
requests:
memory: "512Mi"
limits:
memory: "1024Mi"

  1. LimitRange 設定で組織全体に適用(前述の YAML を利用)。
  2. VPA と Node Auto‑Provisioning の有効化

bash
gcloud container clusters update my-cluster \
--enable-autoprovisioning --max-cpu=32 --max-memory=128Gi

  1. 再デプロイ後の検証
    bash
    kubectl top pod <pod> --containers

まとめ

  • OOMKilled の根本原因は cgroup のメモリ上限超過status.reason=OOMKilled が示す情報をまず確認することが第一歩です。
  • requests / limits と QoS クラスの整合性 を保つことで、Pod が OOM 発生時に最優先で残るかどうかが決まります。Guaranteed もしくは Burstable に統一し、BestEffort は極力回避しましょう。
  • 診断手順は kubectl describe, kubectl top, dmesg の組み合わせ で進め、原因別にチェックリストを適用すれば迅速に根本要因を特定できます。
  • 予防策としては LimitRange / ResourceQuota による標準化と、VPA・Node Auto‑Provisioning といった自動化機能の導入 が有効です。さらにノードレベルで swap 無効化や vm.overcommit_memory 設定を行うことで、カーネル側の挙動も安定させられます。
  • 実践チェックリストとフローを日常的に活用 すれば、典型的な OOM パターンへの対処が体系化され、障害復旧時間を大幅に短縮できます。

これらのベストプラクティスを導入することで、Kubernetes 環境における OOMKilled の発生頻度とインシデント対応コストを効果的に低減できるでしょう。

スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-Kubernetes