【背景】 做了 5 年云原生运维,我们集群 K8s 1.28 + containerd,300+ 工作负载,一半是 Java 服务(JDK17,G1),一半 Go。最近做容量成本盘点时发现一个尴尬的事实:全集群只有不到 30% 的 Pod 是 Guaranteed(requests = limits),其余要么 limits 完全没设(BestEffort),要么 requests 设得极低、limits 拉得很高(Burstable 赌余量)。而恰恰是这批「赌余量」的 Pod,贡献了 70% 以上的节点级驱逐事件和 OOMKill。
但反方论据也很真实:全 Guaranteed 之后,节点实际水位长期只有 40%~50%,单位算力成本上去了 25%,财务那边不乐意——「你们为了稳定性把一半的钱烧掉了」。
【常见的三种做法】
- 全 Guaranteed:requests = limits,节点水位低但可预测,驱逐基本消失,成本最高;
- 低 request 高 limit:requests 只给 2C/4G 这种「保命值」,limits 给 8C/16G,赌节点余量,成本低但驱逐、throttling 频繁,P99 抖动很难归因;
- 不设 limits(或只设 memory limit 不设 CPU limit):CPU 弹性最好,但 memory 无上限时 OOM 会直接炸节点邻居。
【我的倾向与理由】 我倾向「memory 必须 Guaranteed、CPU 可以 Burstable」的混合策略,理由:
- memory 是「硬资源」:超了就是 OOMKill,且 K8s 的 OOM 是 cgroup 级联的,一个 Pod 能拖死同节点邻居,必须 requests = limits;
- CPU 是「软资源」:超了只是 throttling / 被抢,不会死,Burstable 的弹性收益是真实的(Go 服务突发流量下 CPU 峰值通常是均值的 3~5 倍);
- 成本上,memory 占节点成本的 60%+,CPU 只占 30%,把「硬资源」锁死、「软资源」放开,是性价比最高的切法。
- 但前提是:CPU throttling 必须进监控(container_cpu_cfs_throttled_periods_total / container_cpu_cfs_periods_total,阈值我一般设 5% 持续 10min 告警),否则 Burstable 就变成「慢性 P99 抖动」。
【想听大家在什么场景下怎么选】
- 你们线上是哪种策略? Guaranteed 占比大概多少?驱逐事件主要出在 memory 还是 CPU?
- Java 服务(G1 + ZGC)和 Go 服务,你们的 requests/limits 定法有区别吗?G1 的堆外内存怎么算进 limits?
- 「CPU 可以 Burstable」这条,你们有没有踩过「节点级 CPU 争抢导致 P99 抖动、但单 Pod 监控完全正常」的坑?怎么观测的?
- 财务压成本时,你们怎么把「稳定性溢价」量化成数字去说服?有没有人做过「Guaranteed vs Burstable 的故障成本 vs 资源成本」对比?
- 有没有人试过用 VPA 自动调 requests/limits?线上敢全量开吗,还是只当「参考值」用?
我先把我的数据放这儿:全 Guaranteed 后,节点 memory 平均水位从 78% 降到 52%(因为之前 BestEffort 的 Pod 一直在吃余量),但驱逐事件从月均 40+ 次降到 2 次以内,throttling 告警反而多了 3 倍——这说明 Burstable 的「省」是有隐性成本的。欢迎大家拿自己的数据来对拍。
0赞
0收藏
0楼层