容器应用启动失败故障排查实战指南 一、问题概述 容器应用启动失败是 Kubernetes 和 Docker 环境中最常见的运维问题之一。本文系统梳理容器启动失败的各类场景,提供完整的排查思路和解决方案。
二、常见故障现象 2.1 容器状态异常 1 2 3 4 5 6 7 8 9 10 kubectl get pods -n <namespace> docker ps -a
2.2 关键诊断命令 1 2 3 4 5 6 7 8 9 10 11 kubectl describe pod <pod-name> -n <namespace> docker inspect <container-id> kubectl logs <pod-name> -n <namespace> [--previous] docker logs <container-id> kubectl exec -it <pod-name> -n <namespace> -- /bin/sh docker exec -it <container-id> /bin/sh
三、故障分类与排查 3.1 镜像拉取失败 (ImagePullBackOff) 症状 :Pod 状态显示 ImagePullBackOff 或 ErrImagePull
排查步骤 :
1 2 3 4 5 6 7 8 9 10 11 kubectl describe pod <pod-name> kubectl get secret <registry-secret> -n <namespace> -o yaml docker pull <image-name>:<tag>
解决方案 :
1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: v1 kind: Secret metadata: name: regcred type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: <base64-encoded-config> spec: imagePullSecrets: - name: regcred
3.2 容器反复重启 (CrashLoopBackOff) 症状 :容器启动后立即退出,RESTARTS 计数持续增加
排查步骤 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[*].lastState}' kubectl logs <pod-name> --previous kubectl describe pod <pod-name> | grep -A 5 "Limits"
常见原因与解决 :
退出码
可能原因
解决方案
1
应用配置错误、依赖缺失
检查配置文件、环境变量
127
ENTRYPOINT 命令不存在
检查 Dockerfile 或 command 配置
137
内存不足被 OOMKilled
增加 memory limit
1
端口已被占用
检查端口冲突
3.3 健康检查失败 (Liveness/Readiness Probe) 症状 :容器运行但被 Kubernetes 不断重启
排查步骤 :
1 2 3 4 5 6 kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].livenessProbe}' kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].readinessProbe}' kubectl get events --field-selector involvedObject.name=<pod-name>
优化建议 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 failureThreshold: 3
3.4 配置挂载失败 症状 :CreateContainerConfigError 或 MountVolume.SetUp failed
排查步骤 :
1 2 3 4 5 6 7 8 9 10 kubectl describe pod <pod-name> | grep -A 10 "Mounts" kubectl get configmap <name> -n <namespace> kubectl get secret <name> -n <namespace> kubectl get pvc -n <namespace> kubectl get pv
常见问题 :
ConfigMap/Secret 不存在 :创建后再部署
挂载路径冲突 :检查多个卷是否挂载到同一路径
权限问题 :检查 fsGroup 和 securityContext
1 2 3 4 securityContext: fsGroup: 1000 runAsUser: 1000 runAsGroup: 1000
3.5 资源不足导致启动失败 症状 :Pending 状态或 OOMKilled
排查步骤 :
1 2 3 4 5 6 7 8 9 10 kubectl top nodes kubectl describe node <node-name> kubectl describe quota -n <namespace> kubectl describe limitrange -n <namespace> kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].resources}'
解决方案 :
1 2 3 4 5 6 7 resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m"
3.6 网络相关问题 症状 :容器启动但无法连接外部服务
排查步骤 :
1 2 3 4 5 6 7 8 9 10 11 12 kubectl exec <pod-name> -- nslookup <service-name> kubectl get networkpolicy -n <namespace> kubectl get svc -n <namespace> kubectl describe svc <service-name> kubectl exec <pod-name> -- curl -v <target-service>
3.7 依赖服务未就绪 症状 :应用启动时连接数据库/缓存失败
解决方案 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 initContainers: - name: wait-for-db image: busybox command: ['sh' , '-c' , 'until nc -z database 5432; do echo waiting; sleep 2; done' ] command: ["/bin/sh" , "-c" ]args: - | echo "Waiting for database..." until pg_isready -h $DB_HOST -p $DB_PORT; do sleep 2 done echo "Database ready, starting app..." exec /app/start.sh
四、排查流程图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 容器启动失败 │ ├─→ 状态:ImagePullBackOff │ └─→ 检查镜像名、标签、认证 │ ├─→ 状态:CrashLoopBackOff │ ├─→ 查看退出码 │ ├─→ 检查日志 (含 previous) │ └─→ 检查资源限制 │ ├─→ 状态:CreateContainerConfigError │ └─→ 检查 ConfigMap/Secret/Volume │ ├─→ 状态:Pending │ ├─→ 检查节点资源 │ ├─→ 检查调度约束 │ └─→ 检查配额限制 │ └─→ 状态:Running 但服务异常 ├─→ 检查健康探针 ├─→ 检查网络连通性 └─→ 检查依赖服务
五、实战案例 案例 1:Java 应用 OOMKilled 问题 :Spring Boot 应用频繁重启,退出码 137
排查 :
1 2 kubectl describe pod app-xyz | grep -i "oom"
解决 :
1 2 3 4 5 6 7 resources: limits: memory: "1Gi" env: - name: JAVA_OPTS value: "-Xmx512m -Xms256m"
案例 2:配置热更新导致重启 问题 :ConfigMap 更新后应用异常
解决 :使用子路径挂载避免自动更新,或实现配置热加载
1 2 3 4 5 6 7 8 volumeMounts: - name: config mountPath: /app/config.json subPath: config.json
六、预防建议
设置合理的资源限制 :基于实际压测结果配置
完善健康检查 :区分 liveness 和 readiness
优雅关闭处理 :捕获 SIGTERM,完成正在处理的请求
日志标准化 :输出到 stdout/stderr,便于收集
配置版本管理 :ConfigMap/Secret 变更先灰度
依赖检查 :启动前验证关键依赖可用
七、总结 容器启动失败排查需要系统性思维,按照”状态识别 → 日志分析 → 配置检查 → 资源验证 → 网络诊断”的流程逐步排查。建立标准化的排查清单和监控告警,可以大幅缩短故障恢复时间。