exit code 137表示进程被sigkill(信号9)强制终止,需结合kubectl describe pod中last state的reason字段判断根因:reason为oomkilled即容器内存超限;reason为error则多为liveness探针失败;reason为evicted则属节点内存压力驱逐。

当Pod在Kubernetes中反复重启、日志突然中断、且kubectl get pod显示CrashLoopBackOff或OOMKilled状态时,Exit Code 137就是关键线索——它不是应用崩溃,而是Linux内核因内存超限直接终止了容器主进程。
确认是否真为OOMKilled
执行kubectl describe pod <pod-name> -n <namespace></namespace></pod-name>,重点检查Last State → Terminated字段:
若Reason: OOMKilled且Exit Code: 137同时出现,即可锁定为容器级内存超限;若Reason: Evicted或MemoryPressure,则是节点级驱逐,与137无关。
⚠️注意:Reason字段才是唯一判决依据,Exit Code 137本身只代表收到了SIGKILL信号,Liveness探针失败也会触发137,但Reason是Error而非OOMKilled。
查上一次容器的日志断点
运行kubectl logs -n <namespace><pod-name> --previous --tail=100</pod-name></namespace>。
OOMKilled的典型日志特征是:最后一行输出后戛然而止,无异常堆栈、无panic、无error字样;如果看到GC日志(如Full GC)、内存告警(如java.lang.OutOfMemoryError: Java heap space)或应用主动打印free memory: X MB后骤降,则高度指向内存泄漏或配置失衡。
这一步操作起来很简单,直接把命令敲进去就行。
比对内存使用与Limit的实际差距
① 查看当前Pod实时内存占用:kubectl top pod -n <namespace><pod-name></pod-name></namespace>;
② 查看Pod定义中的内存limit:kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.containers[*].resources.limits.memory}'</namespace></pod-name>;
③ 对比二者数值:若top结果持续逼近甚至等于limit(例如limit=200Mi,top显示195Mi),基本可判定为资源配额不足或应用内存增长失控;若top长期稳定在limit的60%以下却仍OOMKilled,则需排查JVM参数(如-Xmx未对齐limit)、sidecar内存争抢或cgroup v1/v2兼容性问题。
这一步必须做,否则所有后续优化都是盲调。
检查节点内存压力与历史OOM事件
方法一:用Prometheus查指标node_vmstat_oom_kill,该计数器每发生一次OOM Killer动作就+1,能定位到具体节点和时间点;
方法二:登录对应Node,执行dmesg -T | grep -i "killed process",输出中会明确列出被kill的进程名、PID、占用内存页数及触发时间,这是Linux内核留下的原始现场证据。
若发现多个不同Pod在同一节点频繁触发此日志,说明节点整体内存已严重过载,不是单个Pod的问题。
验证内存限制是否被正确继承
进入容器内部执行:cat /sys/fs/cgroup/memory/memory.limit_in_bytes。
该值应严格等于Pod YAML中设置的limits.memory(单位字节),例如limit设为200Mi,此处应显示209715200。若数值远大于预期,说明limit未生效——常见于使用了旧版Docker runtime、cgroup v1未启用memory子系统、或容器运行时配置绕过了Kubernetes资源限制。
【若此处数值异常,所有上层排查都将失效】











