3. CPU 资源配额实战:Requests/Limits 配置策略与 CPU Throttling 分析

3.1 CPU Requests 与 Limits 核心概念

在 Kubernetes 中,CPU 资源配额通过 requests 和 limits 两个字段控制。理解两者的差异是避免性能抖动和资源浪费的前提。

属性Requests(保证量)Limits(上限)
调度依据调度器根据节点剩余可分配资源决定 Pod 放置位置不参与调度决策
CPU 份额权重CFS 调度器按 requests 比例分配 CPU 时间片不影响权重,仅限制突发上限
是否可超卖节点总 requests 可超过节点容量(超卖)节点总 limits 可超过节点容量
CPU Throttling不直接触发节流超过 limits 时强制节流(CFS quota)
典型配置策略设为稳态负载基线设为容忍突发峰值上限
最佳实践:生产环境建议始终设置 CPU requests,避免因未设置导致调度器低估负载。对于延迟敏感型工作负载,requests 应等于 limits,消除 CPU 节流风险。

3.2 CPU Throttling 现象与根因分析

CPU Throttling 是指容器在 CFS(Completely Fair Scheduler)配额用尽后被迫等待下一个周期的现象。高节流率直接导致请求延迟增加、吞吐量下降。

3.2.1 节流产生机制

  1. Kubelet 为每个容器创建 cgroup,设置 cpu.cfs_quota_us 和 cpu.cfs_period_us。
  2. 默认周期 cfs_period_us = 100ms(100000μs)。
  3. 若 limits = 2 核,则 cfs_quota_us = 200000μs,容器每 100ms 最多使用 200ms CPU 时间。
  4. 当容器在周期内用完配额,剩余时间被强制节流,直到下一个周期重置。
常见误区:很多团队认为设置较高的 limits 就能避免节流,但忽略了 CFS 周期粒度。即使平均 CPU 使用率低于 limits,短时间内的微突发也可能在单个周期内耗尽配额,导致毫秒级节流。

3.2.2 节流检测方法

# 通过 cgroup 直接查看节流统计
cat /sys/fs/cgroup/cpu/kubepods/burstable/pod<pod-uid>/<container-id>/cpu.stat

# 输出示例
nr_periods 124567
nr_throttled 8923
throttled_time 4567890123

# 节流率 = nr_throttled / nr_periods = 8923 / 124567 ≈ 7.16%

使用 kubectl top pod 或 Prometheus 指标 container_cpu_cfs_throttled_seconds_total 可进行集群级监控。

3.3 CPU Requests/Limits 配置策略

3.3.1 三种典型配置模式

模式RequestsLimits适用场景
Guaranteed(保障型)= Limits= Requests延迟敏感、数据库、核心中间件
Burstable(突发型)< Limits> RequestsWeb 服务、批处理、有波峰负载
BestEffort(尽力型)未设置未设置低优先级、可被驱逐的离线任务

3.3.2 基于性能数据的配置方法

  1. 采集基线:使用 Prometheus 或 VPA 分析过去 7 天 P50/P95/P99 CPU 使用率。
  2. 设置 requests:取 P50 或 P70 值,确保调度器预留足够资源。
  3. 设置 limits:取 P95 或 P99 值,或设置为 requests 的 1.5~2 倍。
  4. 验证节流率:目标 nr_throttled / nr_periods < 1%。若超过 5%,需调整 limits 或优化代码。
案例:某 Java 微服务 P50 CPU = 0.8 核,P99 = 1.6 核。配置 requests: 800m,limits: 1600m。运行后节流率 3.2%,将 limits 提升至 2000m 后节流率降至 0.4%,P99 延迟降低 22%。

3.4 CPU Manager 与拓扑感知调度

CPU Manager 是 kubelet 组件,负责管理 Guaranteed Pod 的 CPU 亲和性。拓扑感知调度则让调度器感知 NUMA 节点拓扑,避免跨 NUMA 访问导致的内存延迟。

3.4.1 CPU Manager 策略对比

策略行为适用场景
none默认策略,不绑定固定 CPU,允许任意调度非性能敏感型工作负载
static为整数核 Guaranteed Pod 分配独占 CPU 核心高吞吐、低延迟、DPDK、实时应用

3.4.2 拓扑感知调度(Topology Manager)

Topology Manager 与 CPU Manager、Device Manager 协同,确保 Pod 的 CPU、内存、设备分配在同一个 NUMA 节点上,减少跨 NUMA 访问开销。

# kubelet 配置示例(kubelet-config.yaml)
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cpuManagerPolicy: "static"
topologyManagerPolicy: "single-numa-node"
topologyManagerScope: "pod"
reservedSystemCPUs: "0-1"   # 预留 2 个核给系统进程
注意事项:
  • static 策略仅对 整数核 requests = limits 的 Guaranteed Pod 生效。
  • 启用 topologyManagerPolicy: single-numa-node 后,若节点无法满足 NUMA 对齐,Pod 将处于 TopologyAffinity 错误状态。
  • 预留 CPU(reservedSystemCPUs)必须与 kubelet 命令行 --system-reserved 保持一致。

3.5 CPU 资源配额与拓扑感知架构图

CPU 资源配额与拓扑感知调度架构 Kubernetes Scheduler 基于 Requests 调度决策 Kubelet CPU Manager + Topology Manager NUMA Node 0 CPU 0-3 CPU 4-7 内存控制器 (本地访问) CFS 配额与节流机制 周期 1 (100ms) 周期 2 (100ms) 周期 3 (100ms) 周期 4 (节流) 周期 5 (100ms) 使用 80% 使用 90% 使用 95% 配额耗尽 → 节流 使用 70% 关键指标:nr_throttled / nr_periods < 1% 为健康状态 Guaranteed Pod 配合 static CPU Manager + single-numa-node 可消除跨 NUMA 访问和节流抖动

3.6 实战配置清单与验证步骤

3.6.1 配置清单

apiVersion: v1
kind: Pod
metadata:
  name: cpu-performance-demo
spec:
  containers:
  - name: app
    image: myapp:latest
    resources:
      requests:
        cpu: "2"          # 保证 2 核
      limits:
        cpu: "2"          # 上限 2 核,Guaranteed 模式
    args:
    - --cpus=2
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: DoNotSchedule

3.6.2 验证步骤

  1. 检查 Pod 状态:kubectl describe pod cpu-performance-demo 确认 QoS 为 Guaranteed。
  2. 验证 CPU 绑定:进入容器执行 cat /sys/fs/cgroup/cpuset/cpuset.cpus 查看绑定的物理核心。
  3. 监控节流:使用 kubectl exec -- cat /sys/fs/cgroup/cpu/cpu.stat 计算节流率。
  4. 延迟测试:使用 wrk 或 hey 施加负载,对比 P99 延迟与节流率变化。
性能调优检查清单:
  • 所有生产 Pod 必须设置 CPU requests,避免 BestEffort 导致资源争抢。
  • 延迟敏感型服务使用 Guaranteed QoS,requests = limits。
  • 启用 CPU Manager static 策略前,确认节点预留了足够的系统 CPU。
  • 多 NUMA 节点环境启用 Topology Manager,策略设为 single-numa-node。
  • 定期监控 nr_throttled 指标,节流率超过 5% 时立即调整 limits 或优化代码。

3.7 CPU 资源配额决策流程

CPU 资源配额配置决策流程 采集 CPU 使用率基线 是否延迟敏感? 是 Guaranteed: requests=limits 否 Burstable: requests < limits 启用 CPU Manager static + Topology Manager