K8s Pod启动失败的排查法

Kubernetes Pod启动失败的排查法

凌晨三点,服务上线后Pod死活起不来,企业微信的告警消息炸成烟花?作为经历过上百次生产事故的老司机,我总结出这套Pod启动失败排查大法,帮你从入门到精通。


一、Pod状态速查表(5秒定位问题)

Pod状态 问题方向 必杀命令
Pending 调度问题 kubectl describe node
ImagePullBackOff 镜像拉取失败 kubectl get events --sort-by=.metadata.creationTimestamp
CrashLoopBackOff 容器持续崩溃 kubectl logs --previous
Init:0/1 初始化容器卡死 kubectl logs -c init-container
CreateContainerError 容器创建失败 journalctl -u kubelet

二、九步排查法(生产环境验证)

第一步:看状态(5秒定位方向)

kubectl get pod -o wide -w  # -w参数实时监控状态变化

第二步:查事件(定位直接元凶)

kubectl describe pod web-78788f5dcd-2hqgw | grep -A 20 Events

Pod事件流示意图

第三步:挖日志(查看临终遗言)

# 关键!获取崩溃前的日志
kubectl logs --since=1h --previous --tail=500 web-78788f5dcd-2hqgw

第四步:验镜像(排除基础问题)

# 在任意节点手动拉取测试
docker pull registry.cn-hangzhou.aliyuncs.com/prod/web:v1.2.3

# 私有镜像认证测试
kubectl run test-$RANDOM --rm -it --image=私密镜像 --overrides='{"spec":{"imagePullSecrets":[{"name":"regcred"}]}}'

第五步:审配置(YAML常见陷阱)

# 典型错误示例
resources:
  limits:     # 只配置limit会导致request=limit!
    cpu: "1"  # 必须同时配置requests
  requests:
    memory: "512Mi"  # 单位错误!应该为512Mi

第六步:查节点(底层资源瓶颈)

# 快速定位节点问题
kubectl describe node | grep -i -e allocat -e capacity -e outof

第七步:调网络(CNI插件故障)

# 检查Calico等网络组件
kubectl get pods -n kube-system | grep -e calico -e flannel

# 容器内网络连通性测试
kubectl debug -it web-78788f5dcd-2hqgw --image=nicolaka/netshoot -- curl api-service:8080

第八步:验存储(PV/PVC连环坑)

# 查看存储声明状态
kubectl get pvc -n prod | grep -e Pending -e Lost

# 进入容器验证挂载
kubectl exec web-78788f5dcd-2hqgw -- ls /data

第九步:终极武器——临时调试容器

# 注入全功能调试容器(需要kubectl debug插件)
kubectl debug -it web-78788f5dcd-2hqgw --image=busybox --share-processes --copy-to=web-debug

三、六大经典翻车现场(附修复方案)

场景1:内存黑洞(OOMKilled隐身杀手)

# 查看历史OOM记录
kubectl get events --field-selector=reason=OOMKilled

修复方案:调整JVM堆参数或增加内存限制

场景2:僵尸节点(Node Not Ready)

# 快速隔离问题节点
kubectl cordon node-12
kubectl drain node-12 --ignore-daemonsets

场景3:Init容器死锁

# 错误配置:init容器无限循环
initContainers:
- name: wait-db
  image: busybox
  command: ['sh', '-c', 'while ! nc -z db 3306; do sleep 1; done'] # 缺少超时机制!

修复方案:增加超时检测

command: ['sh', '-c', 'timeout 60 sh -c "while ! nc -z db 3306; do sleep 2; done"']

场景4:时区不同步引发证书失效

# 检查容器时间
kubectl exec web-78788f5dcd-2hqgw -- date

# 同步容器时区方案
Dockerfile中添加:
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

场景5:探针配置错误导致连环重启

# 错误示例:检测间隔过短
livenessProbe:
  initialDelaySeconds: 3  # 应用启动需要30秒!
  periodSeconds: 2
  failureThreshold: 1

修复方案:根据应用启动时间调整参数

initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3

场景6:版本升级引发的API废弃

# 查看apiserver日志发现废弃API
journalctl -u kube-apiserver | grep deprecated

修复方案:使用kube-no-trouble检测废弃资源

kubectl-knt policy validate

四、生产环境必备工具箱

工具 用途 安装方式
k9s 可视化Pod管理 brew install k9s
stern 多Pod日志聚合 brew install stern
kube-bench CIS安全检测 kubectl插件
kube-eye 集群全景监控 helm安装
popeye 集群健康扫描 kubectl插件

实战组合拳

# 1. 用k9s快速定位异常Pod
# 2. 用stern聚合相关日志
stern "web-*" -n prod --since 10m
# 3. 用kube-debug注入诊断容器

五、防患于未然:上线前检查清单

  1. 容量预检
    kubectl resource-capacity --pods --util --sort cpu
    
  2. 配置校验
    kubectl apply --dry-run=server -f deploy.yaml
    
  3. 金丝雀发布
    kubectl rollout status deployment/web --timeout=300s
    
  4. 逃生方案
    # 快速回滚命令
    kubectl rollout undo deployment/web --to-revision=3
    

六、终极思考:如何构建自愈系统?

  1. HPA自动扩容:设置基于RPS的自动伸缩策略
  2. PDB熔断保护:保证至少30%的Pod可用
    apiVersion: policy/v1
    kind: PodDisruptionBudget
    metadata:
      name: web-pdb
    spec:
      minAvailable: 30%
      selector:
        matchLabels:
          app: web
    
  3. Chaos Engineering:定期进行故障演练

七、写在最后

Pod启动失败排查如同破案,需要:

  • 现场保护:第一时间保存kubectl get pod -o yaml > crash.yaml
  • 全链路思维:从YAML配置到内核参数都要怀疑
  • 防御性编程:在CI/CD中集成启动检测

记住:每一个启动失败的Pod,都是通往K8S大师之路的垫脚石!

posted on 2025-03-22 11:32  Leo-Yide  阅读(137)  评论(0)    收藏  举报