已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
背景
我在一个 12 节点(16C64G,K8s 1.28.9,containerd 1.7.13,cgroup v2,内核 5.15.0-112,Calico 路由模式)的生产集群里混跑 Java 17 微服务(约 18 个 Pod,request 合计 ~28G,limit 合计 ~40G)和一个 Flink 作业(2 个 TaskManager,各 8G limit)。节点上 kubelet 目前只设了 kube-reserved=memory=2Gi,system-reserved 没显式配,eviction-hard 用的是默认 memory.available<100Mi。
现象
kubectl describe node 里 memory allocatable 看着还剩 10Gi+,Burstable Pod 也都没超 limit,但高峰期节点仍偶发把 1~2 个内存最"松"的 Burstable Pod 驱逐掉(事件里 reason=Evicted,message 是 memory.available 低于阈值)。memory.available 在驱逐前一瞬的 node-exporter 采样点其实还有 200Mi 左右,但 100Mi 阈值被瞬时击穿。
补充观测(后来加的)
slabtop 里 dentry + inode_cache 合计 ~2.8G,kmalloc-128 系列 ~1.4G,SReclaimable 看着有 4G+,但 SUnreclaim 也漂到了 1.2G(业务稳态时 800M)——怀疑驱逐窗口内 slab 分配速率超过了回收速率;memory.pressure some 10s 在驱逐前 30s 就 avg10 > 0.3,但 full 10s 仍为 0——说明是 some 阶段拖久了,不是 full 阶段;vmtouch 看业务 Pod 的 page cache 命中率在驱逐前 1min 从 92% 跌到 71%,page fault 率上升 3 倍。已尝试的排查
kube-reserved 到 4Gi,重启 kubelet 后 allocatable 缩小,但驱逐频率没明显下降;eviction-hard 改成 memory.available<250Mi,驱逐更少但节点开始频繁触发 OOM,宿主机侧 dmesg 出现 oom-killer(被杀的多是 Flink TaskManager 的 DirectMemory 段);kubectl describe node 看 Allocatable 和 Capacity 差值,确认 reserved 确实生效了,但没找到 system-reserved 到底占了多少;echo 1 > /proc/sys/vm/drop_caches 手动回收,驱逐立刻停止——但这是验证手段不是方案,生产上没这么干。期望得到的答案形态
memory.available 这个指标本身是否还可靠,有没有更贴近真实可回收量的判据(PSI some、/proc/meminfo 的 MemAvailable 与 Slab(SReclaimable) 的组合?还是 cgroup v2 的 memory.pressure + memory.current 联合判据?);memory.max + memory.high 限制),能在我这个 64G 节点上把驱逐边界标定出来,再反推 reserved 该设多大——最好是带具体命令和参数的;memory.current?我看到过 memory.current 和 RSS + DirectMemory 差 800M 的 case,是不是 page cache + slab 都被算进去了?欢迎给具体数字和命令,不要"建议监控"这种空话。