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:

CPU Throttling 机制:CFS 配额周期 周期 1(100ms) 使用 80ms 未超限,无 Throttle 周期 2(100ms) 使用 120ms(超限) 触发 Throttle 周期 3(100ms) 使用 60ms 恢复运行 Throttling 过程说明: 1. 假设 Limits = 1 核(quota = 100ms / period = 100ms) 2. 周期 2 中容器使用了 120ms CPU 时间,超出 quota 20ms 3. 内核强制容器睡眠 20ms,直到周期 3 开始才能继续运行 4. 周期 3 中容器仅使用 60ms,未超限,正常运行

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

  1. 基准测试先行: 使用 stress 或实际业务负载,测量容器在稳定状态下的 CPU 使用率 P99 值,作为 Requests 的参考基线。
  2. 设置合理的 Limits 上限: 建议 Limits = Requests × (1.2 ~ 2.0),为突发流量预留缓冲,同时避免无限使用。
  3. 监控 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 调度与运行时影响对比总览

Requests vs Limits:调度与运行时影响对比 CPU Requests 调度器:节点资源准入判断 运行时:CFS cpu.shares(权重) 资源竞争时按比例分配 CPU 保证:最小资源承诺 CPU Limits 调度器:不参与节点准入 运行时:CFS cpu.cfs_quota_us(硬限) 超限时触发 Throttling 限制:最大资源上限 互补
最佳实践总结: 生产环境中,建议始终为每个容器设置 CPU Requests,确保调度器能做出合理的资源分配决策。Limits 应根据应用的实际 CPU 使用峰值设置,避免设置过高导致节点资源被个别 Pod 耗尽,也避免设置过低引发频繁 Throttling。对于关键业务,优先使用 Guaranteed QoS(Requests == Limits)。