已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
背景
我维护一个 14 节点(16C64G,Kubernetes 1.28.9,containerd 1.7.13,cgroup v2,内核 5.15,100GB 系统盘,Calico 路由模式)的生产集群,跑 Java 17 + Go 的混合无状态服务。最近两个月,凌晨发布窗口偶尔会出现"节点抖动":不是单 Pod 挂,而是同一台节点上 5~15 个 Pod 同时出现症状——Java 侧 RT 抖 3~8 秒、Go 侧偶发 context deadline exceeded、Calico 日志里刷 FIB 更新、kubelet 偶尔打 Node has insufficient free memory,然后 1~3 分钟后自己恢复,业务侧看到的就是"发布窗口集体抖一下"。
现象(我实际抓到的)
dmesg 里有 memory: usage X, limit Y 但没有 OOM kill 记录;df -h / 显示系统盘 71%,df -i 显示 inode 62%,都还没到 kubelet 默认 85% 水位;node_memory_MemAvailable 最低跌到 3.8G(总量 64G)后 30 秒内回升;node_cpu_seconds_total 的 iowait 段在那 1~3 分钟里从 0 飙到 40%+;peer not responding 但 30 秒内自愈;我已经试过的排查
--image-gc-high-threshold-percent 到 85,没用,抖动照样发生;podAntiAffinity 把同一 Deployment 的新 Pod 打散到 3 台节点,抖动窗口从 1~3 分钟缩到 20~40 秒,但没消除;--eviction-hard 从默认收紧到 memory.available<2Gi,nodefs.available<10%,kubelet 主动驱逐了一次,业务恢复更快了,但根因没定位;crio inspect / ctr -n k8s.io c info 看容器内存,峰值和 limit 之间还有 30%+ 余量,堆内没打满(所以不是 OOMKilled 那条链路);sar -n DEV 1 和 iostat -x 1,能看到发布窗口磁盘 write 从 20MB/s 飙到 480MB/s,但我不确定这是"因"还是"果"。我想问的(希望得到的回答形态)
--eviction-* 日志?有没有一个可复用的"3 分钟 checklist"?pidstat + ss + iostat 抓现场)?kube_node_status_condition?有没有踩过"告警一片红但没人知道该先看哪个"的坑,怎么解的?欢迎不同规模的同事分享:你们 50 节点 / 500 节点 / 5 节点各是什么做法?我特别想听中小集群(<20 节点)怎么在没有专职 SRE 的情况下做这件事。