已采纳
回答正文
回复
讨论正文
该问题的正文、回答与讨论。
背景 我维护一个 10 节点(16C64G,Kubernetes 1.28.9 + containerd 1.7.13,内核 5.15.0-91,cgroup v2)的在线集群,跑 Java 17 / Spring Boot 3 的无状态订单服务 + 一个 log-agent sidecar。Pod 的 memory limit 给到 4Gi。
现象
Java 服务在高峰期偶发触发 Full GC,一次 GC 会在 200~400ms 窗口内瞬时多吃 1.2~1.6G RSS(堆外直接内存 + JIT 编译缓存 + Metaspace 碎片一起顶),叠加 sidecar 的 300~500MB 稳态,直接把 4Gi 的硬顶顶穿——Pod 被 OOMKilled,dmesg 里能看到 memory: oom-kill,cgroup 的 memory.events 里 oom_kill 计数加 1。
但把 limit 无脑提到 8Gi 又不甘心:配额表被顶到 8Gi 后 HPA 的副本数就降了,实际 95 分位也就 4.6G,等于用 70% 的配额换 5% 的可用性。
我在裸 cgroup v2 上手工验证过 memory.high 的效果:把 high 设到 4Gi、max 设到 5Gi,Java 那 300ms 尖峰被内核直接走 reclaim + PSI 回压,业务侧 p99 延迟从 40ms 抖到 90ms,但不 OOM——这正是我想要的"软限 + 硬限"两段式。
已尝试的排查与结果
resources.limits / requests 字段:只有 memory,映射到 memory.max,没有 memory.high 的原生字段。Kubelet 的 cgroup 生成逻辑(/sys/fs/cgroup/kubepods.slice/.../pod<uid>/):memory.max 是 kubelet 写的,memory.high 默认等于 memory.max(v2 语义),没有独立暴露。echo 4294967296 > /sys/fs/cgroup/.../memory.high:单次可行,但 Pod 重启 / 节点重启 / kubelet 重新 reconcile 时值会被重置回 memory.max,需要常驻守护。期望得到的答案形态
while true; do echo ...; sleep 5; done)守护,代价是 sidecar 资源与重启窗口;systemd override / cgroup 模板(对 kubepods.slice 做 drop-in 改 memory.high);-XX:MaxRAMPercentage + 堆外上限 + cgroup-aware GC(UseContainerSupport),把压力从"内核回压"转到"JVM 内回压"。memory.pressure)观测脚本,让我能区分"软限生效"和"硬 OOM"两种事件。(引用:社区里已有 sidecar 资源预算与 cgroup 观察的讨论,我的问题是把"预算"往"运行时软限"再推一步。)