控制节点上的 CPU 管理策略

特性状态: Kubernetes v1.26 [stable]

Kubernetes 将 Pod 在节点上执行的许多方面抽象化,不向用户暴露。这是有意设计的。然而,一些工作负载要求在延迟和/或性能方面有更强的保证才能正常运行。kubelet 提供了方法来支持更复杂的工作负载放置策略,同时保持抽象层不包含显式的放置指令。

关于资源管理的详细信息,请参阅管理 Pod 和容器的资源文档。

关于 kubelet 如何实现资源管理的详细信息,请参阅节点资源管理器文档。

准备工作

你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具已配置为与你的集群通信。建议在本教程中使用至少两个不作为控制平面主机的节点组成的集群。如果你还没有集群,可以使用 minikube 创建,或使用以下 Kubernetes 演练环境之一

你的 Kubernetes 服务器版本必须不低于 v1.26。

要检查版本,输入 kubectl version

如果你运行的是旧版本的 Kubernetes,请查阅你实际运行版本的文档。

配置 CPU 管理策略

默认情况下,kubelet 使用 CFS 配额来强制执行 Pod 的 CPU 限制。当节点运行大量 CPU 密集型 Pod 时,工作负载可能会迁移到不同的 CPU 内核,具体取决于 Pod 是否被限流以及调度时哪些 CPU 内核可用。许多工作负载对此类迁移不敏感,因此在没有干预的情况下也能正常工作。

然而,在 CPU 缓存亲和性(CPU cache affinity)和调度延迟显著影响工作负载性能的场景下,kubelet 允许使用替代的 CPU 管理策略来确定节点上的一些放置偏好。

Windows 支持

特性状态: Kubernetes v1.32 [alpha] (默认未启用)

在 Windows 上可以通过使用 WindowsCPUAndMemoryAffinity 特性门控来启用 CPU 管理器支持,这需要容器运行时的支持。启用特性门控后,按照以下步骤配置CPU 管理器策略

配置

CPU 管理器策略由 --cpu-manager-policy kubelet 参数或 KubeletConfiguration 中的 cpuManagerPolicy 字段设置。支持以下两种策略

  • none: 默认策略。
  • static: 允许具有特定资源特征的 Pod 在节点上获得增强的 CPU 亲和性和独占性。

CPU 管理器会通过 CRI 定期写入资源更新,以协调内存中的 CPU 分配与 cgroupfs。协调频率通过新的 kubelet 配置值 --cpu-manager-reconcile-period 设置。如果未指定,则默认为与 --node-status-update-frequency 相同的持续时间。

静态策略的行为可以通过 --cpu-manager-policy-options 参数进行微调。该参数接受一个逗号分隔的 key=value 策略选项列表。如果禁用 CPUManagerPolicyOptions 特性门控,则无法微调 CPU 管理器策略。在这种情况下,CPU 管理器仅使用其默认设置运行。

除了顶层 CPUManagerPolicyOptions 特性门控外,策略选项还分为两个组:Alpha 级别(默认隐藏)和 Beta 级别(默认可见)。这些组分别由 CPUManagerPolicyAlphaOptionsCPUManagerPolicyBetaOptions 特性门控控制。与 Kubernetes 标准不同,这些特性门控控制的是选项组,因为为每个独立选项添加一个特性门控会过于繁琐。

修改 CPU 管理器策略

由于 CPU 管理器策略只能在 kubelet 启动新 Pod 时应用,因此简单地将策略从 "none" 更改为 "static" 对现有 Pod 不生效。因此,要正确更改节点上的 CPU 管理器策略,请执行以下步骤:

  1. 排空节点。
  2. 停止 kubelet。
  3. 删除旧的 CPU 管理器状态文件。此文件的默认路径是 /var/lib/kubelet/cpu_manager_state。这将清除 CPUManager 维护的状态,以便新策略设置的 cpu-sets 不会与之冲突。
  4. 编辑 kubelet 配置,将 CPU 管理器策略更改为所需的值。
  5. 启动 kubelet。

