Kubernetes

Kubernetesでの OOMKilled と Linux OOM Killer の仕組み・QoS・Eviction・自動スケール対策

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

お得なお知らせ

スポンサードリンク
1ヶ月で資格+現場入り

インフラエンジニアへの最短ルート

未経験でもAWS・Linux・ネットワーク資格を最短で取り、現場入りまでサポート。SREやクラウドエンジニアの入口。

CODE×CODEスピード転職|無料面談▶ SRE/クラウドのフリーランス案件▶

▶ AWS/GCP/Kubernetesの独学には Kindle Unlimited の技術書読み放題がコスパ最強。


スポンサードリンク

1. Linux カーネルの OOM 機構と Kubernetes が参照する情報

項目 説明
OOM Killer メモリが枯渇したノードでカーネルが自動的にプロセスを SIGKILL するサブシステム。oom_score_adj に基づき、最も「犠牲価値」が低いタスク(=cgroup)から順に対象となります。
pswapd スワップ領域の再利用を試みるデーモンであり、OOM 判定には関与しません。メモリ圧迫時は swap reclaim を行い、一時的に memory.available が回復することがありますが、根本的な OOM 状態の検知はカーネルの out‑of‑memory ロジックが担います。
cgroup v1/v2 の memory controller Pod ごとに割り当てた memory.limit_in_bytes(ハードリミット)を超えると、メモリコントローラが即座に対象プロセスへ SIGKILL を送ります。これが コンテナ単位の OOMKilled の直接原因です。
/proc/meminfo & memory.available カーネルがノード全体の空きメモリを算出する指標。memory.available が閾値以下になると、NodeProblemDetector (NPD)kubelet が「MemoryPressure」状態として NodeCondition を更新します。

ポイント
- ノードレベルの圧迫はカーネルが直接 OOM Killer を起動するか、memory.available が低下して NodeCondition MemoryPressure が立ち上がるかのいずれかで対処されます。
- コンテナ単位の OOM は cgroup のハードリミット超過がトリガーとなり、Kubernetes からは Pod のステータスに OOMKilled が付与されます。


2. Kubernetes における Eviction フロー(NodeProblemDetector を含む)

  1. NPD の監視
  2. NPD は systemd サービスとして動作し、/proc/meminfo/sys/fs/cgroup/.../memory.usage_in_bytes を定期的に取得。
  3. memory.available < evictionHard.memory.available(kubelet 設定)や 90 % 超過といった条件を満たすと、NodeCondition の MemoryPressure=True を設定します。

  4. kubelet のリアクション

  5. kubelet は NodeCondition が MemoryPressure に遷移したことを検知すると、eviction controller を起動。
  6. 設定ファイル (KubeletConfiguration) の evictionHard, evictionSoft, evictionMinimumReclaim で定義された閾値に従い、QoS クラス別に Pod を選択し Graceful Eviction(Pod が削除対象になる前に PreStop フックが走る)を実行します。

  7. OOM Killer の介在

  8. 上記 eviction で対象外の Pod がノード全体のメモリ不足状態をさらに悪化させた場合、カーネルは直接 OOM Killer を呼び出し、cgroup スコアリングに基づき最もスコアが低い Pod(=oom_score_adj が高い)を即座に SIGKILL します。
  9. このとき Kubernetes は Pod のステータスReason: OOMKilled を付与し、イベントとして記録されます。

まとめ:NPD → NodeCondition → kubelet eviction →(必要なら)カーネル OOM Killer の三段階フローが実際の動作です。単純化せずにそれぞれのコンポーネントが果たす役割を理解しておくことが、正しいチューニングの出発点になります。


3. QoS クラスとリソース設定が Eviction に与える影響

QoS 設定条件 メモリ圧迫時の優先順位
Guaranteed 全コンテナで requests == limits が明示的に設定されている 最低。memory.request が全体の 100 % とみなされ、NodeCondition が出ても最初は対象になりません。
Burstable 1 つ以上のコンテナで requests < limits(もしくは一部未設定) 中間。kubelet は同クラス内で memory.request / memory.limit の比率が小さい Pod から順に evict します。
BestEffort 全てのコンテナで requests, limits が未設定(=0) 最優先。NodeCondition が立つと最初に対象となります。

実務上のベストプラクティス
- 本番環境は Guaranteed に近づける設計が基本です。
- Burstable を使用する場合でも、requests は必ず設定し、最低限保証できるメモリ を明示します(例:requests: 256Mi, limits: 512Mi)。
- BestEffortバッチ処理や短命ジョブ に限定し、監視アラートで早期に検知できるようにします。


4. AKS(Azure Kubernetes Service)向け実装ガイド

4.1 Azure のネイティブ監視と NPD の連携

