K8s故障排查的方法论
Kubernetes集群运维中,故障响应速度直接决定业务受损时长。SRE的核心能力不是记住所有命令,而是建立快速定位问题的思维框架:从控制面到数据面,从集群级到Pod级,逐层收窄故障范围。这篇实战指南覆盖生产环境最常见的三类故障——Pod CrashLoop、Service流量异常、节点NotReady,每类都给出完整的排查路径和处置命令。
Pod CrashLoopBackOff:从日志到根因定位
Pod反复崩溃重启是最高频的K8s故障。第一步看事件和上一次容器日志:
# 查看Pod事件
kubectl describe pod <pod-name> -n <namespace>
# 查看上一次容器日志(关键:--previous)
kubectl logs <pod-name> -n <namespace> --previous
# 如果容器内没有shell,用临时容器调试
kubectl debug <pod-name> -n <namespace> --image=busybox -it
CrashLoop的常见根因及对应解法:
1. OOMKilled:events中显示Last State: Terminated, Reason: OOMKilled。解法是调整resources.limits.memory,同时用kubectl top pod确认实际内存用量。注意Java应用JVM堆内存需低于container memory limit,建议JVM max heap = limit * 0.7。
2. Liveness Probe失败:容器启动慢但探针超时短。调大initialDelaySeconds和timeoutSeconds,或改用startupProbe做初始探测:
startupProbe:
httpGet:
path: /health/startup
port: 8080
failureThreshold: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /health/live
port: 8080
failureThreshold: 3
periodSeconds: 15
3. 配置/密钥缺失:应用启动依赖ConfigMap或Secret,但资源不存在或Key名称不匹配。describe pod的events中会显示configmap "xxx" not found或secret "xxx" not found。
Service流量不通:端点与网络策略诊断
Service配置正确但流量不通,排查链路如下:
# 1. 检查Endpoints是否关联到Pod
kubectl get endpoints <svc-name> -n <namespace>
# 2. Endpoints为空时,检查selector匹配
kubectl get pods -n <namespace> -l app=my-app --show-labels
# 3. Pod存在但Endpoints为空,检查readinessProbe
kubectl describe pod <pod-name> -n <namespace> | grep -A5 Readiness
# 4. Endpoints正常但流量不通,集群内测试连通性
kubectl run test --image=busybox -it --rm -- wget -qO- <svc-name>:<port>
# 5. 跨namespace访问需用FQDN
# <svc-name>.<namespace>.svc.cluster.local
NetworkPolicy限制是另一个常见原因。如果集群启用了CNI网络策略(Calico/Cilium),默认拒绝所有跨namespace流量。排查命令:
kubectl get networkpolicy -n <namespace>
kubectl describe networkpolicy <policy-name> -n <namespace>
临时验证时可删除NetworkPolicy观察流量是否恢复,确认后补上正确的ingress规则。
节点NotReady:从kubelet到基础设施逐层排查
节点变为NotReady状态意味着kubelet停止向API Server上报节点状态,或上报的心跳中包含异常条件。
# 查看节点条件和事件
kubectl describe node <node-name>
# 关键字段:Conditions中的Ready、MemoryPressure、DiskPressure、PIDPressure
# 事件中查看kubelet相关报错
排查优先级:
1. SSH到节点检查kubelet状态
systemctl status kubelet
journalctl -u kubelet --since "10 minutes ago"
2. 磁盘压力:DiskPressure为True时,kubelet拒绝新Pod调度并触发镜像清理。df -h检查/var/lib/kubelet和/var/lib/containerd使用率,清理废弃镜像:crictl rmi --prune。
3. 内存压力:MemoryPressure为True时,kubelet驱逐BestEffort和Burstable Pod。free -h确认内存使用,kubectl describe node查看当前Pod内存request/limit总量是否超出节点容量。
4. PLEG问题:kubelet日志中出现PLEG is not healthy,通常是容器运行时(containerd)卡死。重启containerd:systemctl restart containerd。频繁出现需检查容器运行时版本和内核版本兼容性。
故障复盘与SLO对齐
每次P0/P1故障解决后,必须完成复盘文档:故障时间线、根因分析(5 Whys)、影响面评估(受影响用户数、业务指标偏离)、修复措施和防护措施。将复盘结论转化为监控告警规则和混沌工程测试用例,确保同类故障可被早期发现和快速自愈。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-ji-qun-gu-zhang-ying-ji-xiang-ying-cong/