Kubernetes の「メモリ使用量」は一つではない: OOMKilled と Eviction の見分け方
kubectl top が見ている working set と、memcg OOM(memory.current vs limit)と、kubelet の eviction(ノードの memory.available)は別物。だから「top では余裕があるのに OOMKilled」「MemAvailable ベースでは空いているのに Evicted」が起こる。
どんなときに使う?
- コンテナが
OOMKilledされたが limit まで余裕があるように見える - ノード使用率が低そうなのに Pod が Evicted される
- request の見直しで global OOM / eviction を減らしたい
覚え方(イベントと見ている値)
| イベント | 見ている値 | 条件のイメージ |
|---|---|---|
| memcg OOM | コンテナ/Pod/kubepods の memory.current | memory.max(limit)に達し、reclaim しても下がらない |
| global OOM | ノード全体のメモリ枯渇 | oom_score で犠牲プロセスを選ぶ(request / QoS が効く) |
| Eviction | ノードの memory.available ≒ MemTotal − ルート cgroup の working set | kubelet の evictionHard / Soft(既定は memory.available<100Mi など) |
kubectl top/container_memory_working_set_bytesは working set(おおむねmemory.current − inactive_file)。RSS ではない- memcg OOM は working set ではなく
memory.currentを limit と比較する - Node に
SystemOOMイベントがあれば global OOM の証拠。無いからといって memcg とは限らない(イベント保持は既定約 1 時間)
対処の優先順位
- 実際の使用量に合わせて memory request を合わせる — 配置密度・eviction 候補・
oom_score_adjに効く(global OOM / eviction 向け)。memcg OOM には効かない - memcg OOM なら limit の見直しと、Pod /
kubepods.slice側で当たっていないかも確認 - 調査の入口:
kubectl describe podのOOMKilled→ ノードのSystemOOM→container_memory_usage_bytesと working set / RSS の比較
詳細な cgroup v2 対応表・PromQL・VPA の話は出典記事にまとまっている。