requests 与 limits 的关系
requests 是「保证值」,调度器按它给 Pod 找节点,节点也按它决定资源竞争的权重;limits 是「上限」,超过 CPU 上限会被内核节流,超过内存上限会被直接杀掉。把 limits 写得比 requests 大,节点上就出现了超卖空间:日常按 requests 装箱,空闲时突发可以借用,但这份余量没有保证,高峰期同一节点上的容器会互相争抢。
基本信息
| requests 作用 | 调度依据、节点装箱依据、CPU 竞争时的权重 |
|---|---|
| limits.cpu 作用 | CPU 时间片上限,超出被 CFS 节流,进程不会被杀 |
| limits.memory 作用 | 内存上限,超出触发 OOMKill,容器重启 |
| 合法性约束 | limits 不能小于 requests,否则 API Server 拒绝创建 |
| QoS 归属 | 两者都不设是 BestEffort,都相等是 Guaranteed,其余为 Burstable |
| 观察工具 | kubectl top、监控中的 CFS 节流与 OOM 指标 |
超卖带来的影响
超卖带来的影响
requests.cpu: 200m
limits.cpu: 2000m
# 十个副本只占 2 核调度额度,满载时却需要 20 核:
# 高峰期同节点容器互相争抢,各自被节流,延迟同时升高
# 内存同理:limits 只是天花板,真正能不能用要看节点当时是否空闲查看争抢与超用
查看争抢与超用
kubectl top pod --containers -n prod # 实际用量与容器粒度对比
kubectl get pod web-x -o jsonpath='{.spec.containers[*].resources}' # 清单侧声明
kubectl describe node node1 | grep -A8 'Allocated resources' # 节点侧已分配的 requests
# 监控侧关注:container_cpu_cfs_throttled_seconds_total(节流)、
# container_memory_working_set_bytes 与 OOM 计数QoS 等级与特点
| QoS | 判定条件 | 特点 |
|---|---|---|
| Guaranteed | 每个容器都设置了 requests 且等于 limits | 最稳,节点压力大时最后才被驱逐 |
| Burstable | 设置过 requests,limits 更大或只设了一项 | 允许突发,争抢时受节流影响 |
| BestEffort | 完全没设置 requests 与 limits | 最先被驱逐,用量完全不可控 |
典型使用场景
- 延迟敏感服务:把 requests 设得接近 limits,减少被同节点邻居节流的概率
- 批处理任务:可以放宽超卖,用较低优先级与可中断特性换取更高的装箱率
- 容量规划:统计所有 Pod 的 requests 之和来判断节点还能不能排下新业务
- 超卖率评估:用 limits 之和与节点可分配量之比衡量最坏情况下的资源缺口
- 排查周期性延迟抖动:先看是否被 CFS 节流,而不是先怀疑代码
limits 小于 requests 属于非法配置,API Server 会直接拒绝;调参时先改 requests 再改 limits,避免中间状态被拒。另外 CPU 与内存的失败方式完全不同:CPU 超用表现为变慢,内存超用表现为容器被杀,排查方向也不同。
给命名空间配 LimitRange 可以给未声明的容器补上默认 requests 与 limits,避免整批 Pod 落到 BestEffort;但默认值与业务实际需求可能差很远,仍要按服务逐个确认。