凌晨三点的K8s集群告警:从混沌到秩序的故障排查全流程

一、紧急响应阶段:快速定位异常Pod

在集群告警触发后的黄金10分钟内,需通过结构化命令快速锁定问题Pod。以下命令组合可覆盖80%的常见故障场景:

1. 状态扫描与优先级排序

  1. # 筛选非运行状态Pod并按重启次数降序排列
  2. kubectl get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded \
  3. --sort-by='.metadata.creationTimestamp' | tail -20

该命令可快速识别持续重启的Pod,重点关注CrashLoopBackOffError状态的容器。建议将输出结果按重启次数和创建时间双重排序,优先处理新出现的异常。

2. 事件链分析

  1. # 获取Pod的完整事件时间线(重点查看FailedScheduling、Killing、BackOff等事件)
  2. kubectl describe pod <pod-name> -n <namespace> | grep -A 30 "Events:"

事件日志中常包含关键线索:

  • FailedScheduling:节点资源不足或污点配置问题
  • Killing:OOM Killer或健康检查失败
  • BackOff:容器持续崩溃导致的重试延迟

3. 资源压力诊断

  1. # 节点资源分配热力图
  2. kubectl top nodes --no-headers | awk '{print $1,$2,$3,$4,$5/1024"Gi"}'
  3. # 容器资源使用详情(需开启metrics-server)
  4. kubectl top pod <pod-name> -n <namespace> --containers --sort-by=cpu

当发现某个节点的Allocated resources超过85%阈值时,需立即检查是否存在资源配额设置不合理或Pod调度不均衡问题。

二、深度排查阶段:穿透表象找根因

在初步定位异常Pod后,需通过多维度数据交叉验证确定根本原因:

1. 容器生命周期分析

  1. # 获取容器退出状态码(非零值表示异常终止)
  2. kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[*].lastState.terminated.exitCode}'
  3. # 查看崩溃前最后200行日志(--tail参数控制行数)
  4. kubectl logs <pod-name> -n <namespace> --previous --tail=200

常见退出码解析:

  • 137:OOM Killer触发(需结合dmesg日志确认)
  • 139:Segmentation fault(应用代码缺陷)
  • 255:应用内部错误(检查应用日志)

2. 网络问题定位
对于出现NetworkPluginNotReadyContainerCreating卡住的Pod:

  1. # 检查CNI插件状态(以某开源网络组件为例)
  2. kubectl get pods -n kube-system | grep cni-plugin
  3. kubectl exec -n kube-system <cni-pod-name> -- cat /host/etc/cni/net.d/current.conf
  4. # 验证iptables规则规模(超过5万条需优化)
  5. iptables-save | grep -c "^-A"

建议定期清理无效的kube-proxy规则,避免规则膨胀导致网络性能下降。

3. 存储问题诊断
当Pod卡在ContainerCreating状态且事件显示AttachVolume.Attach failed时:

  1. # 检查存储卷状态
  2. kubectl get pv,pvc -n <namespace>
  3. kubectl describe pv <pv-name> | grep -A 10 "Claim:"
  4. # 验证存储后端连接性(以NFS为例)
  5. showmount -e <nfs-server-ip>
  6. mount -t nfs <nfs-server-ip>:/<path> /mnt/test

三、典型案例解析:Liveness探针配置陷阱

某生产环境曾出现大规模Pod重启事件,最终定位到Deployment配置中的探针参数不合理:

事故配置片段

  1. livenessProbe:
  2. httpGet:
  3. path: /healthz
  4. port: 8080
  5. initialDelaySeconds: 10 # 应用启动需要30s加载缓存
  6. periodSeconds: 5 # 每5秒探测一次
  7. timeoutSeconds: 2 # 2秒无响应即判定失败
  8. failureThreshold: 2 # 连续2次失败就重启

问题复盘

  1. 启动延迟不足:应用实际需要30秒完成初始化,但initialDelaySeconds仅设置10秒,导致探针在应用就绪前就开始检查
  2. 探测频率过高periodSeconds:5配合timeoutSeconds:2,使应用在短暂GC停顿时就被误杀
  3. 容错机制缺失failureThreshold:2意味着任何两次网络抖动都会触发重启

优化建议

  1. livenessProbe:
  2. httpGet:
  3. path: /healthz
  4. port: 8080
  5. initialDelaySeconds: 45 # 增加启动缓冲期
  6. periodSeconds: 30 # 降低探测频率
  7. timeoutSeconds: 5 # 延长响应等待
  8. failureThreshold: 3 # 增加容错次数

四、预防性优化措施

为避免重复发生同类故障,建议建立以下机制:

1. 配置静态检查

  1. # 使用kubeval验证YAML语法
  2. kubeval --strict deployment.yaml
  3. # 自定义探针参数检查脚本
  4. #!/bin/bash
  5. MIN_INITIAL_DELAY=30
  6. MIN_PERIOD=10
  7. cat deployment.yaml | yq '.spec.template.spec.containers[].livenessProbe' | \
  8. while read probe; do
  9. delay=$(echo $probe | yq '.initialDelaySeconds')
  10. period=$(echo $probe | yq '.periodSeconds')
  11. if [ $delay -lt $MIN_INITIAL_DELAY ] || [ $period -lt $MIN_PERIOD ]; then
  12. echo "Warning: Unhealthy probe configuration detected"
  13. fi
  14. done

2. 混沌工程实践
在测试环境注入以下故障场景:

  • 模拟应用启动延迟(通过sleep容器前置)
  • 网络延迟注入(使用tc命令)
  • 资源压力测试(限制Pod的CPU/内存)

3. 监控告警增强
配置以下关键指标的告警规则:

  • 容器重启率(>1次/小时触发告警)
  • 探针失败率(连续3次失败触发告警)
  • 节点资源使用率(>80%预警,>90%告警)

结语

Kubernetes集群的稳定性维护需要建立”预防-检测-响应-恢复”的完整闭环。通过标准化排查流程、自动化检查工具和混沌工程实践,可将夜间故障处理时间从小时级压缩至分钟级。建议运维团队定期复盘历史故障,将典型案例转化为自动化检查规则,持续迭代优化运维体系。