cgroup v1 CPU Shares 到 v2 CPU Weight 的新转换公式

概述

CPU 资源的分配与限制是确保系统稳定性和性能的关键环节,也是 SRE 工作中关注的核心问题之一。随着 Linux 控制组(cgroup)从 v1 版本迁移到 v2 版本,Kubernetes 需要相应地将 CPU 请求值映射到新的资源控制参数上。本文详细介绍了 Kubernetes 生态中一个重要的改进:从 cgroup v1 cpu.shares 到 cgroup v2 cpu.weight 的新转换公式。该变更解决了旧线性映射公式带来的两个严重问题:Kubernetes 工作负载相对于非 Kubernetes 进程优先级降低,以及容器内部进行细粒度资源分配的粒度不足。这一改进对于运行在 cgroup v2 系统上的所有 Kubernetes 集群的可靠性、性能预测及容量规划具有直接意义。

核心概念

要理解这一变更,首先需要明确几个关键概念及其差异。

  1. cgroup v1 cpu.shares:在 cgroup v1 中,用于表示容器 CPU 份额的参数。其默认值为 1024,定义了当 CPU 资源争用时,不同 cgroup 之间分配 CPU 时间的相对权重。例如,请求 1 个 CPU(1000m)会计算为 cpu.shares = 1000 * 1024 / 1000 = 1024。
  2. cgroup v2 cpu.weight:cgroup v2 中的替代参数,范围从 1 到 10000(10⁰ 到 10⁴),默认值为 100。它更直接地表示相对权重。
  3. 旧的线性转换公式:早期 Kubernetes 采用的映射方法:cpu.weight = (1 + ((cpu.shares - 2) * 9999) / 262142)。该公式将 v1 的 cpu.shares 范围 [2, 262144] 线性映射到 v2 的 cpu.weight 范围 [1, 10000]。
  4. 新的二次转换公式:本次改进引入的公式,旨在更精确地映射关键值点: cpu.weight = ⌈ 10^(L²/612 + 125L/612 - 7/34) ⌉,其中 L = log₂(cpu.shares)。 这个公式经过精心设计,确保了三个关键点的准确映射:
    • (cpu.shares=2, cpu.weight=1):最小值。
    • (cpu.shares=1024, cpu.weight=100):默认值。
    • (cpu.shares=262144, cpu.weight=10000):最大值。

实践

新公式的应用与集成

新转换公式在 OCI(Open Container Initiative)运行时层实现,而非 Kubernetes 核心代码。这意味着其采用完全依赖于底层容器运行时的更新。当前,已支持此公式的 OCI 运行时版本包括:

  • runc:版本 1.3.2 及以上。
  • crun:版本 1.23 及以上。

当集群节点升级或更换使用了新版 OCI 运行时后,新创建的 Pod 将自动应用此新公式计算 cpu.weight。

对现有部署的影响与迁移考量

对于已经运行在 cgroup v2 环境下的 Kubernetes 集群,升级 OCI 运行时以采用新公式需要谨慎评估。关键影响包括:

  1. 预期行为变化:工作负载的 CPU 调度优先级和权重值将发生改变。例如,一个请求 1000m CPU 的容器,其 cpu.weight 将从旧公式计算的 ≈39 提升至新公式的 102,更接近默认值 100。
  2. 工具链兼容性:任何直接依赖或假设旧线性公式计算预期 cpu.weight 值的工具(如某些自定义资源管理器、监控系统或验证脚本)可能需要更新。需要特别注意,由于公式是多对一映射(如 90m 到 109m 的 CPU 请求都可能映射到 cpu.weight=17),从 cpu.weight 反向推导精确的原始 cpu.request 值是不可靠的。
  3. 迁移路径:强烈建议在非生产环境中测试新公式对现有工作负载和工具链的影响,确认兼容性后再在生产环境进行 OCI 运行时升级。精确的 CPU 请求值应始终从 Pod 的 spec 中读取,而非从 cgroup 参数反推。

SRE 要点

  • 与可靠性的关联:旧公式的主要问题之一是降低了 Kubernetes 工作负载相对于系统守护进程的 CPU 优先级。在资源紧张时,这可能导致关键业务容器被不必要地抢占 CPU 资源,影响服务可用性和延迟。新公式恢复了公平的优先级,直接提升了生产工作负载在争用场景下的资源保障和可预测性。
  • 与可观测性/监控的关联:这一变更要求 SRE 团队更新对 CPU 资源分配的认知和相关的监控告警规则。监控系统中关于 cpu.weight 的基线阈值、预期值比较逻辑可能需要重新校准,以避免因公式变更导致的误报或漏报。
  • 与事件响应的关联:当在 cgroup v2 环境中调查 CPU 性能问题(如 throttling)时,SRE 需要知道节点 OCI 运行时的版本以及它应用的是哪种转换公式,因为这直接影响到分析 cpu.weight 值是否合理。问题的根本原因可能与此类底层配置变更有关。
  • 最佳实践:
    1. 明确依赖:在管理资源配额和 SLO 时,应明确记录底层 cgroup 版本及 CPU 权重转换逻辑。
    2. 渐进式升级:升级 OCI 运行时前,务必进行充分的非生产环境测试。
    3. 避免反向依赖:避免在监控或自动化工具中硬编码 cpu.weight 的具体数值或依赖其反向推导原始请求值。
  • 常见反模式:
    • 在生产环境中直接升级 OCI 运行时而不进行兼容性测试。
    • 基于旧公式在监控中设置固定的 cpu.weight 阈值告警,导致大量误报。
    • 误以为可以高精度地通过 cpu.weight 还原出 Pod 声明的 CPU 资源。
  • 相关指标(SLI/SLO):此变更直接影响 cpu.weight 这一底层 SLI(服务等级指标) 的值。虽然它不直接构成一个独立的 SLI,但它是实现 CPU 调度公平性和资源保障能力的关键底层参数。相关的 SLO(如“P99 延迟低于 X”或“CPU throttling 时间低于 Y%”)的达成,可能间接依赖于 CPU 权重映射的正确性和公平性。SRE 应将 OCI 运行时版本作为计算基础设施健康状况的元数据之一进行跟踪。

相关概念:cgroup-resource-management, oci-runtime, resource-quotas