Kubernetes CrashLoopBackOff 排查全流程:从 describe 到日志到 exit code
2026/7/23 22:49:56 网站建设 项目流程

Kubernetes CrashLoopBackOff 排查全流程:从 describe 到日志到 exit code

线上发个版,Pod 状态突然变成CrashLoopBackOff,重启次数噌噌往上涨,服务 502。这几乎是每个用 K8s 的人都会撞上的场景。很多人第一反应是kubectl delete pod让它重建——但如果是配置或代码问题,重建再多次也是白搭,反而把现场删没了。

这篇按「看状态 → 看事件 → 看日志 → 看退出码」的顺序,把排查流程走一遍,每一步该敲什么命令、看什么关键字,讲清楚。

先搞懂 CrashLoopBackOff 是什么

它不是一种错误,而是一种状态:容器启动 → 崩溃退出 → kubelet 按退避策略(10s、20s、40s……最长 5min)等一会儿再重启 → 又崩。BackOff指的就是这个越来越长的重启间隔。

所以 CrashLoopBackOff 只告诉你「容器起来就挂」,真正的原因藏在崩溃的那一下。排查的核心是抓住崩溃瞬间的信息

第一步:kubectl get + describe 看全貌

# 看重启次数和状态,RESTARTS 高且在涨就是它kubectl get pod-nmyns# 关键:describe 看 Events 和上一次容器的退出状态kubectl describe pod my-app-7d9f-nmyns

describe输出里盯三个地方:

Last State: Terminated Reason: Error Exit Code: 1 # ← 退出码是最重要的线索 Started: ... Finished: ... State: Waiting Reason: CrashLoopBackOff

底部的Events区域也要看,像镜像拉不下来(ErrImagePull)、探针失败(Liveness probe failed)、OOM 都会在这里留痕。

第二步:退出码直接缩小范围

Exit Code是判断方向最快的信号,几个高频值背下来:

Exit Code含义常见原因
0正常退出容器主进程跑完就退了(比如把一次性脚本当常驻服务)
1应用异常代码抛未捕获异常、配置读不到
137被 SIGKILL(128+9)OOMKilled内存超限,或 liveness 探针杀的
143被 SIGTERM(128+15)优雅关闭,通常是被正常调度掉
126/127命令不可执行/找不到entrypoint 路径错、脚本没加执行权限

看到 137 别急着改代码,先确认是不是内存的事:

kubectl describe pod my-app-7d9f-nmyns|grep-ioom# 输出 Reason: OOMKilled 就实锤了内存超限

第三步:看日志,重点是「上一个」容器的日志

这是最容易踩的坑。Pod 已经重启了,kubectl logs默认给你的是当前这个容器的日志——它可能刚起来还没崩,啥也看不到。真正有价值的是崩掉的那个容器:

# -p / --previous 看上一个已终止容器的日志,这才是崩溃现场kubectl logs my-app-7d9f-nmyns--previous# 多容器 Pod 要指定容器名kubectl logs my-app-7d9f-nmyns-capp--previous

崩溃日志里通常直接写着原因:数据库连不上、环境变量缺失、端口被占、配置文件解析失败。绝大多数 Exit Code 1 都能在--previous日志里找到根因。

第四步:如果日志也是空的

有些容器崩得太快,--previous也捞不到东西(比如 entrypoint 直接报错、进程秒退)。这时换思路,让容器别崩,进去手动跑:

# 临时把 command 覆盖成 sleep,让 Pod 能起来供你调试apiVersion:v1kind:Podmetadata:name:debug-appspec:containers:-name:appimage:myrepo/my-app:v1.2.3# 用出问题的同一个镜像command:["sh","-c","sleep 3600"]# 覆盖原 entrypoint,先撑住
kubectl apply-fdebug-app.yaml kubectlexec-itdebug-app --sh# 进去后手动执行原来的启动命令,报错就直接打在你眼前/app/entrypoint.sh

这招能把「容器秒崩看不到日志」变成「命令行里直接报错」,屡试不爽。

高频根因对照

排查多了会发现,CrashLoopBackOff 翻来覆去就那么几类:

  • 配置缺失:ConfigMap/Secret 没挂上,或 key 名写错,应用读不到必需配置直接退。kubectl describeEnvironmentMounts能对一遍。
  • 依赖没就绪:启动时强连数据库/Redis,连不上就 panic。正确做法是加重试或用 initContainer 探测依赖。
  • liveness 探针太激进:应用启动慢(比如 JVM 预热),但initialDelaySeconds给太短,还没起来就被探针判死重启。表现是日志正常却反复重启,Events里有Liveness probe failed。改大initialDelaySeconds或改用startupProbe
  • OOMKilled(137):limits.memory给低了,或应用真漏内存。先把 limit 调合理,再排查是不是真泄漏。
  • 把一次性任务当服务跑(Exit 0):脚本跑完就退,Deployment 又拉起来。这种应该用 Job 而不是 Deployment。

小结

CrashLoopBackOff 排查记住这条链路:

  • kubectl get pod确认重启在涨 →kubectl describe podExit CodeEvents
  • 退出码先分方向:137 查 OOM,1 查应用异常,126/127 查启动命令。
  • kubectl logs --previous才是崩溃现场,别看当前容器日志。
  • 日志也捞不到,就用command: sleep覆盖 entrypoint,进容器手动跑复现。

一句话记忆点:别急着 delete pod,先 describe 看退出码、logs 加--previous看崩溃现场——删了就没现场了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询