K8s Pod 频繁 CrashLoopBackOff 排查
2026-08-11 00:53:03
# Kubernetes
Pod 状态在 CrashLoopBackOff 与 Running 之间反复横跳,RESTARTS 计数持续增长。这说明容器启动后很快退出,kubelet 不断按退避策略重启它。本文给出从「看现象」到「定位根因」再到「修复」的完整路径。
问题现象与背景原因
1 | kubectl get pod |
CrashLoopBackOff 本身不是错误原因,而是结果:容器主进程异常退出,被 kubelet 反复拉起。常见根因:
- 应用启动即退出:启动命令写错、依赖服务(数据库 / 配置中心)不可达、配置文件 / 环境变量缺失,导致进程跑起来马上退出(Exit Code 0 / 1 / 2)。
- OOMKilled:容器内存超过
limits.memory,被 cgroup 杀掉(Exit Code 137)。 - 存活探针(livenessProbe)配置不当:初始延迟
initialDelaySeconds太短,或探测路径 / 端口错误,容器还没就绪就被判定失败杀死。 - 依赖未就绪 / 端口冲突:应用绑定的端口被占用,或需要的服务地址错误。
- 镜像问题:打错的镜像、entrypoint 与 CMD 冲突。
排查过程(思路与定位方法)
第一步:看退出码与最后状态。 describe 的 Last State 会告诉你容器是怎么死的,这是定位的第一手信息:
1 | kubectl describe pod api-6f9c8b7d-xk2p |
关注 Last State 与 Events:
1 | Last State: Terminated |
不同 Exit Code 指向不同方向:
| Exit Code | 含义 | 排查方向 |
|---|---|---|
| 0 / 1 / 2 | 应用自身退出 | 应用日志、启动命令、依赖 |
| 137 | 被 SIGKILL(OOM) | 内存 limit、内存泄漏 |
| 139 | SIGSEGV 段错误 | 应用 bug、原生库 |
| 143 | SIGTERM 优雅退出 | 被探针 / PreStop 杀掉 |
第二步:看崩溃前的日志(关键)。 容器已重启,当前日志可能不是崩溃那次的,必须加 --previous 看上一次:
1 | kubectl logs api-6f9c8b7d-xk2p --previous |
第三步:判断是不是探针问题。 若 describe 的 Events 里反复出现 Unhealthy: Liveness probe failed,说明是探针误杀:
1 | kubectl describe pod api-6f9c8b7d-xk2p | grep -i -A3 Unhealthy |
提示:
--previous是排查 CrashLoopBackOff 的必杀技。很多同学只kubectl logs当前容器,看到空日志就以为没输出,其实是看错了那一次。
最终的解决方法
- 应用退出(Exit 0 / 1 / 2):修正启动命令、补齐缺失的 ConfigMap / Secret / 环境变量;确认依赖服务地址可达。先用
kubectl run起一个临时调试容器进相同镜像排查。 - OOMKilled(137):调大
resources.limits.memory,或排查应用内存泄漏。临时先把 limit 调大让 Pod 先跑起来再优化。 - 探针误杀:调大
initialDelaySeconds(给应用足够启动时间),或把过严的livenessProbe先改成readinessProbe,排除探针本身的问题后再恢复。 - 端口 / 依赖冲突:检查
containerPort与实际监听端口是否一致,依赖地址是否从环境变量 / Service 名正确注入。
临时排错时可先去掉 livenessProbe 让容器保持 Running,再进容器内部调试:
1 | kubectl exec -it api-6f9c8b7d-xk2p -- sh |
操作命令(可直接复制执行)
1 | # 1. 看状态与重启次数 |