You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K8s 1.15中Job的Pod发生OOM却显示Succeeded的问题

基础环境
  • K8s 版本:1.15
问题场景
  • 业务侧部署了一个设置了2Gi内存限制的Job
  • 任务实际运行的内存需求超过设定的2Gi配额,触发节点内核OOM回收机制
  • 观测到的异常表现:
    • Job状态显示为completed
    • 关联Pod状态为succeeded
    • Pod主容器上报的退出码为0(常规定义为任务正常执行结束)
    • 实际Pod是被OOM机制强制终止的
      现象参考:
      现象截图
异常诱因

该异常是K8s 1.15版本kubelet内置的容器状态同步逻辑bug导致的,完整触发链路为:

  • 正常场景下,容器内存超过cgroup设定的limit阈值时,内核会触发OOMKill强制终止容器主进程,容器运行时会向上上报终止事件为OOMKilled,对应退出码为137;kubelet会将该真实状态同步给API Server,Job控制器收到失败状态后会判定Pod执行失败,不会将Job标记为Completed。
  • 在1.15版本中,kubelet在处理容器状态转换的临界时序时存在缺陷:当OOMKill事件发生在容器从Running状态向Terminated状态转换的间隙,kubelet的状态缓存会被容器正常运行阶段的临时退出状态覆盖,错误将实际被OOM终止的容器状态,标记为正常退出(退出码0、退出原因Completed)。
  • Job控制器的状态判定逻辑仅校验Pod上报的退出码字段,不会额外回溯lastState中记录的真实终止原因,直接将状态错配的Pod判定为执行成功,最终出现Job显示完成、实际任务未正常执行的异常。
排查步骤
  • 拉取异常Pod的完整描述信息,重点核对state和lastState两个字段的内容,避免被当前显示的正常退出状态误导:执行命令kubectl describe pod <异常Pod名称>,如果在lastState.terminated区域发现Reason: OOMKilled、退出码137的记录,即可确认是状态上报错配问题。
  • 登录Pod所在的工作节点,查看内核OOM日志:执行命令dmesg -T | grep -i 'out of memory',交叉核对日志中对应的cgroup内存超限、进程被OOMKill的时间点,和Pod的运行时间做匹配,确认OOM触发的事实。
  • 检查关联Job的全量事件流:执行kubectl describe job <异常Job名称>,核对事件序列中Pod被标记为成功的时间点,和节点OOM日志的时间是否吻合,排除其他导致Pod假成功的因素。
解决方案
  • 临时规避:修改任务启动脚本,在业务逻辑中增加内存占用监控逻辑,当检测到运行内存接近配置的limit阈值时,主动释放资源、优雅退出并返回非0错误码,避免触发内核强制OOM的路径,绕开kubelet的状态上报bug。
  • 版本修复:将K8s集群升级到1.16及以上的稳定版本,上述kubelet状态同步错配的bug已在后续版本中修复,可正确上报OOMKill事件的真实状态,不会再出现退出码错配的问题。
  • 兜底校验:在集群中配置自定义的状态校验规则,对所有Job资源增加判定逻辑,一旦检测到Pod存在OOMKilled的历史状态,即使上报的退出码为0,也强制将Job标记为失败状态,避免假成功的任务误导业务流程。

内容的提问来源于stack exchange,提问作者fresh learning

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 14:45:03