对需要更改 CPU 管理器策略的每个节点重复此过程。跳过此过程将导致 kubelet 崩溃并循环重启,出现以下错误

could not restore state from checkpoint: configured policy "static" differs from state checkpoint policy "none", please drain this node and delete the CPU manager checkpoint file "/var/lib/kubelet/cpu_manager_state" before restarting Kubelet

none 策略配置

此策略没有额外的配置项。

static 策略配置

此策略管理一个共享 CPU 池,该池最初包含节点上的所有 CPU。可独占分配的 CPU 数量等于节点上的总 CPU 数量减去由 kubelet --kube-reserved--system-reserved 选项预留的任何 CPU。从 1.17 版本开始,可以使用 kubelet --reserved-cpus 选项显式指定 CPU 预留列表。由 --reserved-cpus 显式指定的 CPU 列表优先于由 --kube-reserved--system-reserved 指定的 CPU 预留。这些选项预留的 CPU 会从初始共享池中以物理核心 ID 升序的方式,按整数数量获取。此共享池是运行任何 BestEffortBurstable Pod 中的容器所使用的 CPU 集合。Guaranteed Pod 中具有分数 CPU requests 的容器也在此共享池的 CPU 上运行。只有同时是 Guaranteed Pod 的一部分且具有整数 CPU requests 的容器才会被分配独占 CPU。

静态策略选项

你可以根据其成熟度级别使用以下特性门控来开启和关闭选项组

  • CPUManagerPolicyBetaOptions 默认启用。禁用以隐藏 Beta 级别选项。
  • CPUManagerPolicyAlphaOptions 默认禁用。启用以显示 Alpha 级别选项。你仍然需要使用 CPUManagerPolicyOptions kubelet 选项来启用每个选项。

静态 CPUManager 策略存在以下策略选项

  • full-pcpus-only (GA, 默认可见) (1.33 或更高版本)
  • distribute-cpus-across-numa (Beta, 默认可见) (1.33 或更高版本)
  • align-by-socket (Alpha, 默认隐藏) (1.25 或更高版本)
  • distribute-cpus-across-cores (Alpha, 默认隐藏) (1.31 或更高版本)
  • strict-cpu-reservation (Beta, 默认可见) (1.32 或更高版本)
  • prefer-align-cpus-by-uncorecache (Alpha, 默认隐藏) (1.32 或更高版本)

可以通过将 full-pcpus-only=true 添加到 CPUManager 策略选项来启用 full-pcpus-only 选项。类似地,可以通过将 distribute-cpus-across-numa=true 添加到 CPUManager 策略选项来启用 distribute-cpus-across-numa 选项。当两者都设置时,它们是“加法”关系,CPU 将以完整物理核心块而不是单个核心的方式跨 NUMA 节点分布。align-by-socket 策略选项可以通过将 align-by-socket=true 添加到 CPUManager 策略选项来启用。它也是对 full-pcpus-onlydistribute-cpus-across-numa 策略选项的加法。

可以通过将 distribute-cpus-across-cores=true 添加到 CPUManager 策略选项来启用 distribute-cpus-across-cores 选项。目前不能与 full-pcpus-onlydistribute-cpus-across-numa 策略选项一起使用。

可以通过将 strict-cpu-reservation=true 添加到 CPUManager 策略选项,然后删除 /var/lib/kubelet/cpu_manager_state 文件并重启 kubelet 来启用 strict-cpu-reservation 选项。

可以通过将 prefer-align-cpus-by-uncorecache 添加到 CPUManager 策略选项来启用 prefer-align-cpus-by-uncorecache 选项。如果使用了不兼容的选项,kubelet 将无法启动,并在日志中解释错误。

有关你可以配置的各个选项行为的更多详细信息,请参阅节点资源管理器文档。

上次修改时间:太平洋标准时间 2025 年 2 月 25 日下午 4:48:KEP-2625: cpumanager full-pcpus-inly becomes GA (0a80c0544a)