← 中文资源

简体中文版本

Kubernetes OOMKilled — 容器超出内存限制

通过测量真实内存用量、上调或合理设定限制,并区分泄漏与瞬时峰值,修复 OOMKilled。

阅读英文原文

症状

本篇指南处理“Kubernetes OOMKilled — 容器超出内存限制”。请从症状出发,按顺序执行诊断,在推进前确认每个假设;随后通过修复与验证步骤闭环。

可观察到的症状包括:

  • Pod 反复重启,末次状态为 OOMKilled,退出码 137
  • 容器在高负载下终止,空闲时正常
  • kubectl describe pod 显示 “Reason: OOMKilled”

诊断

先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。

步骤 1

kubectl describe pod <pod> | grep -A 5 "Last State\|Limits"

末次状态为 OOMKilled 加上内存限制,显示被触及的上限。

步骤 2

kubectl top pod <pod> && cat /sys/fs/cgroup/memory.max

把实时用量与 cgroup 限制对比,可判断应上调限制还是修复泄漏。

常见诱因(按出现频率排序):

  • 容器内存限制低于其真实工作集
  • 无界缓存或缓冲区持续增长直至触及 cgroup 限制
  • 内存泄漏跨请求累积

根因

当容器的 cgroup 内存用量达到其限制时,内核 OOM killer 会终止该容器并杀掉占用最大的进程。Kubernetes 报告退出码 137 与原因 OOMKilled,这与应用层错误不同。

修复

把内存限制调整到观测峰值加余量,修复泄漏或无界缓存,设置 requests 以便调度,并使用感知内存上限的运行时(如堆上限)让应用自行管理内存。

注意:限制设得过高会导致节点资源压力与驱逐;应基于实测峰值而非猜测。

resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"   # peak + headroom, based on measurement
    cpu: "500m"

# Node.js: cap the heap below the container limit
env:
  - name: NODE_OPTIONS
    value: "--max-old-space-size=384"

验证

运行原始负载并确认无 OOMKilled 重启;验证稳态内存低于限制并留有头寸。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。