3. Requests 与 Limits:CPU 资源语义与运行时影响
CPU 的 Requests 与 Limits 是 Kubernetes 资源管理的核心原语,但二者在调度决策、内核 CFS 配额、CPU 时间片分配以及容器实际运行行为上存在本质差异。理解这些差异是进行 CPU 容量配额调优的前提。
3.1 语义定义与核心区别
| 属性 | Requests(请求) | Limits(限制) |
|---|---|---|
| 调度语义 | 节点资源预留的保证值,调度器据此判断节点是否满足 Pod 运行条件 | 调度器不直接使用 Limits 做准入判断,仅用于运行时约束 |
| 内核实现 | 对应 CFS cpu.shares(相对权重),非硬性上限 |
对应 CFS cpu.cfs_quota_us(硬性时间片上限) |
| 超卖行为 | 节点可超卖(所有 Pod Requests 总和可超过节点 CPU 总量) | 节点不可超卖 Limits(所有 Pod Limits 总和超过节点 CPU 总量时,内核仍可执行,但可能触发 Throttling) |
| CPU 时间分配 | 空闲 CPU 可被容器借用,权重由 Requests 比例决定 | 严格限制容器在每周期内可使用的 CPU 时间上限 |
| QoS 等级影响 | Requests == Limits 时属于 Guaranteed 类;Requests < Limits 时属于 Burstable 类 | 未设置 Limits 时属于 BestEffort 类(仅设置 Requests 也归为 Burstable) |
关键结论: Requests 是“承诺的最小资源”,Limits 是“允许的最大资源”。调度器只看 Requests,运行时内核同时使用两者。
3.2 调度阶段的实际影响
调度器(kube-scheduler)在节点筛选阶段,会累加节点上所有已运行 Pod 的 CPU Requests 总和,并与节点可分配 CPU 容量进行比较。只有剩余容量 ≥ 待调度 Pod 的 CPU Requests 时,该节点才被纳入候选。
# 节点可分配 CPU:4 核(4000m)
# 已运行 Pod Requests 总和:2500m
# 待调度 Pod Requests:1000m
# 剩余容量:4000 - 2500 = 1500m ≥ 1000m → 节点通过筛选
常见误区: 调度器不会检查 Limits。即使节点上所有 Pod 的 Limits 总和远超节点 CPU 总量,调度器仍可能将新 Pod 调度到该节点。这会导致节点 CPU 过度竞争,引发严重的 Throttling 现象。
3.3 运行时阶段的实际影响
容器运行时(如 containerd/runc)在创建容器时,会根据 Requests 和 Limits 配置内核 CFS(Completely Fair Scheduler)参数:
- cpu.shares(由 Requests 决定):控制 CPU 时间片的相对权重。当节点 CPU 资源充足时,所有容器都能获得所需 CPU;当 CPU 资源紧张时,按 Requests 比例分配。
- cpu.cfs_quota_us / cpu.cfs_period_us(由 Limits 决定):在每 100ms(默认 period)内,容器最多只能使用 quota 对应的 CPU 时间。超过则被 Throttle(节流),直到下一个周期。
性能调优提示: 对于延迟敏感型应用(如 API 网关、实时交易系统),建议设置 Requests == Limits(Guaranteed QoS),避免因 CPU 竞争或 Throttling 引入不可控的延迟抖动。
3.4 CPU Throttling 与时间片分配机制
下图展示了当容器 CPU 使用率超过 Limits 时,内核 CFS 如何执行 Throttling:
3.5 Requests 与 Limits 的典型配置模式
| 配置模式 | QoS 等级 | 适用场景 | 风险提示 |
|---|---|---|---|
| Requests == Limits | Guaranteed | 延迟敏感、数据库、核心中间件 | 资源利用率较低,需精确评估实际需求 |
| Requests < Limits | Burstable | Web 服务、批处理任务、开发环境 | CPU 竞争时可能被限制,需监控 Throttling 率 |
| 仅设置 Requests,不设 Limits | Burstable | 非关键业务、弹性伸缩场景 | 可能耗尽节点 CPU,影响同节点其他 Pod |
| 均不设置 | BestEffort | 测试、低优先级批处理 | 无任何资源保障,优先被驱逐 |
3.6 调优实践:如何合理设置 CPU Requests 与 Limits
- 基准测试先行: 使用
stress或实际业务负载,测量容器在稳定状态下的 CPU 使用率 P99 值,作为 Requests 的参考基线。 - 设置合理的 Limits 上限: 建议 Limits = Requests × (1.2 ~ 2.0),为突发流量预留缓冲,同时避免无限使用。
- 监控 Throttling 指标: 通过
container_cpu_cfs_throttled_seconds_total和container_cpu_cfs_periods_total计算 Throttling 率:
# PromQL 示例:计算容器 CPU Throttling 率(最近 5 分钟)
rate(container_cpu_cfs_throttled_seconds_total[5m])
/
rate(container_cpu_cfs_periods_total[5m])
* 100
调优红线: 当 Throttling 率持续超过 5% 时,说明容器频繁被内核节流,应增大 Limits 或优化应用 CPU 使用模式。对于延迟敏感型服务,Throttling 率应控制在 1% 以下。
3.7 调度与运行时影响对比总览
最佳实践总结: 生产环境中,建议始终为每个容器设置 CPU Requests,确保调度器能做出合理的资源分配决策。Limits 应根据应用的实际 CPU 使用峰值设置,避免设置过高导致节点资源被个别 Pod 耗尽,也避免设置过低引发频繁 Throttling。对于关键业务,优先使用 Guaranteed QoS(Requests == Limits)。