一、 核心困惑:为什么 CPU 使用率很低,却触发了节流告警?

在 Kubernetes 的日常运维中,一个非常普遍且令人困惑的现象是:监控仪表盘显示容器的 CPU 平均使用率 非常低,但同时却收到了严重的 CPU 节流 告警。

这引出了一个核心问题:CPU 节流告警的触发,并非取决于长时间的 平均 CPU 使用率,而是由毫秒级别的 瞬时 CPU 峰值 撞上资源限制(limits.cpu)所导致的。平均值会掩盖这些对应用性能造成致命影响的瞬时瓶颈。


二、 CPU 节流的根本原理:CFS Quota

Kubernetes 的 CPU 限制(limits)依赖于 Linux 内核的 CFS (Completely Fair Scheduler) Quota 机制。理解其工作方式是解开谜团的关键。

  • 调度周期 (cpu.cfs_period_us): CFS 将时间划分为一个个微小的调度周期,通常固定为 100ms(即 100,000 微秒)。
  • CPU 配额 (cpu.cfs_quota_us): 它定义了在一个调度周期(100ms)内,一个容器被允许使用的 CPU 总时间。这个值由 limits.cpu 决定。
    • limits.cpu: "1" 意味着配额为 100ms。
    • limits.cpu: "0.5" (或 500m) 意味着配额为 50ms。
    • limits.cpu: "2" 意味着配额为 200ms。

节流的触发机制: 在一个 100ms 的时间窗口内,如果容器用满了其全部分配的 CPU 配额(例如 50ms),那么在这个周期的剩余时间里(剩下的 50ms),内核会强制暂停该容器的进程,不允许其再被调度执行。这个强制暂停就是“节流”(Throttling)。直到下一个 100ms 周期开始,容器才能重新获得 CPU 时间。

生动的比喻:高速公路的平均速度与瞬时超速

概念 类比 解释
平均 CPU 使用率 一小时内的 平均车速 您可能开了10分钟(时速150km/h),然后停车了50分钟,最终平均时速仅为25km/h,远低于限速。
CPU 节流 瞬时超速被 摄像头抓拍 在那飞驰的10分钟里,您的瞬时速度超过了120km/h的限制,因此被判定为违规。

结论:应用的平均 CPU 使用率低,完全不代表它在处理请求的关键路径上没有发生严重的、损害性能的瞬时节流。


三、 如何正确监控与告警

鉴于平均使用率的“欺骗性”,我们必须使用正确的指标来监控和告警。

1. 黄金指标:periods 而非 seconds

cAdvisor 提供了两个相关的节流指标,但它们的可靠性天差地别:

指标 (Metric) 含义 可靠性与可用性 推荐度
container_cpu_cfs_throttled_periods_total 容器被节流的 周期总数 高。这是最标准、最可靠的节流指标,几乎所有环境都提供。 ⭐⭐⭐⭐⭐
container_cpu_cfs_throttled_seconds_total 容器被节流的 累计总时长 低。严重依赖内核版本,在很多系统中恒为0,导致查询无数据。 ⭐

实践准则:始终使用 container_cpu_cfs_throttled_periods_total 和 container_cpu_cfs_periods_total 来进行计算。

2. 标准告警规则:CPUThrottlingHigh

这是一个业界标准的告警规则,用于检测节流率是否超过了某个阈值(例如 25%)。

sum without (id, metrics_path, name, image, endpoint, job, node) (
  topk by (cluster, namespace, pod, container, instance) (1, 
    increase(container_cpu_cfs_throttled_periods_total{container!="",job="kubelet",metrics_path="/metrics/cadvisor"}[5m])
  )
) 
/ on (cluster, namespace, pod, container, instance) group_left () 
sum without (id, metrics_path, name, image, endpoint, job, node) (
  topk by (cluster, namespace, pod, container, instance) (1, 
    increase(container_cpu_cfs_periods_total{job="kubelet",metrics_path="/metrics/cadvisor"}[5m])
  )
) 
> (25 / 100)
  • 核心逻辑: (过去5分钟节流周期增量) / (过去5分钟总周期增量) > 0.25
  • 含义: 如果一个容器在5分钟内,有超过25%的调度周期都发生了节流,则触发告警。这是一个非常明确的性能问题信号。

3. 仪表盘可视化查询

为了在 Grafana 等工具中可视化 CPU 节流的严重程度,应使用与告警规则类似的逻辑,计算节流率。

# 计算 CPU 节流率 (%)
sum(rate(container_cpu_cfs_throttled_periods_total{namespace="$namespace", pod=~"$pod", container!=""}[$__rate_interval])) by (pod, container)
/
sum(rate(container_cpu_cfs_periods_total{namespace="$namespace", pod=~"$pod", container!=""}[$__rate_interval])) by (pod, container)
* 100

将这个查询的结果以百分比的形式展示在图表上,可以非常直观地定位到哪些 Pod 或容器正在遭受 CPU 节流的影响。


四、 解决方案与实践

当确认发生 CPU 节流后,可以根据业务场景和资源情况选择以下一种或多种方案。

1. 调整 CPU limits(最直接)

这是最快、最直接的解决方法。如果应用确实存在无法优化的瞬时 CPU 峰值,适当地提高 limits.cpu 的值可以立竿见影地减少节流,改善应用响应时间。

  • 操作:kubectl edit deployment/... 修改容器的 resources.limits.cpu 值。
  • 建议:可以尝试将 limits 翻倍,然后持续观察节流率是否显著下降。

2. 仅设置 requests,移除 limits(需谨慎)

当容器只设置 requests 而不设置 limits 时,其 QoS 等级为 Burstable。

  • 优点:
    • 消除节流:只要节点上存在空闲的 CPU 资源,容器就可以突破 requests 的限制尽情使用,从而完全避免了 CFS 节流带来的性能惩罚。
    • 提高资源利用率:充分利用节点的闲置资源。
  • 缺点:
    • “吵闹的邻居”:一个行为异常的容器可能会耗尽整个节点的 CPU,影响同一节点上其他服务的稳定性。
    • 资源规划困难:由于容器使用资源的行为不可预测,给集群的容量规划带来挑战。
  • 适用场景:对延迟非常敏感、能容忍资源争抢的服务,或在资源隔离做得很好的非生产环境中。

3. 优化应用程序代码(最根本)

从根源上解决问题。通过性能分析工具(如 Profiler)定位到导致 CPU 峰值的代码逻辑。

  • 方向:
    • 优化算法,减少计算复杂度。
    • 将同步的、CPU 密集型的单线程任务改造为异步或多线程的平缓处理模式。
    • 引入缓存,减少重复计算。

4. 使用静态 CPU 管理策略(终极方案)

对于需要极致性能和稳定低延迟的数据库、消息队列等应用,可以启用节点的 静态 CPU 管理策略 (static policy)。

  • 要求:容器必须为 Guaranteed QoS 等级(requests 和 limits 相等且为整数)。
  • 效果:Kubernetes 会为该容器分配独占的物理 CPU 核心。进程将完全脱离 CFS Quota 的管制,不再有任何节流,并且可以避免与其他进程争抢核心所带来的上下文切换开销。
  • 代价:会降低节点的 CPU 资源利用率,因为被分配的核心无法被其他任何容器共享。
最后修改日期: 26 9 月, 2026

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。

允许上传的最大文件为80 MB。 您可以上传:图像, 音频, 视频, 文档, 电子表格, 互动, 文本, 存档, 代码, 其他。 评论文本中插入的YouTube、Facebook、Twitter和其他服务的链接将自动嵌入。 Drop files here