Kubernetes Pod 故障排查指南:从状态识别到根因定位的完整实践

做 Kubernetes 运维的同学,十有八九都遇到过 Pod 各种状态异常的问题。

半夜三点收到告警,发现 Pod 在 CrashLoopBackOff 里挣扎,这种场景估计大家都经历过。

本文结合实战经验,梳理一套通用的 Pod 故障排查流程,帮你快速定位问题。

一、先看懂 Pod 状态

Pod 的状态是排查的起点,不同状态对应不同的排查方向。

arduino 复制代码
kubectl get pods -o wide

重点关注 STATUSRESTARTS 两列:

状态 含义 紧急程度
CrashLoopBackOff 容器持续崩溃重启 🔴 立刻处理
ImagePullBackOff 镜像拉取失败 🔴 立刻处理
Pending Pod 未被调度 🟡 30分钟内处理
Running 但不健康 容器在跑但服务异常 🔴 立刻处理
Evicted 节点资源不足被驱逐 🟡 30分钟内处理

二、CrashLoopBackOff:容器启动失败

这是最常见的故障状态,背后原因可能有多种。

排查步骤

1. 查看容器日志(最先做)

ini 复制代码
# 查看当前日志
kubectl logs <pod-name> --tail=100

# 查看上一次崩溃的日志(关键!)
kubectl logs <pod-name> --previous

# 实时追踪日志
kubectl logs <pod-name> -f

2. 查看 Pod 事件

sql 复制代码
kubectl describe pod <pod-name>

重点看 Events 部分,Kubernetes 会在这里给出失败原因的描述。

3. 常见根因分析

应用启动失败

makefile 复制代码
# 典型错误:连接数据库超时
Error: Connection refused: mysql-service:3306

解决方案:检查依赖服务是否就绪,配置合理的启动超时时间。

OOMKilled(内存溢出)

vbnet 复制代码
Exit Code: 137
OOMKilled: true

解决方案:合理设置 resources limits

vbnet 复制代码
Exit Code: 137
OOMKilled: true

健康检查配置不当

yaml 复制代码
livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30  # 关键:避免冷启动误杀
  periodSeconds: 5
  failureThreshold: 3

三、ImagePullBackOff:镜像拉取失败

这个问题排查相对简单。

1. 检查镜像地址

ini 复制代码
# 查看 Pod 使用的镜像
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[].image}'

2. 常见原因

原因 现象 解决方案
镜像名拼写错误 ErrImagePull 修正镜像地址
私有仓库无权限 ImagePullBackOff 配置 imagePullSecrets
节点网络不通 ImagePullBackOff 检查网络策略
镜像版本不存在 ErrImagePull 确认 tag 是否正确

3. 私有仓库配置示例

ini 复制代码
# 创建 Secret
kubectl create secret docker-registry my-registry \
  --docker-server=registry.example.com \
  --docker-username=admin \
  --docker-password=xxxxx

# Pod 中引用
spec:
  imagePullSecrets:
    - name: my-registry

四、Pending:调度失败

Pending 状态说明 Pod 还没被调度到节点上。

1. 查看调度原因

css 复制代码
kubectl describe pod <pod-name> | grep -A 10 Events

常见原因:

  • 资源不足Insufficient CPU/Memory
  • 调度约束不满足:nodeSelector、affinity、taints/tolerations 冲突
  • PVC 未绑定:存储依赖未就绪

2. 节点资源检查

perl 复制代码
kubectl describe node | grep -A 5 "Allocated resources"

3. 污点和容忍度问题

vbnet 复制代码
# Pod 需要的容忍度
spec:
  tolerations:
  - key: "disk-pressure"
    operator: "Exists"
    effect: "NoSchedule"

五、Running 但不健康

Pod 状态显示 Running,但服务响应异常。

1. 检查探针状态

bash 复制代码
kubectl describe pod <pod-name>
# 看 Containers 下的 Readiness 和 Liveness

2. 端口配置核对

Service 配置中容易混淆的三个端口:

字段 含义 示例
port Service 暴露端口 80
targetPort 转发到 Pod 的端口 8080
containerPort Pod 内应用监听的端口 8080

3. Service Selector 检查

csharp 复制代码
# 查看 Pod 标签
kubectl get pods --show-labels

# 查看 Service 的 selector
kubectl get svc <service-name> -o jsonpath='{.spec.selector}'

两者必须匹配,否则流量无法到达 Pod。

六、实用排查命令清单

ini 复制代码
# 1. 快速定位所有异常 Pod
kubectl get pods --field-selector=status.phase!=Running -A

# 2. 查看集群事件(按时间排序)
kubectl get events --sort-by='.lastTimestamp'

# 3. 进入容器调试
kubectl exec -it <pod-name> -- sh

# 4. 使用调试镜像临时进入
kubectl debug <pod-name> -it --image=nicolaka/netshoot

# 5. 端口转发测试
kubectl port-forward <pod-name> 8888:8080

# 6. 网络连通性测试
kubectl exec <pod-name> -- curl -I http://<service-name>:80

七、生产环境建议

1. 完善监控告警

yaml 复制代码
# Prometheus 告警规则示例
- alert: PodCrashLoop
  expr: kube_pod_container_status_restarts_total > 3
  for: 5m
  labels:
    severity: critical

2. 规范健康检查配置

所有服务必须配置 readinessProbelivenessProbe,关键服务建议加 startupProbe

3. 资源配额规范

yaml 复制代码
resources:
  requests:
    cpu: "100m"
    memory: "256Mi"
  limits:
    cpu: "500m"
    memory: "512Mi"

总结

Pod 故障排查的核心是建立清晰的排查路径:

状态 → 事件 → 日志 → 配置 → 网络

按这个顺序逐层排查,能解决绝大多数问题。

最后说一句:转行做运维前期确实会遇到很多"没见过的状态",但只要掌握了排查方法论,很多问题其实没那么可怕。

有问题欢迎评论区交流。

相关推荐
JAVA96519 小时前
JAVA面试-JVM篇 03-JVM运行时数据区哪些是线程私有的哪些是共享的
java·jvm·面试
枫子有风21 小时前
LLM-Agent智能体(大厂面试常问)
面试·职场和发展·llm·agent
Oo_行者_oO1 天前
删库先别跑路,万一修复呢?MySQL 误删数据恢复可落地运维文档
数据库·面试
Moment1 天前
从多人编辑到 Agent 写文档,Hocuspocus v4 正在改写协同系统 😍😍😍
前端·后端·面试
贺国亚1 天前
评估-Eval-Hallucination与质量度量
后端·面试
javaDocker1 天前
某大厂AI应用开发面试题
面试·职场和发展
CS_SKILL1 天前
腾讯后台社招一面:系统调用、TCP 可靠性、URL 到 DNS,再加一个计时函数设计题
网络·tcp/ip·面试·腾讯校招·后台开发面经
CoderYanger1 天前
A.每日一题:2095. 删除链表的中间节点
java·数据结构·程序人生·leetcode·链表·面试·职场和发展
周末也要写八哥1 天前
面经经验分享|熟练掌握面试考点
经验分享·面试·职场和发展
不知名的老吴1 天前
面经经验分享|模拟面试的重要性前瞻
经验分享·面试·职场和发展