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 故障排查的核心是建立清晰的排查路径:

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

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

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

有问题欢迎评论区交流。

相关推荐
AI人工智能+电脑小能手5 小时前
【大白话说Java面试题 第77题】【Mysql篇】第7题:回表查询与全表扫描的区别?
java·开发语言·数据库·mysql·面试
张元清5 小时前
在 React 里写动画又不跟渲染周期较劲:useRafFn、useRafState、useFps、useDevicePixelRatio、useUpdate
前端·javascript·面试
代码帮6 小时前
面试题 - GIL全局解释器锁 :为什么Python多线程不能利用多核?GIL对I/O密集和CPU密集任务的影响?如何绕过GIL(多进程、C扩展)
python·面试
Raink老师6 小时前
【AI面试临阵磨枪-65】设计一个支持 10w 并发的 AI 聊天服务(流式、高可用、成本优化)
人工智能·面试·职场和发展
HelloRainy8 小时前
用 C++ 实现 shared_ptr 与 weak_ptr,线程安全是怎么解决的
面试
敲个大西瓜9 小时前
面经(1)
面试
雮尘9 小时前
100+ React 面试题 —— 来自前面试官的直接整理(2026)
前端·react.js·面试
Mahir0810 小时前
Spring MVC 深度解密:从 DispatcherServlet 到请求处理全流程
java·后端·spring·面试·mvc
一叶遮惊鸿10 小时前
Go 服务 Graph 热更新实践:用 atomic.Value 替代 sync.Once
面试