4. CPU资源配额基础:Kubernetes CPU Request与Limit机制、CFS配额与CPU Throttling

在服务网格场景下,Envoy Sidecar 与业务容器共享同一套 CPU 资源配额。理解 Kubernetes 的 CPU 资源模型以及底层 CFS(Completely Fair Scheduler)配额机制,是诊断因 CPU 节流(Throttling)导致 API 延迟飙升的前提。

4.1 CPU Request 与 Limit:资源保证与硬边界

Kubernetes 通过 Request 和 Limit 两个参数定义容器的 CPU 资源约束:

参数 含义 调度依据 运行时行为
Request 容器保证能获得的 CPU 时间下限 节点调度决策(总和 ≤ 节点可分配) CFS 为该容器分配对应的权重(Shares)
Limit 容器最多能使用的 CPU 时间上限 不参与调度 CFS 通过配额周期(CFS Quota)强制执行硬限制
关键认知: Request 决定“你能用多少”,Limit 决定“你最多能用多少”。当 Limit > Request 时,容器在空闲时可突发(Burst)使用额外 CPU;当 CPU 争用时,容器只能获得 Request 对应的份额。

4.2 CFS 配额与 CPU Throttling 原理

Kubernetes 的 CPU Limit 底层由 Linux CFS 的 cpu.cfs_quota_us 和 cpu.cfs_period_us 实现。默认周期为 100ms(即 100000μs)。

  • CFS Period:一个固定的时间窗口,默认 100ms。
  • CFS Quota:在该周期内,容器允许使用的 CPU 时间总量。
  • Throttling:当容器在周期内消耗完 Quota,剩余时间将被强制休眠,直到下一个周期重置。

例如,设置 limits.cpu: 2,则 CFS Quota = 2 × 100000μs = 200000μs。容器每 100ms 最多运行 200ms(即 2 个核满负载)。

Throttling 计算公式:
Throttled Time = 容器在周期内实际运行时间 - CFS Quota(当实际运行时间 > Quota 时)
节流率 = Throttled Time / (CFS Period × 周期数)

4.3 CPU Throttling 对服务网格延迟的影响

Envoy 作为 Sidecar 处理所有入站和出站流量。当 Envoy 容器被 CPU Throttling 时,其事件循环(Event Loop)无法及时处理网络 I/O,直接导致:

  • 请求排队:Worker 线程被暂停,新请求在连接池或缓冲区堆积。
  • 延迟抖动:P99 延迟出现周期性尖峰,与 CFS 周期(100ms)对齐。
  • 连接超时:上游连接建立或 TLS 握手因调度延迟而失败。
常见误区: 仅监控容器 CPU 使用率(如 80%)无法发现 Throttling。Throttling 发生在微秒级的时间片内,必须通过 container_cpu_cfs_throttled_seconds_total 指标或 /sys/fs/cgroup/cpu.stat 中的 nr_throttled 来观测。

4.4 CFS 配额与 CPU Throttling 工作流程

下图展示了从 Pod 创建到 CFS 执行 Throttling 的完整链路:

CFS 配额与 CPU Throttling 工作流程 Pod 定义 resources.limits.cpu=2 Kubelet 写入 cgroup 参数 CGroup cpu.cfs_quota_us=200000 CFS 调度器 周期 100ms,追踪已用 CPU 时间 已用时间 > Quota? 是 Throttle 休眠 否 继续运行 正常调度 说明: 当容器在 100ms 周期内消耗完 CFS Quota(如 200ms CPU 时间),CFS 强制容器线程休眠至周期结束,导致 Envoy 无法处理网络事件。

4.5 关键监控指标与诊断方法

在服务网格延迟诊断中,以下指标直接关联 CPU Throttling:

指标名称(Prometheus) 类型 诊断意义
container_cpu_cfs_throttled_seconds_total Counter 累计 Throttled 时间,增量反映节流严重程度
container_cpu_cfs_throttled_periods_total Counter 发生 Throttling 的周期数,与总周期数对比得节流率
container_cpu_cfs_periods_total Counter CFS 总周期数,用于计算节流比例
envoy_server_live + 延迟直方图 Gauge/Histogram 关联 Throttling 事件与 P99 延迟尖峰
诊断命令示例(在节点上直接查看 cgroup):
# 查看 Envoy 容器的 CFS 状态
cat /sys/fs/cgroup/cpu/kubepods/besteffort/pod<pod-uid>/<container-id>/cpu.stat

# 输出示例
nr_periods 12345
nr_throttled 678
throttled_time 34567890  # 单位:纳秒

# 节流率计算
throttle_ratio = nr_throttled / nr_periods  # 0.055 = 5.5%

4.6 优化策略:避免 Envoy 被 Throttling

基于上述机制,针对服务网格的 CPU 资源配额优化应遵循以下原则:

  1. 设置合理的 Request:基于 Envoy 的稳态 CPU 使用率(P99 或 P95)设置 Request,确保调度器为其预留足够份额。
  2. Limit 不宜过紧:避免将 Limit 设置为与 Request 相同(即无突发能力)。建议 Limit = Request × 1.5~2.0,允许流量突发时 Envoy 能短暂使用更多 CPU。
  3. 监控 Throttling 而非 CPU 使用率:将 container_cpu_cfs_throttled_seconds_total 加入告警规则,阈值设为 > 1% 节流率。
  4. 考虑禁用 CPU Limit(仅限特定场景):在独占节点或 QoS 保证的 Pod 中,可移除 Limit 以避免 Throttling,但需配合节点资源预留。
避坑提示: 不要盲目提高 Envoy 的 CPU Request。过高的 Request 会导致节点资源碎片化,降低调度密度。应结合 Envoy 的实际资源画像(通过 Prometheus 历史数据)进行精确配置。

4.7 知识结构总结

下表梳理了 CPU 资源配额的核心概念及其在服务网格延迟诊断中的角色:

概念 层级 对延迟的影响 优化方向
CPU Request 调度保证 低 Request 导致调度不足,竞争加剧 基于 P99 使用率设置
CPU Limit 运行时硬限制 过紧 Limit 导致 Throttling,延迟抖动 保留突发余量
CFS Quota 内核实现 Quota 耗尽直接触发线程休眠 监控 nr_throttled
CFS Period 内核时间窗口 固定 100ms,影响 Throttling 粒度 不可调(内核参数)