首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >K8s集群又崩了,这次我终于搞清楚了原因

K8s集群又崩了,这次我终于搞清楚了原因

作者头像
用户11081884
发布2026-07-20 20:28:20
发布2026-07-20 20:28:20
180
举报

凌晨三点,刺耳的手机警报把你从梦中拽醒——“生产集群节点大面积NotReady”。你睡眼惺忪地爬起来,面对着一片飘红的监控大盘,kubectl命令像石沉大海,业务流量开始断崖式下跌。这种场景,是不是似曾相识?

Kubernetes集群的崩溃,往往不是单一故障点引发的“雪崩”,而是多个系统性问题积累到临界点的“总爆发”。今天,我就结合多次“救火”经历,为你梳理出导致集群“暴毙”的几个最核心、也最容易被忽略的深层原因。下次再遇到,你就能直奔主题,而不是在黑暗中盲目试错。


一、etcd:那个沉默的“心脏骤停者”

问题现象kubectl命令超时或无响应,API Server间歇性报错,节点状态更新延迟,甚至整个集群控制平面“僵死”。

根本原因:etcd作为Kubernetes的“分布式数据库”,存储着所有集群状态。当它出问题时,整个集群的“大脑”就宕机了。常见死因包括:

  1. 磁盘写满:默认2GB的quota-backend-bytes在大型集群中很快耗尽,etcd进入只读模式,集群变为“植物人”。 etcd官方文档
  2. 性能瓶颈:低配硬件(机械硬盘、低内存)、未开启压缩导致历史版本堆积,使读写延迟飙升。
  3. 网络分区或脑裂:etcd集群节点间通信中断,无法达成共识,导致数据不一致。
  4. 大对象冲击:单个巨大的ConfigMap或Secret写入,超过默认的max-request-bytes(1.5MB),导致请求被拒绝。

排查与止血

代码语言:javascript
复制
# 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)。
  • 硬件隔离:为etcd配备SSD、独立CPU和充足内存,绝不与计算节点混部。
  • 定期备份与演练:使用etcdctl snapshot save定期备份,并演练恢复流程。

二、网络插件(CNI):那根被踩断的“大动脉”

问题现象:节点状态突然变为NotReady,Pod间网络不通,跨节点服务调用失败,但节点本身SSH可连,kubelet进程也在运行。

根本原因:Calico、Flannel、Cilium等CNI插件是集群的“神经系统”。其故障会导致Pod网络平面瘫痪。常见原因:

  1. DaemonSet Pod崩溃:CNI插件的DaemonSet Pod(如calico-node)因资源不足、镜像拉取失败或配置错误而CrashLoopBackOff
  2. IP地址池耗尽:Pod数量增长导致分配给节点的IP子网(如Calico的IPPool)耗尽,新Pod无法获得IP。
  3. 底层网络规则混乱iptablesipvs规则被异常程序修改,或netfilter连接跟踪表nf_conntrack满,导致新连接无法建立。
  4. 节点内核参数不兼容:某些CNI插件(如Calico的IPIP模式)需要特定的内核模块或参数支持。

排查与止血

代码语言:javascript
复制
# 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*虚拟网卡或路由。

根治建议

  • 资源保障:为CNI DaemonSet设置合理的resources.requests/limits,防止因资源竞争被驱逐。
  • 规划IP地址池:根据集群规模预估Pod数量,预留足够的IP地址空间。
  • 优化内核参数:调整nf_conntrack_maxnet.ipv4.ip_forward=1等参数。
  • 选择稳定CNI:生产环境选择经过大规模验证的CNI插件,并关注其版本兼容性。

三、资源耗尽与组件竞争:无声的“内耗战争”

问题现象:集群响应变慢,调度延迟增加,部分节点NotReady,系统组件(如kube-dns)频繁重启,但监控显示整体CPU/内存使用率并不高。

根本原因:这是一种更隐蔽的问题。不是资源绝对不足,而是关键的系统组件(控制平面)与业务容器之间,或者不同系统组件之间,发生了资源竞争,导致“系统饥饿”。

  1. API Server过载:大量LIST/WATCH请求(如来自众多Pod的日志收集组件)打满默认的并发连接数(--max-requests-inflight=400),阻塞了kubelet的心跳上报和调度器请求,引发连锁反应。
  2. 节点内核资源耗尽:进程号PID、文件描述符fd、内存页等底层资源被某个异常Pod耗尽,导致节点上所有容器(包括kubeletcontainerd)不稳定。
  3. kubelet 内存泄漏:旧版本kubelet可能存在内存泄漏,长时间运行后OOM,导致节点失联。

排查与止血

代码语言:javascript
复制
# 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-killertask fork failed等日志。

根治建议

  • 调优控制平面:如上一篇调优文章所述,提升API Server的并发参数(max-requests-inflightmax-mutating-requests-inflight),为系统组件设置高优先级。
  • 资源隔离与限制:为所有Pod(包括系统组件)设置合理的资源限制,避免单个Pod吞噬所有资源。使用LimitRangeResourceQuota
  • 升级与维护:保持kubeletcontainerd等基础组件为稳定版本,定期重启以释放潜在泄漏。

总结

集群崩溃后的排查固然重要,但最高明的运维是让故障不发生。基于以上分析,我为你总结了一份“集群健壮性清单”:

  1. 监控先行:不仅要监控CPU/内存,更要监控etcd性能指标(存储大小、读写延迟)、API Server并发与延迟CNI插件Pod状态节点内核资源(PID、fd、inotify)。
  2. 容量规划:定期评估集群容量,包括Pod数量、存储空间、IP地址池,提前扩容,避免触及极限。
  3. 变更管控:任何对集群的修改(升级、配置变更、应用部署)都要有回滚计划,并在非高峰期进行。
  4. 混沌工程:在测试集群定期模拟节点故障、网络分区、etcd压力等场景,验证系统的容错和恢复能力。
  5. 知识沉淀:将每次故障的排查过程、根因分析和解决方案记录成案,形成团队的“故障知识库”。

记住,Kubernetes集群的稳定性,不是一个开关,而是一个需要持续投入和精心维护的系统工程。从被动响应到主动防御,是你从“运维工程师”迈向“SRE”的关键一步。

“经一事,长一智”。希望这些用深夜和焦虑换来的经验,能帮你照亮下一次的排查之路。

“无他,惟手熟尔”!有需要的用起来!

如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Nicholas与Pypi 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、etcd:那个沉默的“心脏骤停者”
  • 二、网络插件(CNI):那根被踩断的“大动脉”
  • 三、资源耗尽与组件竞争:无声的“内耗战争”
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档