Kubernetes作为容器编排领域的事实标准,其复杂的状态机机制使故障排查成为SRE稳定性工程的日常挑战。Pod作为K8s最小调度单元,其状态直接反映应用健康度。本文系统梳理Pod常见异常状态的诊断方法和修复流程,帮助运维团队缩短故障应急响应时间。
Pod生命周期与状态机解析
Kubernetes中Pod经历Pending、Running、Succeeded、Failed、Unknown等状态。DevOps实践中,准确判断Pod停留在哪个异常状态是排查的第一步。使用kubectl获取详细事件信息:
# 查看Pod状态
kubectl get pods -n production
# 查看Pod详情(事件、调度信息、容器状态)
kubectl describe pod <pod-name> -n production
# 查看Pod事件(按时间排序)
kubectl get events -n production --sort-by='.lastTimestamp'
# 实时观察Pod变化
kubectl get pods -n production -w
describe输出中的Events部分是诊断的核心信息源,记录了调度、拉取镜像、启动容器等各阶段的事件,按时间倒序排列。
Pending状态:调度失败排查
Pod处于Pending状态通常表示调度器无法为其找到合适的节点。常见原因包括资源不足、节点污点未容忍、节点选择器不匹配。
# 查看调度失败原因
kubectl get pod <pod-name> -n production -o jsonpath='{.status.conditions[?(@.type=="PodScheduled")].message}'
# 检查节点资源使用情况
kubectl describe nodes | grep -A 5 "Allocated"
# 查看节点资源分配百分比
kubectl get nodes -o custom-columns="NAME:.metadata.name,CPU:.status.allocatable.cpu,MEM:.status.allocatable.memory"
# 检查Pod的资源请求是否超出节点容量
kubectl get pod <pod-name> -n production -o jsonpath='{.spec.containers[*].resources.requests}'
资源不足是最常见原因。当节点CPU或内存分配率达到90%以上时,调度器不再分配新Pod。解决方案包括扩容节点、降低Pod资源请求、或清理异常占用资源的Pod。
# 临时扩容节点池(云环境)
kubectl scale nodepool production-pool --replicas=5
# 调整Deployment资源请求
kubectl set resources deployment api-gateway -n production \\
--requests=cpu=200m,memory=256Mi \\
--limits=cpu=500m,memory=512Mi
# 检查污点和容忍配置
kubectl get nodes -o custom-columns="NAME:.metadata.name,TAINTS:.spec.taints"
CrashLoopBackOff:容器反复崩溃
CrashLoopBackOff表示容器启动后立即退出,Kubelet反复尝试重启。这是Kubernetes容器编排中最棘手的故障之一,需要检查容器日志和退出码。
# 查看容器日志(当前容器实例)
kubectl logs <pod-name> -n production
# 查看上一个崩溃容器的日志(关键!)
kubectl logs <pod-name> -n production --previous
# 查看容器退出码
kubectl get pod <pod-name> -n production -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'
# 查看重启次数
kubectl get pod <pod-name> -n production -o jsonpath='{.status.containerStatuses[0].restartCount}'
常见的退出码含义:0表示正常退出(检查是否缺少前台进程),1表示应用错误,137表示OOM被杀,139表示段错误,143表示收到SIGTERM。
OOM Killer是CrashLoopBackOff的常见诱因。检查内存限制和应用实际使用量:
# 查看是否被OOM Kill
kubectl get pod <pod-name> -n production -o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}'
# 查看容器内存使用
kubectl top pod <pod-name> -n production
# 增加内存限制
kubectl set resources deployment worker -n production \\
--limits=memory=1Gi
ImagePullBackOff:镜像拉取失败
镜像拉取失败通常由镜像名称错误、仓库认证缺失或网络策略阻断导致。CI/CD流水线中最容易出现此类问题。
# 查看拉取失败详情
kubectl describe pod <pod-name> -n production | grep -A 10 "Events:"
# 检查镜像名称是否正确
kubectl get pod <pod-name> -n production -o jsonpath='{.spec.containers[0].image}'
# 配置私有仓库认证
kubectl create secret docker-registry regcred \\
--docker-server=registry.yunthe.com \\
--docker-username=admin \\
--docker-password=<password> \\
--docker-email=admin@yunthe.com
# 在Deployment中引用Secret
# spec.template.spec.imagePullSecrets:
# - name: regcred
Init容器阻塞排查
Init容器必须按顺序成功执行完毕,主容器才会启动。如果Init容器卡住,Pod会一直停留在Init状态。日志分析时需要指定容器名称:
# 查看Init容器状态
kubectl get pod <pod-name> -n production -o jsonpath='{.status.initContainerStatuses[*].state}'
# 查看指定Init容器日志
kubectl logs <pod-name> -n production -c init-db
kubectl logs <pod-name> -n production -c init-config --previous
# 常见阻塞原因:等待数据库就绪
kubectl exec <pod-name> -c init-db -n production -- nslookup mysql-service
kubectl exec <pod-name> -c init-db -n production -- wget -qO- http://config-service:8080/health
就绪探针与存活探针配置问题
探针配置不当会导致Pod被反复重启或从Service端点摘除。监控告警体系中,探针失败是高频告警源。排查时关注探针配置参数和实际响应时间。
# 查看探针配置
kubectl get pod <pod-name> -n production -o jsonpath='{.spec.containers[0].readinessProbe}'
kubectl get pod <pod-name> -n production -o jsonpath='{.spec.containers[0].livenessProbe}'
# 查看探针失败事件
kubectl describe pod <pod-name> -n production | grep -E "Liveness|Readiness|Unhealthy"
# 进入容器手动测试探针端点
kubectl exec -it <pod-name> -n production -- curl -v http://localhost:8080/health
就绪探针的initialDelaySeconds设置过短会导致应用尚未启动完成就被标记为不健康。建议根据应用实际启动时间设置,Java应用通常需要30-60秒,Go应用约5-10秒。
网络策略导致的服务不通
Kubernetes NetworkPolicy限制Pod间通信。混沌工程演练中,网络策略误配是常见的”人为故障”场景。排查连通性时需要逐段检查:
# 检查NetworkPolicy
kubectl get networkpolicy -n production
kubectl describe networkpolicy <policy-name> -n production
# 临时部署调试Pod测试连通性
kubectl run debug --image=nicolaka/netshoot -it --rm --restart=Never -n production
# 在调试Pod中执行网络诊断
dig nginx-service.production.svc.cluster.local
curl -v http://nginx-service:80
tcpdump -i eth0 -n port 80
# 检查CoreDNS解析
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs <dns-pod> -n kube-system
故障应急响应中应建立标准化排查流程:先查Pod状态,再查容器日志,然后检查探针和事件,最后排查网络和存储。每个环节使用对应的诊断命令,形成可复用的SOP文档。配合监控告警体系的自动化触发,可将平均故障恢复时间(MTTR)压缩至分钟级别。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-rong-qi-bian-pai-gu-zhang-pai-cha-pod-yi-chang/