コンポーネント 役割
Azure Monitor for containers kubelet が出力する memory.available、NodeCondition、Pod の OOM イベントを Log Analytics に自動転送。
NodeProblemDetector (AKS 拡張) Azure Monitor エージェントと連携し、MemoryPressure を検知した際に node.kubernetes.io/memory-pressure アノテーションを付与します。
kubelet の evictionHard デフォルトは memory.available<100Mi. AKS ではポータルまたは CLI で --eviction-hard=memory.available<200Mi 等に上書き可能です。

カスタマイズ例(Azure CLI)

ポイントmemory.available は「実際に割り当て可能なメモリ」なので、スワップが有効でもこの指標は減少しません。したがって、スワップの使用量で OOM が回避できるケースは稀です。

4.2 Azure Advisor と自動スケールアウト

  • Azure Advisor は「Node の MemoryPressure」頻度を分析し、Cluster Autoscaler の有効化やノードサイズ変更を提案します。
  • Cluster Autoscaler (AKS)az aks enable-addons --addons cluster-autoscaler で有効化し、最小・最大ノード数を設定できます。

  • 推奨:VPA と組み合わせる場合は、--scale-down-delay-after-add=10m 等でスケールインのタイミングを遅らせ、リソースが安定するまで待機させます。

4.3 AKS 向け Observability(Prometheus + Grafana)

メトリクス 説明
container_memory_working_set_bytes コンテナの実際に使用中のメモリ(RSS+Cache)。
kube_pod_container_resource_limits_memory_bytes Pod が宣言した limits.memory
node_memory_Active_bytes / node_memory_MemTotal_bytes ノード全体の利用率。

PromQL 例(80 % 警告・90 % 致命的)

  • Alertmanager のルールは evaluation_interval: 30sfor: 2m(Warning)/1m(Critical)に設定し、スパイクによる誤検知を抑えます。
  • Azure Monitor と統合すれば、アラートが Action Group に流れ、Teams/PagerDuty へ即時通知できます。

5. GKE(Google Kubernetes Engine)向け実装ガイド

5.1 GKE 標準の NodeProblemDetector と kubelet 設定

コンポーネント デフォルト挙動
NodeProblemDetector (GKE) /proc/meminfoMemAvailable を監視し、閾値 90 % 超過で node.kubernetes.io/memory-pressure 条件を付与。
kubelet evictionHard デフォルトは memory.available<100Mi. GKE は --eviction-hard=memory.available<200Mi,resource.memory.threshold=0.9 の形でカスタマイズ可能。

gcloud コマンド例(標準クラスター)

  • Autopilot クラスタの場合は、ノードがユーザーに見えない代わりに GKE が自動的に Memory Pressure の検知 → Pod Eviction を実行します。PodSecurityPolicy の制約を付けることで、過度な limits 設定を防げます。

5.2 GKE と Cloud Monitoring の連携

  • Cloud Monitoring(旧 Stackdriver)により、kube_node_status_condition{condition="MemoryPressure"} が自動的にメトリクス化されます。
  • アラートポリシーで「MemoryPressure が 5 分以上継続」したら Pub/Sub → Cloud Functions で自動的に Cluster Autoscaler を有効化することが可能です。

5.3 GKE 向け Observability(Prometheus + Grafana)

GKE では Managed Prometheus が標準で有効化でき、kube_pod_container_resource_requests_memory_bytescontainer_memory_working_set_bytes を組み合わせたダッシュボードがすぐに利用可能です。

  • Alertmanager の代わりに Google Cloud Alerting を使用し、同様の閾値(80 %/90 %)で通知先を Cloud Pub/Sub → Slack に流す構成が推奨です。

6. 自動スケーリングと予防策:VPA + Cluster Autoscaler

機能 主な役割 AKS の実装ポイント GKE の実装ポイント
Vertical Pod Autoscaler (VPA) requests/limits を自動的に推奨・更新。Pod 再起動が必要になるが、リソース過不足を根本から解消。 Azure Marketplace の VPA アドオンか、Helm chart (vpa-admission-controller) をデプロイ。recommendationOnly でまずは提案だけ取得し、CI でレビュー後に Auto に切替。 GKE では autoscaling-profile=optimize-utilization と組み合わせて VPA を Helm で導入。updateMode: Auto が推奨。
Cluster Autoscaler (CA) ノードプールのサイズを自動調整し、Pod のスケジューラが失敗したときにノード追加。 Azure VM Scale Set と連携。--scale-down-delay-after-add=10m で急激なスケールイン防止。 GKE の autoscaling-profile=balanced がデフォルト。Node pool ごとに maxPodsPerNode を適切に設定し、VPA 推奨上限が収まるよう調整。

実践的フロー
1. VPA が requests を増やしたら、CA が自動でノード数を拡張(必要に応じて別サイズの VM/Node pool にシフト)。
2. CA がスケールアウトした瞬間、kube‑scheduler が保留中だった Pod を再度スケジュールし直す。
3. メモリ圧迫が解消されたら、CA は scale-down-unneeded-time(デフォルト 10 min)経過後に余剰ノードを削除。

