Kubernetes容器编排中Pod故障排查全流程:从CrashLoopBackOff到Running

Pod故障排查的基本思路

Kubernetes集群中Pod的状态异常是最常见的运维问题。排查Pod故障遵循一个核心原则:从外到内,逐层定位。先看Pod状态和事件,再看容器日志,最后进入容器内部检查进程和配置。熟练掌握这套排查流程,大部分Pod故障都能在15分钟内定位根因。

常见Pod异常状态速查表

不同状态对应不同的排查方向:

CrashLoopBackOff:容器启动后崩溃退出,kubelet反复重启。最常见的原因是应用程序启动失败、配置错误或依赖服务不可达。

ImagePullBackOff:镜像拉取失败。检查镜像地址、私有仓库认证、网络连通性。

Pending:Pod无法被调度到任何节点。通常是资源不足、节点选择器不匹配或PV未绑定。

Terminating:Pod删除时卡住。通常是因为preStop钩子阻塞或容器内进程不响应SIGTERM。

Completed:容器正常退出(exit code 0),但restartPolicy不是OnFailure。对于Job这是正常的,对于Deployment需要检查命令是否缺少常驻进程。

CrashLoopBackOff排查五步法

CrashLoopBackOff占生产环境Pod故障的60%以上。按以下步骤排查:

第一步:查看Pod事件

kubectl describe pod <pod-name> -n <namespace>

关注Events部分,尤其是最近一次的Warning事件。Liveness probe失败、OOMKilled等信息会直接显示在这里。

第二步:查看容器日志

# 查看当前容器日志
kubectl logs <pod-name> -n <namespace>

# 如果容器已重启,查看上一次的日志
kubectl logs <pod-name> -n <namespace> --previous

–previous参数非常关键,崩溃前的日志往往包含真正的错误原因。

第三步:检查退出码

kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'

常见退出码含义:137=OOMKilled(被内核杀掉);1=应用通用错误;2=命令语法错误。

第四步:检查探针配置

Liveness探针配置不当是CrashLoopBackOff的高频原因。特别是initialDelaySeconds设得太小,应用还没完成初始化就被探针判定死亡:

livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30    # 应用启动需要时间,别设成0
  periodSeconds: 10
  failureThreshold: 3         # 允许连续失败3次才重启

第五步:临时禁用探针验证

如果怀疑是探针导致的重启循环,可以临时修改部署移除Liveness探针,确认应用是否能正常运行:

kubectl edit deployment <deploy-name> -n <namespace>
# 删除livenessProbe段,保存退出

ImagePullBackOff排查方法

镜像拉取失败要检查三个环节:

# 1. 确认镜像地址是否正确
kubectl describe pod <pod-name> | grep -A5 "Events"

# 2. 检查私有仓库Secret是否存在
kubectl get secret -n <namespace>

# 3. 在节点上手动测试镜像拉取
docker pull <registry>/<image>:<tag>

国内环境拉取海外镜像经常超时。解决方案:配置镜像加速器,或使用国内镜像仓库同步。对于企业私有仓库,确认Secret的认证信息和仓库地址匹配:

kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=readonly \
  --docker-password=<token> \
  --docker-email=dev@example.com \
  -n <namespace>

Pod一直Pending的排查路径

Pod无法调度时,kubectl describe输出的Events会明确告诉你原因:

kubectl describe pod <pod-name> | grep -A10 "Events"

# 典型输出示例:
# Warning  FailedScheduling  0/3 nodes are available:
#   1 Insufficient cpu, 1 Insufficient memory, 1 node(s) had taints

对应解决方案:

资源不足:降低requests/limits,或给集群添加节点,或清理不再需要的资源。

Taint/Toleration不匹配:检查节点taint和Pod toleration是否兼容,特别是Master节点的node-role.kubernetes.io/control-plane taint。

PVC未绑定:检查StorageClass是否存在、是否有可用PV。

# 快速查看集群资源余量
kubectl top nodes
kubectl describe node <node-name> | grep -A5 "Allocated resources"

Pod卡在Terminating的处理

删除Pod后状态一直显示Terminating,通常是因为容器内进程没有正确处理SIGTERM信号,或者preStop钩子执行超时:

# 强制删除(跳过优雅终止)
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0

# 查看是否有finalizer阻塞
kubectl get pod <pod-name> -o jsonpath='{.metadata.finalizers}'

生产环境建议在Dockerfile中确保应用能正确响应SIGTERM。Spring Boot应用默认支持,但需要确认server.shutdown=graceful配置。Node.js应用需要监听process信号:

process.on('SIGTERM', () => {
  server.close(() => {
    process.exit(0);
  });
});

网络故障排查

Pod内服务无法访问外部或其他Pod时:

# 进入Pod测试网络
kubectl exec -it <pod-name> -- /bin/sh

# 在Pod内执行
nslookup kubernetes.default    # DNS是否正常
curl -v http://service-name:port/health  # 服务发现
curl -v http://external-url     # 出站连通性

# 检查Service和Endpoint
kubectl get endpoints <service-name> -n <namespace>
# 如果Endpoints是<none>,说明没有就绪的Pod匹配Selector

DNS问题排查:kubectl get pods -n kube-system -l k8s-app=kube-dns 确认CoreDNS运行正常。如果CoreDNS本身异常,整个集群的服务发现都会失效。

日志采集与持久化

容器重启后日志会丢失。生产环境务必配置日志持久化方案:

1. 标准输出方案:配合Filebeat/Fluentd采集容器日志到ES/Loki。

2. Sidecar日志代理:在Pod中注入日志采集Sidecar,适合需要采集文件日志的场景。

3. kubectl logs –since:临时排查时限制时间范围,避免拉取过多日志。

kubectl logs <pod-name> --since=1h --tail=200

排障命令速记

kubectl get pods -A 查看全集群Pod状态;kubectl describe pod 看事件和状态详情;kubectl logs –previous 看崩溃前日志;kubectl exec -it 进入容器内部排查;kubectl get events –sort-by=.metadata.creationTimestamp 按时间排查看最近事件。这五条命令覆盖了90%的Pod故障排查场景。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-rong-qi-bian-pai-zhong-pod-gu-zhang-pai-cha-quan/

(0)
小编小编
上一篇 13小时前
下一篇 13小时前

相关推荐