背景 我维护一套 K8s 集群上的 Java + Go 混合微服务,CPU 是 Burstable(requests=2,limits=4)为主。今年两次 P99 抖动复盘,根因都指向 CFS 节流:一个批处理型服务在 limit 边缘跑,cfs_throttled_periods 在高峰段明显上涨,直接拖垮同节点邻居的 RT。于是我们开始全员调 limits——结果调完发现,不少服务为了"不被节流"把 limit 抬到了 8C,节点 CPU 实际分配率被推得很高,超卖反而更危险了。 这件事让我意识到:CPU limit 这个参数,团队里基本没有人能讲清楚"它到底应该设成多少"。 设小了尾延迟抖,设大了超卖失控,干脆不设又回到"无约束 QoS"的老路。
常见分歧 我见过至少四种做法,各有各的理:
- requests/limits 同值(Guaranteed QoS):最稳,但内存也得同值,Java 堆内存场景基本用不了;
- 只设 requests、不设 limits:节点资源靠 K8s 调度兜底,接受 Burstable 被抢占的风险,配合 LimitRange 给个软上限;
- 设 limits 但按 P99×1.5 拍脑袋:最常见的做法,但没人验证过 P99 采样窗口够不够长、够不够代表高峰;
- 完全交给 HPA + VPA:理论上最优雅,但 VPA 在 K8s 1.27 还是 Alpha,我们集群不敢上。
我的倾向 我倾向于走"requests 定基线、limits 定尖峰、用数据标定"的路线:
- requests 按稳态 P50 CPU 设(不是 P99,P99 留给 limits);
- limits 按近 30 天 P99 × 1.2 起步,然后观察 cfs_throttled_periods 和 node_cpu_allocation_ratio 两个指标,连续一周无节流且分配率 < 80% 再往下收;
- 对延迟敏感的服务(网关、支付链路)单独用 Guaranteed,内存用 cgroup memory 限制而不是 K8s limits。
但我不确定的是:这个标定方法在节点分配率本来就高(>85%)的集群里,是不是根本走不通? 这时候是不是应该先降超卖比,而不是纠结 limits 设多少?
想听大家聊聊
- 你们线上容器的 CPU limits 是按数据标定的还是按经验拍的?有没有一个可复现的标定流程?
- 有没有人真的跑过"只设 requests 不设 limits"的方案?节点被打爆过没有?
- 如果节点分配率已经 >85%,你们会先降超卖比、还是先给关键服务设 Guaranteed?
- 批处理型服务(ETL、离线计算)在 K8s 上到底该不该给 limits?还是直接扔进 Batch API 管?
欢迎贴你们集群的 kubectl top nodes 和 cfs 节流数据,咱们对着数据聊。
0赞
0收藏
0楼层