この循環を 「Memory‑aware Autoscaling」 と呼び、AKS・GKE 共通のベストプラクティスとして推奨します。


7. OOMKilled インシデントレスポンスチェックリスト(ブランド別追加項目)

# アクション AKS 向け具体例 GKE 向け具体例
1 Pod 定義のリソース検証 az aks browse → Azure Policy で AllowedResources: limits.memory を必須化。 gcloud resource-manager policies create --constraint=constraints/k8s.allowedResourceLimits
2 CI/CD でシミュレーション実行 GitHub Actions のステップで kubectl top podkube-score を組み合わせ、リソース不足を検知。 Cloud Build + kube-linter で同様にチェック。
3 Prometheus アラートのサイレンス管理 Azure Monitor の「Alert rule」→「Suppress during deployment window」設定。 Cloud Alerting の「Notification channel」→「Mute」機能を活用。
4 メモリリーク診断フロー Azure Application Insights の Live Metrics でコンテナメトリックをリアルタイム可視化。 GKE の Cloud ProfilerCloud Trace を組み合わせ、ヒープダンプ取得手順を Runbook に記載。
5 VPA / CA 設定の妥当性レビュー Azure Policy で vpa.autoscaling.k8s.ioAuto のみ許可し、maxAllowed 超過時は PR をブロック。 GKE の Config Connector に AutoscalingPolicy リソースをデプロイし、ポリシー違反を自動で PR に変換。
6 インシデント対応 Runbook の整備 Azure DevOps Wiki に「OOMKilled 対応フロー」ページ作成 → kubectl describe podaz monitor metrics alert list. Google Cloud Documentation に同様の手順を Markdown で保存し、ChatOps (Google Chat Bot) と連携。
7 定期的な負荷テスト実施 Azure Load Testing Service で memcached ストレスシナリオを走らせ、メモリ使用率が 85 % 超えるか検証。 GKE の kubetest2stress-ng イメージで同様に実行し、結果を Cloud Logging に保存。

注記:上表は AKSGKE が提供するネイティブ機能・CLI を活用した例です。自社の CI/CD パイプラインや SRE ツールチェーンに合わせてカスタマイズしてください。


8. 最終まとめ(Key Takeaways)

  1. OOM の根本原因は二系統
  2. ノード全体の MemoryPressure → kubelet が eviction、必要なら OOM Killer。
  3. コンテナ cgroup ハードリミット超過 → 直接 SIGKILL(Pod が即座に OOMKilled)。

  4. NodeProblemDetector の役割は「状態フラグ付与」 に止まり、実際のプロセス殺害は kubelet またはカーネルが行うことを認識しておく。

  5. QoS クラスとリソース設定は Eviction の優先順位を決定 する最重要パラメータ。

  6. 本番は Guaranteed に近づけ、Burstable は最低でも requests を必ず設定。

  7. AKS と GKE の固有機能(Azure Monitor + Advisor、GKE Autopilot / Cloud Monitoring)を活用し、MemoryPressure → Eviction の自動化とスケールアウトの連携を実装する。

  8. Observability は Prometheus/Grafana(AKS)または Managed Prometheus/Cloud Monitoring(GKE)でメトリクスとアラートを一元管理し、段階的閾値(80 % Warning / 90 % Critical)で過剰なノイズを抑制。

  9. VPA + Cluster Autoscaler の組み合わせ が最も効果的な「Memory‑aware Autoscaling」戦略となり、OOM 発生リスクを根本から低減できる。

  10. インシデントレスポンスは自動化(Azure Policy / GKE Config Connector)と定期的負荷テストで事前検証し、Runbook に落とし込んだ手順で迅速対応が可能。

以上を踏まえて、AKS・GKE 環境それぞれに最適化された メモリ管理パイプライン を構築すれば、OOMKilled の発生率は大幅に低減し、サービスの可用性とコスト効率が向上します。


本稿は 2024 年 11 月時点の Kubernetes v1.30、AKS 2024‑3、GKE 2024‑2 の仕様を元に執筆しています。バージョンアップや新機能追加に伴い、設定項目が変化する可能性がありますので、公式ドキュメントの定期的なレビューを推奨します。

スポンサードリンク

お得なお知らせ

スポンサードリンク
1ヶ月で資格+現場入り

インフラエンジニアへの最短ルート

未経験でもAWS・Linux・ネットワーク資格を最短で取り、現場入りまでサポート。SREやクラウドエンジニアの入口。

CODE×CODEスピード転職|無料面談▶ SRE/クラウドのフリーランス案件▶

▶ AWS/GCP/Kubernetesの独学には Kindle Unlimited の技術書読み放題がコスパ最強。


-Kubernetes