开放问答
K8s 节点抖动了但告警一片红:内存/CPU/磁盘/网络四类压力到底谁先到,怎么从现象反推根因?
该问题的正文、回答与评论。
提问者 沈亦舟-266 · 状态 open
Kubernetes节点分诊资源压力SRE云原生发布窗口
背景
我维护一个 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_exporter 上
node_memory_MemAvailable最低跌到 3.8G(总量 64G)后 30 秒内回升; node_cpu_seconds_total的 iowait 段在那 1~3 分钟里从 0 飙到 40%+;- Calico 里偶发
peer not responding但 30 秒内自愈; - 发布窗口是"滚动 50% 并发 + 镜像 2.2GB",我怀疑拉取带宽和临时内存叠加,但抓不到直接证据。
我已经试过的排查
- 调大
--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,但我不确定这是"因"还是"果"。
我想问的(希望得到的回答形态)
- 你们线上节点级压力分诊的实际顺序是什么?是先看 node_exporter 四件套(mem/cpu/net/disk)的哪一条,还是直接看 kubelet 的
--eviction-*日志?有没有一个可复用的"3 分钟 checklist"? - 发布窗口这种"多压力叠加"场景,怎么把带宽、临时内存、磁盘 write、网络抖动这四条线在时间轴上对齐?你们用什么工具链(Prometheus + Grafana?还是直接
pidstat+ss+iostat抓现场)? - 你们怎么给节点建"压力分级"告警?是 P0(驱逐发生)/ P1(水位 80%)/ P2(趋势 30min 上涨)这种梯度,还是直接看
kube_node_status_condition?有没有踩过"告警一片红但没人知道该先看哪个"的坑,怎么解的? - 开放一点的问题:cgroup v2 下,节点级内存和 Pod 级内存的"余量"是不是应该解耦来看? 我现在的直觉是"节点余量"和"Pod 余量"是两个独立预算,但没人跟我确认过——你们线上怎么算这笔账的?
欢迎不同规模的同事分享:你们 50 节点 / 500 节点 / 5 节点各是什么做法?我特别想听中小集群(<20 节点)怎么在没有专职 SRE 的情况下做这件事。
评论
暂无评论。