首页/云/云与容器速查/K8s OOMKilled 排查

K8s OOMKilled 排查

容器内存超过 limit 被内核杀死:状态里 reason=OOMKilled、退出码 137。和 Docker 一致:先确认 limit 与真实用量,再区分配置问题与应用内存增长。

云与容器速查云更新于 2026-10-13

K8s OOMKilled 是什么

Pod 里的容器内存超过 limits 上限会被内核杀死,容器状态里 reason 显示 OOMKilled、退出码 137。与单机 Docker 的判断逻辑一致:先确认生效的限制值与真实用量峰值,再区分是限制设得太小还是应用内存真的在涨。差别在于 Kubernetes 里还要多看一层——节点内存压力同样会触发驱逐,根因未必在容器本身。

基本信息

确认方式取容器状态 lastState 中的 terminated.reason 是否为 OOMKilled
对比对象limits.memory 与 kubectl top 或监控里的峰值内存
节点侧因素节点内存压力会触发驱逐,需查节点事件与内核记录
常见修正调大 limit、修内存增长、限制并发与缓存
预防建议requests 与 limits 设置得接近,配合压测与内存告警

典型使用场景

  • Pod 反复重启:确认是否每次都是内存超限被杀
  • 发布回归:新版本内存占用上升,用峰值对比定位变化
  • 大促前评估:按压测峰值重新设定内存上下限
  • 节点驱逐排查:多个 Pod 同时异常,怀疑是节点资源不足
  • 成本优化:用真实峰值下调过大的 limit,提升装箱率

排查命令

排查命令
kubectl get pod web-1 -o jsonpath='{.status.containerStatuses[0].lastState}'
# 关注 reason 是否为 OOMKilled 与 exitCode 是否为 137
kubectl top pod web-1                      # 当前实际用量
kubectl describe pod web-1 | grep -i oom   # 事件里的相关记录
kubectl describe node node-1 | grep -i memory | head   # 节点内存压力
kubectl get pod web-1 -o jsonpath='{.spec.containers[*].resources}'   # 生效限制

判定与处置对照

现象判定处置方向
稳定运行后周期性被杀内存随流量或时间增长排查泄漏,结合长期曲线判断
一起量立即被杀limit 低于实际需求按峰值重新设定 limit
多个 Pod 同时异常节点内存压力导致驱逐扩容节点或调整 requests
只有生产环境出现数据量或并发高于测试用生产负载压测后调参
只把 limit 调大并不能解决问题:如果应用的记忆曲线仍在上涨,早晚还会撞墙。上线前按压测峰值的一点三到一点五倍设限,比事后反复加大更稳。
完全不设 limits 风险更大:容器内存无界会先耗尽节点内存,触发节点级驱逐,波及同一节点上的所有业务,影响面远超单个容器。

易错点

  • limits 完全不设,内存无界,节点先撑不住并驱逐其他业务
  • Java 只按堆参数估算,堆外内存与线程栈加起来远超 limit
  • requests 与 limits 差距过大,调度按 requests 安排,节点实际内存被超卖
  • 把 OOMKilled 当成偶发事件反复重启,不做峰值统计与容量复盘

数据来源与参考

  • Kubernetes Docs:Resource Management
  • Kubernetes Docs:Pod QoS

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