
凌晨三点,刺耳的手机警报把你从梦中拽醒——“生产集群节点大面积NotReady”。你睡眼惺忪地爬起来,面对着一片飘红的监控大盘,kubectl命令像石沉大海,业务流量开始断崖式下跌。这种场景,是不是似曾相识?
Kubernetes集群的崩溃,往往不是单一故障点引发的“雪崩”,而是多个系统性问题积累到临界点的“总爆发”。今天,我就结合多次“救火”经历,为你梳理出导致集群“暴毙”的几个最核心、也最容易被忽略的深层原因。下次再遇到,你就能直奔主题,而不是在黑暗中盲目试错。
问题现象:kubectl命令超时或无响应,API Server间歇性报错,节点状态更新延迟,甚至整个集群控制平面“僵死”。
根本原因:etcd作为Kubernetes的“分布式数据库”,存储着所有集群状态。当它出问题时,整个集群的“大脑”就宕机了。常见死因包括:
quota-backend-bytes在大型集群中很快耗尽,etcd进入只读模式,集群变为“植物人”。 etcd官方文档max-request-bytes(1.5MB),导致请求被拒绝。排查与止血:
# 1. 检查etcd成员健康状态(需在etcd节点执行,并指定证书)
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
--key=/etc/kubernetes/pki/etcd/healthcheck-client.key \
endpoint health
# 2. 检查etcd存储空间使用情况
etcdctl --write-out=table endpoint status
# 3. 查看etcd日志(通常与kubelet日志一起)
journalctl -u etcd -f关键线索:日志中出现“database space exceeded”、“raft: stopped heartbeat”、“request too large”等字样。
根治建议:
quota-backend-bytes(如8GB),设置auto-compaction-retention(如8小时),提升max-request-bytes(如10MB)。etcdctl snapshot save定期备份,并演练恢复流程。问题现象:节点状态突然变为NotReady,Pod间网络不通,跨节点服务调用失败,但节点本身SSH可连,kubelet进程也在运行。
根本原因:Calico、Flannel、Cilium等CNI插件是集群的“神经系统”。其故障会导致Pod网络平面瘫痪。常见原因:
DaemonSet Pod(如calico-node)因资源不足、镜像拉取失败或配置错误而CrashLoopBackOff。IPPool)耗尽,新Pod无法获得IP。iptables或ipvs规则被异常程序修改,或netfilter连接跟踪表nf_conntrack满,导致新连接无法建立。排查与止血:
# 1. 检查故障节点上的CNI插件Pod状态
kubectl get pods -n kube-system -o wide | grep <cni-component> | grep <node-name>
# 2. 查看CNI插件Pod的日志
kubectl logs -n kube-system <cni-pod-name> --tail=50
# 3. 检查节点网络配置(以Calico为例,检查是否生成了网络接口和路由)
ssh <node-ip> ip addr show | grep cali
ssh <node-ip> route -n
# 4. 检查系统连接跟踪表状态
ssh <node-ip> sysctl net.netfilter.nf_conntrack_count
ssh <node-ip> sysctl net.netfilter.nf_conntrack_max关键线索:CNI Pod状态异常、日志报错、节点上缺少cali*虚拟网卡或路由。
根治建议:
resources.requests/limits,防止因资源竞争被驱逐。nf_conntrack_max、net.ipv4.ip_forward=1等参数。问题现象:集群响应变慢,调度延迟增加,部分节点NotReady,系统组件(如kube-dns)频繁重启,但监控显示整体CPU/内存使用率并不高。
根本原因:这是一种更隐蔽的问题。不是资源绝对不足,而是关键的系统组件(控制平面)与业务容器之间,或者不同系统组件之间,发生了资源竞争,导致“系统饥饿”。
LIST/WATCH请求(如来自众多Pod的日志收集组件)打满默认的并发连接数(--max-requests-inflight=400),阻塞了kubelet的心跳上报和调度器请求,引发连锁反应。PID、文件描述符fd、内存页等底层资源被某个异常Pod耗尽,导致节点上所有容器(包括kubelet、containerd)不稳定。kubelet可能存在内存泄漏,长时间运行后OOM,导致节点失联。排查与止血:
# 1. 检查API Server监控指标(如有Prometheus)
# 关注:request_rate, request_duration_seconds, inflight_requests
# 2. 检查节点资源(SSH到节点)
ssh <node-ip> top# 看整体和kubelet/containerd进程资源
ssh <node-ip> cat /proc/sys/kernel/pid_max
ssh <node-ip> df -h /var/lib/kubelet # 检查kubelet数据盘
# 3. 查看kubelet日志
journalctl -u kubelet -f--tail=100关键线索:API Server延迟高、kubelet日志出现“PLEG is not healthy”、节点/var/log/messages中有oom-killer或task fork failed等日志。
根治建议:
max-requests-inflight,max-mutating-requests-inflight),为系统组件设置高优先级。LimitRange和ResourceQuota。kubelet、containerd等基础组件为稳定版本,定期重启以释放潜在泄漏。集群崩溃后的排查固然重要,但最高明的运维是让故障不发生。基于以上分析,我为你总结了一份“集群健壮性清单”:
记住,Kubernetes集群的稳定性,不是一个开关,而是一个需要持续投入和精心维护的系统工程。从被动响应到主动防御,是你从“运维工程师”迈向“SRE”的关键一步。
“经一事,长一智”。希望这些用深夜和焦虑换来的经验,能帮你照亮下一次的排查之路。
“无他,惟手熟尔”!有需要的用起来!
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!
本文分享自 Nicholas与Pypi 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!