← 中文资源

简体中文版本

十分钟定位 CrashLoopBackOff 根因

读上一次容器日志、退出码与事件消息,给崩溃原因分类,修对那一层而不是反复重启。

阅读英文原文

目标

CrashLoopBackOff 会把自己的证据藏起来:当前容器刚启动,日志一片空白。真正有价值的是上一次已终止容器的日志、它的退出码与退出原因,以及调度事件。三个信息组合能在几分钟内把故障分类为应用报错、内存超额被杀或探针误杀,然后修对相应层,而不是反复重启白白消耗退避时间。

步骤要点

  1. 用 kubectl logs –previous –tail=50 读上一次容器的临终日志,通常能直接看到栈、缺文件或配置解析错误。
  2. 用 jsonpath 取 lastState.terminated 的 exitCode 与 reason,Error 加 exit=1 指向应用自身,OOMKilled 加 137 指向内存超额。
  3. describe pod 看事件段,区分探针不健康、ConfigMap 挂载失败与调度失败等不同方向的修复。
  4. 用同一镜像交互式起临时 Pod,检查 env 与配置文件是否存在,确认或排除配置层问题后再改清单。
  5. 修对应层(例如 set env 补 CONFIG_PATH)后用 rollout status 验证一次,重启计数归零不动才是真正的成功标准。

排错提示

日志为空多半是应用写文件不写 stdout,先 exec 查看日志文件,或临时把容器命令改成 tail 日志文件;exit=137 立即出现就是 OOMKilled,确认真实需求后调大内存限额,并检查堆配置是否超过容器限额;交互式能跑但部署里崩,常是 liveness 探针在启动完成前杀进程,加 startupProbe 或调大 initialDelaySeconds 而不是放宽所有检查。

适用边界

–previous 只保留最近一次终止容器,更早的崩溃需要日志外发或事件回放;CrashLoopBackOff 的退避是指数级的,修复后的验证可能要等几分钟,盯着 rollout status 而不是反复查询重启数。

代码示例

# What did the LAST run say before dying?
kubectl logs worker-7d9c6b5-x2lkp --previous --tail=20
# Error: ENOENT: no such file or directory, open '/app/config/prod.yaml'

# How did it die?
kubectl get pod worker-7d9c6b5-x2lkp -o jsonpath=\
  "{.status.containerStatuses[0].lastState.terminated.reason}"
# Error   (not OOMKilled -> app-level failure)

# Fix the named layer, then verify once
kubectl set env deployment/worker CONFIG_PATH=/app/config/prod.yaml
kubectl rollout status deployment/worker --timeout=120s