从 cgroup v1 CPU Shares 到 v2 CPU Weight 的新转换

发布: (2026年1月31日 GMT+8 00:00)
7 分钟阅读

I’m happy to translate the article for you, but I’ll need the full text you’d like translated. Could you please paste the content (excluding the source line you already provided) here? Once I have it, I’ll translate it into Simplified Chinese while preserving the original formatting, markdown syntax, and technical terms.

公告:改进的 CPU 份额 → CPU 权重 转换公式

我们很高兴推出一个新的转换公式,将 cgroup v1 CPU shares 转换为 cgroup v2 CPU weight。此改进解决了在使用 cgroup v2 的系统上运行的 Kubernetes 工作负载的 CPU 优先级分配相关的关键问题。

背景

Kubernetes 最初是为 cgroup v1 设计的,在该版本中,CPU 份额通过以 millicpu 形式分配容器的 CPU 请求来简单定义。

示例:请求 1 CPU1024m)的容器会得到 cpu.shares = 1024

过了一段时间,cgroup v1 开始被其继任者 cgroup v2 替代。在 cgroup v2 中,CPU 份额的概念(范围从 2 到 262 144,即 (2^{1}) 到 (2^{18}))被 CPU 权重(范围从 1 到 10 000,即 (10^{0}) 到 (10^{4}))所取代。

随着向 cgroup v2 的迁移,KEP‑2254 引入了一个转换公式,用于将 cgroup v1 的 CPU 份额映射到 cgroup v2 的 CPU 权重:

cpu.weight = (1 + ((cpu.shares - 2) * 9999) / 262142)

该公式将 ([2^{1}, 2^{18}]) 的值线性映射到 ([10^{0}, 10^{4}])。

Linear conversion from cgroup v1 CPU shares to cgroup v2 CPU weight

虽然这种方法简单,但线性映射会带来若干显著问题,影响性能和配置粒度。

Source:

先前转换公式的问题

当前的转换公式带来了两个主要问题。

对非 Kubernetes 工作负载的优先级降低

  • cgroup v1 中,CPU shares 的默认值为 1024
    因此,请求 1 CPU(1024 m)的容器与在 Kubernetes 之外运行的系统进程拥有相同的优先级。

  • cgroup v2 中,CPU weight 的默认值为 100,但当前公式将 1 CPU(1024 m) 转换为仅 ≈ 39 的 weight——不到默认值的 40 %。

示例

场景设置
容器请求1 CPU(1024 m)
cgroup v1cpu.shares1024(默认)
cgroup v2(当前)cpu.weight39(远低于默认 100

影响
迁移到 cgroup v2 后,Kubernetes(或 OCI)工作负载相对于非 Kubernetes 进程的 CPU 优先级会下降。这在节点上运行大量系统守护进程且资源紧张的情况下尤为严重。

粒度难以管理

当前公式对小的 CPU 请求会得到非常低的数值,导致在容器内部为细粒度资源分配创建子 cgroup 时困难(参见 KEP #5474)。

示例

场景设置
容器请求100 m CPU
cgroup v1cpu.shares102
cgroup v2(当前)cpu.weight4(对子 cgroup 配置来说太低)

影响
在 cgroup v1 中,100 m CPU(102 shares)的请求能够在子 cgroup 之间合理分配 CPU weight。而在 cgroup v2 中,4 的 weight 过于粗糙,阻碍了 CPU 资源在子 cgroup 之间的有效分配。随着 为非特权容器提供可写 cgroup(KEP #5474)的即将支持,这一问题将变得更加关键。

新的转换公式

描述

新的公式更为复杂,但在 cgroup v1 CPU shares 与 cgroup v2 CPU weight 之间的映射效果要好得多:

[ \text{cpu.weight} = \Bigl\lceil 10^{\left(\frac{L^{2}}{612} + \frac{125L}{612} - \frac{7}{34}\right)} \Bigr\rceil, \qquad\text{其中 } L = \log_{2}(\text{cpu.shares}) ]

它是一个二次函数,经过以下三个关键点:

cgroup v1 cpu.sharescgroup v2 cpu.weight
2 (最小值)1 (最小值)
1024 (默认值)100 (默认值)
262 144 (最大值)10 000 (最大值)

从视觉上看,新函数如下所示:

新转换公式 – 完整视图

放大重要区域:

新转换公式 – 缩放视图

该函数“接近线性”,但经过精心设计,使上述三个关键点恰好对齐。

它如何解决问题

更好的优先级对齐

请求 1 CPU(1024 m)的容器现在得到

cpu.weight = 102

这接近 cgroup v2 的默认权重 100。这恢复了 Kubernetes 工作负载与系统进程之间的预期优先级关系。

改进的粒度

请求 100 m CPU 的容器得到

cpu.weight = 17

(参见此处演示)。这使得容器内部的资源分配更加细致。

采用与集成

此更改在 OCI 层实现。换句话说,它 在 Kubernetes 本身实现;因此,新转换公式的采用完全取决于 OCI 运行时的采用情况。

支持的运行时

运行时启用新公式的版本
runcv1.3.2release notes
crunv1.23release notes

对现有部署的影响

Important: 如果某些使用者仍假设使用旧的线性转换公式,可能会受到影响。直接根据之前公式计算预期 CPU‑weight 值的应用程序或监控工具可能需要更新,以适配新的二次转换。

相关场景包括:

  • 预测 CPU‑weight 值的自定义资源管理工具。
  • 验证或期望特定权重值的监控系统。
  • 程序化设置或校验 CPU‑weight 值的应用程序。

Kubernetes 项目建议在升级 OCI 运行时之前,在非生产环境中测试新转换公式,以确保与现有工具链的兼容性。

我可以在哪里了解更多?

我该如何参与?

如果您有兴趣为 Kubernetes 节点级功能做贡献,请加入 Kubernetes Node Special Interest Group (SIG‑Node)

我们欢迎新的贡献者以及对资源管理挑战的多元化视角。

Back to Blog

相关文章

阅读更多 »