兄弟们,今天复盘一个K8s生产集群的严重故障。
故障现象非常典型且致命:集群多个节点状态突变为 NotReady,核心业务Pod大面积陷入 CrashLoopBackOff,Service层直接爆出大量502错误,整个集群处于半瘫痪状态,业务完全不可用。
面对这种集群级故障,最考验SRE和运维的心理素质。今天就把这次真实故障的排查和处置过程拆解一下,全是现场实操的血泪经验,希望能帮大家在遇到类似情况时,能稳住阵脚,快速恢复。
🚨 故障初期“四不要”红线(保命必看):
一、 完整应急处置SOP:先稳住,再抢救
遇到大故障,千万别一上来就想着“怎么把代码修好”或者“怎么把节点重启”,口诀是:先稳住集群,再抢救业务。
完整流程如下:
二、 控制面与节点排查:摸清底牌
节点 NotReady 是表象,背后可能是kubelet挂了、网络断了或者资源耗尽了。
1. 快速查看集群与节点状态
# 查看节点状态,找出NotReady的节点
kubectl get nodes -o wide
# 查看异常节点的详细事件(重点看 Conditions 和 Events)
kubectl describe node <node-name>
# 查看控制面组件状态(apiserver, scheduler, controller-manager)
kubectl get pods -n kube-system -o wide
2. 节点层深度排查(上SSH)
登录到 NotReady 的节点,按以下顺序排查:
# 1. 查kubelet状态和日志(最常见的背锅侠)
systemctl status kubelet
journalctl -u kubelet -f –since "1 hour ago" | grep -iE "error|fail|panic"
# 2. 查容器运行时状态(containerd/docker)
systemctl status containerd
crictl info
crictl ps -a | grep -v Running
# 3. 查节点资源占用(重点看磁盘和inode!)
top -c
df -h # 看磁盘空间,特别是 /var/lib/kubelet 和 /var/lib/containerd
df -i # 看inode使用率,inode耗尽也会导致kubelet停摆!
# 4. etcd 健康检查
# 如果是kubeadm部署的,可以直接用kubectl查
kubectl get –raw /healthz/etcd
# 或者进etcd容器查
kubectl exec -it etcd-master -n kube-system — etcdctl endpoint health –endpoints=https://127.0.0.1:2379
💡 常见节点故障模式:
- 磁盘满/Inode满:容器日志没轮转,或者某个业务疯狂写临时文件。
- OOM:节点物理内存耗尽,触发内核OOM Killer,把kubelet或容器运行时杀了。
- 内核Panic/死机:硬件问题或内核Bug,只能硬重启。
- 证书过期:经典老番,1年期满,apiserver或kubelet证书过期,节点直接失联。
三、 Pod与工作负载排查:定位业务死因
节点没问题,但Pod就是起不来,或者疯狂重启。
1. 快速定位异常Pod
# 按命名空间列出非Running状态的Pod
kubectl get pods -n <namespace> | grep -v Running
# 查看Pod详细事件和退出码(重点看 Last State 和 Events)
kubectl describe pod <pod-name> -n <namespace>
# 查看容器日志(注意:一定要加 –previous 看上一次崩溃前的日志!)
kubectl logs <pod-name> -n <namespace> –previous –tail=100
# 查看Deployment滚动状态,看是不是卡住了
kubectl rollout status deployment/<deployment-name> -n <namespace>
# 按时间排序查看命名空间Events,找最新报错
kubectl get events -n <namespace> –sort-by='.lastTimestamp' | tail -n 20
2. 常见异常状态的真实含义
别只看字面意思,要懂背后的逻辑:
- CrashLoopBackOff:容器启动后立刻退出,或者探针一直失败。K8s在尝试重启它,但间隔时间越来越长。真相:通常是代码有Bug启动报错、配置文件挂载错了、或者数据库连不上。
- OOMKilled:容器内存超限被系统Kill。真相:不一定是代码内存泄漏!很可能是 resources.limits.memory 设得太抠,或者Java应用没配好JVM参数(没识别到容器内存限制)。
- ImagePullBackOff / ErrImagePull:镜像拉不到。真相:镜像Tag写错了、Harbor密码变了、或者节点到镜像仓库的网络不通(DNS解析失败)。
- ContainerCreating:一直卡在创建中。真相:通常是存储卷(PV/PVC)挂载失败,或者CNI网络插件分配IP失败。
四、 网络与存储排查:打通任督二脉
Pod起来了,但是互相不通,或者域名解析不了,这时候就要查网络了。
1. 网络排查三连
# 1. 查 Service 和 Endpoints(看后端有没有挂上Pod)
kubectl get svc <svc-name> -n <namespace>
kubectl get ep <svc-name> -n <namespace> # 如果ENDPOINTS为空,说明Pod探针失败或标签不匹配
# 2. 测试 CoreDNS 解析
kubectl exec -it <pod-name> -n <namespace> — nslookup kubernetes.default
kubectl exec -it <pod-name> -n <namespace> — nslookup <your-service-name>
# 3. 查 NetworkPolicy(是不是误拦截了)
kubectl get networkpolicy -A
# 4. 查 kube-proxy 和 CNI 插件日志
kubectl logs <kube-proxy-pod> -n kube-system –tail=50
kubectl logs <calico-node-pod> -n kube-system –tail=50 # 以Calico为例
2. 存储排查
# 查看 PVC 状态,如果是 Pending 说明存储供应失败
kubectl get pvc -A
# 查看 PV 详细事件
kubectl describe pvc <pvc-name> -n <namespace>
💡 集群网络故障典型表现:
- Pod能起,但跨节点不通:CNI插件(如Calico/Flannel)挂了,或者底层物理网络(VXLAN/BGP)路由问题。
- 域名解析失败:CoreDNS Pod异常,或者节点上的 resolv.conf 被篡改。
- Service访问不通:kube-proxy没正常下发iptables/IPVS规则,或者后端Pod探针全挂导致Endpoints为空。
🛠️ 终极杀器:如果以上命令看不出问题,直接上 tcpdump 抓包,或者在容器里用 curl -v 和 telnet 测端口,能解决99%的网络玄学问题。
五、 业务恢复:分级处理,止血优先
故障排查清楚了,接下来是恢复业务。记住:能摘除故障节点就摘除,别死磕修复,业务优先!
1. 可快速恢复的场景
- 代码/配置变更引起的雪崩:直接回滚。kubectl rollout undo deployment/<name> -n <namespace>
- 单节点故障(如硬件损坏、内核Panic):直接隔离并驱逐Pod,让调度器把它调度到健康节点。# 标记节点不可调度
kubectl cordon <node-name>
# 驱逐节点上的Pod(注意加 –ignore-daemonsets 和 –delete-emptydir-data)
kubectl drain <node-name> –ignore-daemonsets –delete-emptydir-data –force - 单点资源耗尽:临时扩容节点,或者调整HPA。
2. 需谨慎操作的场景
- etcd 数据损坏/丢失:
- 前提:必须有最近的etcd备份!
- 风险:恢复etcd会丢失备份点之后所有的集群状态变更(比如你刚建的Pod、刚改的配置全没了)。
- 操作:停掉apiserver,使用 etcdctl snapshot restore 恢复数据,重启etcd和apiserver。不到万不得已,不要走这一步。
- 节点底层OS/运行时彻底崩溃:不要尝试去重启kubelet或containerd,直接走上面的 cordon + drain 流程,然后让底层IaaS团队去重装系统或重建节点。
六、 根因分析:找背锅侠
业务恢复了,复盘不能少。常见故障诱因及排查路径:
怎么找根因?
不要拍脑袋!顺着 kubectl get events 的时间线,结合 Grafana 监控大盘的指标突变,再辅以 apiserver 审计日志,形成证据链。
七、 事后加固:擦屁股的艺术
故障处理完,如果不做加固,下次还会翻车。
八、 总结:高频踩坑血泪教训
最后,总结几个我见过无数人踩过的坑,大家引以为戒:
K8s 运维就是一场修行,故障不可怕,可怕的是没有预案和复盘。希望这篇实战复盘能帮大家在遇到集群级故障时,做到心中有数,手中有剑。
如果你觉得这篇文章对你有帮助,或者你也在生产环境踩过类似的坑,欢迎在评论区交流你的“血泪史”!
觉得有用,别忘了点个赞、收藏一下,以备不时之需(毕竟排查故障时,你可能只想直接复制命令)!我们下期见!
网硕互联帮助中心



评论前必须登录!
注册