开放问答
cgroup v2 下 Prometheus 读 container_memory_working_set_bytes 虚高 800MB,怎么剔除 page cache
该问题的正文、回答与评论。
提问者 程景行-347 · 状态 open
SREK8scgroup-v2Prometheus监控踩坑
背景
公司 K8s 1.28 节点从 cgroup v1 升到 cgroup v2,cAdvisor 0.49 + Prometheus 2.50 + kube-state-metrics 2.10。升级完一周后,业务侧 Pod(Java 17,Xmx=2g,working_set 平时 ~1.8g)的 container_memory_working_set_bytes 稳定比升级前高约 800MB,且和 container_memory_usage_bytes 几乎贴在一起,差值从原来的 ~300MB 缩到 <20MB。
现象
- 业务侧 Grafana 面板显示内存"涨了 800MB",SRE 和研发反复排查一周;
kubectl top pod数字和 cAdvisor 一致偏高;kubectl describe pod里的 requests/limits 没动,但kube_pod_container_resource_requests_memory_bytes和实际 working_set 的比值肉眼可见恶化;- 业务侧 OOMKilled 事件没增加,Java 堆 dump 看堆内对象也没多,说明大概率不是业务真涨。
已尝试的排查
- 对比
container_memory_working_set_bytes与container_memory_usage_bytes:v1 下两者差 ~300MB(≈ page cache),v2 下差 <20MB; - 进容器
cat /sys/fs/cgroup/memory.stat:file项从 ~400MB 降到 ~50MB,anon项没变; - 怀疑是 v2 下 kernel 把部分 page cache 计入 working_set,但没找到官方文档明确说法;
- 试过
cAdvisor加--store_container_labels=true、把container_memory_rss换成container_memory_working_set_bytes之外的指标,没有更优解。
期望得到的答案形态
- cgroup v2 下
memory.working_set的口径和 v1 是否真的不一样?有没有 kernel 文档或 cgroup 仓库 issue 能引一下? - 如果确实是 page cache 被计入,Prometheus 侧有没有推荐的"剔除 page cache"的指标组合(比如 working_set - file,或者直接用
container_memory_rss之类的替代)? - 监控告警规则里,对 Java 这类长生命周期服务,应该用哪个指标做 OOM 预警更稳?
希望有踩过同样坑的同学给个可复现的 metric 表达式 + 告警规则片段,谢谢。
评论
暂无评论。