节点资源管理器

为了支持对延迟敏感和高吞吐量的负载,Kubernetes 提供了一套资源管理器。 这些管理器旨在协调和优化节点资源的对齐,以满足 Pod 对 CPU、设备和内存(大页)资源提出的特定要求。

硬件拓扑对齐策略

**拓扑管理器(Topology Manager)**是 kubelet 的一个组件,它旨在协调负责这些优化的组件集合。 整个资源管理过程由你指定的策略控制。要了解更多信息,请阅读控制节点上的拓扑管理策略

为 Pod 分配 CPU 的策略

特性状态: Kubernetes v1.26 [stable] (默认启用:是)

Pod 绑定到节点后,该节点上的 kubelet 可能需要多路复用现有硬件(例如,在多个 Pod 之间共享 CPU),或者通过专用一些资源来分配硬件(例如,为 Pod 独占使用分配一个或多个 CPU)。

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

然而,对于 CPU 缓存亲和性和调度延迟显著影响工作负载性能的工作负载,kubelet 允许使用替代的 CPU 管理策略来确定节点上的某些放置偏好。 这是通过 **CPU 管理器(CPU Manager)**及其策略实现的。有两种可用的策略:

  • nonenone 策略明确启用现有的默认 CPU 亲和方案,除了操作系统调度器自动执行的亲和性之外不提供任何亲和性。 针对Guaranteed PodBurstable Pod 的 CPU 使用限制使用 CFS 配额强制执行。
  • staticstatic 策略允许 Guaranteed Pod 中具有整数 CPU requests 的容器访问节点上的独占 CPU。 这种独占性通过 cpuset cgroup 控制器强制执行。

CPU 管理器不支持在运行时下线和上线 CPU。

静态策略

静态策略支持更细粒度的 CPU 管理和独占 CPU 分配。 此策略管理一个共享 CPU 池,该池最初包含节点中的所有 CPU。 独占可分配 CPU 的数量等于节点中的 CPU 总数减去 kubelet 配置设置的任何 CPU 预留。这些选项预留的 CPU 以整数形式从初始共享池中按物理核心 ID 升序获取。 此共享池是运行 BestEffortBurstable Pod 中任何容器的 CPU 集合。 Guaranteed Pod 中具有分数 CPU requests 的容器也运行在共享池中的 CPU 上。 只有属于 Guaranteed Pod 且具有整数 CPU requests 的容器才被分配独占 CPU。

当符合静态分配要求的 Guaranteed Pod 中的容器被调度到节点时,CPU 会从共享池中移除并放置到容器的 cpuset 中。 CFS 配额不用于限制这些容器的 CPU 使用,因为它们的用途受调度域本身限制。 换句话说,容器 cpuset 中的 CPU 数量等于 Pod 规约中指定的整数 CPU limit。这种静态分配增加了 CPU 亲和性,并减少了由于对 CPU 密集型工作负载进行节流而导致的上下文切换。

考虑以下 Pod 规约中的容器:

spec:
  containers:
  - name: nginx
    image: nginx

由于未指定资源 requestslimits,上述 Pod 在 BestEffort QoS 等级下运行。 它运行在共享池中。

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
      requests:
        memory: "100Mi"

由于资源 requests 不等于 limits 且未指定 cpu 数量,上述 Pod 在 Burstable QoS 等级下运行。 它运行在共享池中。

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "2"
      requests:
        memory: "100Mi"
        cpu: "1"

由于资源 requests 不等于 limits,上述 Pod 在 Burstable QoS 等级下运行。 它运行在共享池中。

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "2"
      requests:
        memory: "200Mi"
        cpu: "2"

由于 requests 等于 limits,上述 Pod 在 Guaranteed QoS 等级下运行。 并且容器对 CPU 资源的资源限制是一个大于或等于一的整数。 nginx 容器被授予 2 个独占 CPU。

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "1.5"
      requests:
        memory: "200Mi"
        cpu: "1.5"

由于 requests 等于 limits,上述 Pod 在 Guaranteed QoS 等级下运行。 但容器对 CPU 资源的资源限制是一个分数。 它运行在共享池中。

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "2"

由于只指定了 limits,并且在未明确指定 requests 时将其设置为等于 limits,上述 Pod 在 Guaranteed QoS 等级下运行。 并且容器对 CPU 资源的资源限制是一个大于或等于一的整数。 nginx 容器被授予 2 个独占 CPU。

静态策略选项

以下是静态 CPU 管理策略可用的策略选项,按字母顺序排列:

align-by-socket(Alpha 版,默认隐藏)
按物理封装/插槽边界而非逻辑 NUMA 边界对齐 CPU(自 Kubernetes v1.25 起可用)
distribute-cpus-across-cores(Alpha 版,默认隐藏)
将虚拟核心(有时称为硬件线程)分配到不同的物理核心(自 Kubernetes v1.31 起可用)
distribute-cpus-across-numa(Beta 版,默认可见)
将 CPU 分散到不同的 NUMA 域,旨在实现所选域之间的均匀平衡(自 Kubernetes v1.23 起可用)
full-pcpus-only(GA,默认可见)
始终分配完整的物理核心(自 Kubernetes v1.22 起可用,自 Kubernetes v1.33 起达到 GA 状态)
strict-cpu-reservation(Beta 版,默认可见)
无论 QoS 等级如何,都禁止所有 Pod 在保留的 CPU 上运行(自 Kubernetes v1.32 起可用)
prefer-align-cpus-by-uncorecache(Beta 版,默认可见)
尽力而为地按非核心(末级)缓存边界对齐 CPU(自 Kubernetes v1.32 起可用)

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

  • CPUManagerPolicyBetaOptions (默认启用)。禁用以隐藏 Beta 级别的选项。
  • CPUManagerPolicyAlphaOptions (默认禁用)。启用以显示 Alpha 级别的选项。

你仍然需要在 kubelet 配置文件中使用 cpuManagerPolicyOptions 字段启用每个选项。

有关你可以配置的各个选项的更多详细信息,请继续阅读。

full-pcpus-only

如果指定了 full-pcpus-only 策略选项,静态策略将始终分配完整的物理核心。 默认情况下,在没有此选项的情况下,静态策略使用拓扑感知的最佳匹配分配来分配 CPU。在启用 SMT 的系统上,该策略可以分配独立的虚拟核心,这些核心对应于硬件线程。这可能导致不同的容器共享相同的物理核心;这种行为反过来又会导致 “吵闹的邻居”问题。 启用此选项后,kubelet 仅在所有容器的 CPU 请求可以通过分配完整的物理核心来满足时,才会接纳 Pod。 如果 Pod 未通过准入,它将进入 Failed 状态,并显示消息 SMTAlignmentError

distribute-cpus-across-numa

如果指定了 distribute-cpus-across-numa 策略选项,在需要多个 NUMA 节点才能满足分配的情况下,静态策略将均匀地分配 CPU 到各个 NUMA 节点。 默认情况下,CPUManager 会将 CPU 尽可能地打包到一个 NUMA 节点上,直到该节点满载,任何剩余的 CPU 简单地溢出到下一个 NUMA 节点。这可能会在依赖屏障(和类似同步原语)的并行代码中造成不必要的瓶颈,因为这类代码往往只以最慢的 worker(由于至少一个 NUMA 节点上可用的 CPU 较少而变慢)的速度运行。通过在 NUMA 节点之间均匀分配 CPU,应用程序开发人员可以更容易地确保没有单个 worker 比其他 worker 更多地受到 NUMA 效应的影响,从而提高这些类型应用程序的整体性能。

align-by-socket

如果指定了 align-by-socket 策略选项,在决定如何为容器分配 CPU 时,将认为 CPU 在插槽边界对齐。 默认情况下,CPUManager 在 NUMA 边界对齐 CPU 分配,如果需要从多个 NUMA 节点获取 CPU 才能满足分配,这可能会导致性能下降。 尽管它尝试确保所有 CPU 都从**最少**数量的 NUMA 节点分配,但不能保证这些 NUMA 节点将在同一插槽上。 通过指示 CPUManager 明确地在插槽边界而不是 NUMA 边界对齐 CPU,我们能够避免此类问题。 请注意,此策略选项与 TopologyManagersingle-numa-node 策略不兼容,并且不适用于插槽数量大于 NUMA 节点数量的硬件。

distribute-cpus-across-cores

如果指定了 `distribute-cpus-across-cores` 策略选项,静态策略将尝试将虚拟核心(硬件线程)分配到不同的物理核心。 默认情况下,`CPUManager` 倾向于将 CPU 尽可能地打包到少数物理核心上,这可能导致相同物理核心上的 CPU 之间发生争用,并导致性能瓶颈。 通过启用 `distribute-cpus-across-cores` 策略,静态策略可确保 CPU 尽可能地分布在多个物理核心上,从而减少相同物理核心上的争用,从而提高整体性能。然而,需要注意的是,当系统负载过重时,此策略可能效果不佳。在这些条件下,减少争用的好处会减弱。 相反,默认行为有助于减少核心间通信开销,可能在高负载条件下提供更好的性能。

strict-cpu-reservation

KubeletConfiguration 中的 reservedSystemCPUs 参数,或已弃用的 kubelet 命令行选项 --reserved-cpus,为操作系统系统守护进程和 Kubernetes 系统守护进程定义了一个明确的 CPU 集合。 此参数的更多详细信息可以在 明确预留 CPU 列表 页面上找到。 默认情况下,这种隔离仅针对具有整数 CPU 请求的 Guaranteed Pod 实现,而不是针对 Burstable 和 BestEffort Pod(以及具有分数 CPU 请求的 Guaranteed Pod)。 准入仅比较 CPU 请求与可分配 CPU。 由于 CPU 限制高于请求,默认行为允许 Burstable 和 BestEffort Pod 使用 reservedSystemCPUs 的容量,并导致主机操作系统服务在实际部署中饿死。 如果启用了 strict-cpu-reservation 策略选项,静态策略将不允许任何工作负载使用 reservedSystemCPUs 中指定的 CPU 核心。

prefer-align-cpus-by-uncorecache

如果指定了 `prefer-align-cpus-by-uncorecache` 策略,静态策略将为单个容器分配 CPU 资源,使得分配给容器的所有 CPU 共享相同的非核心缓存块(也称为末级缓存或 LLC)。 默认情况下,`CPUManager` 将紧密打包 CPU 分配,这可能导致容器从多个非核心缓存中分配 CPU。 此选项使 `CPUManager` 能够以最大化非核心缓存有效利用率的方式分配 CPU。 分配是尽力而为的,旨在在相同的非核心缓存内关联尽可能多的 CPU。 如果容器的 CPU 需求超过单个非核心缓存的 CPU 容量,`CPUManager` 将最小化使用的非核心缓存数量,以保持最佳的非核心缓存对齐。 特定的工作负载可以从缓存级别的缓存间延迟和“吵闹的邻居”减少中受益。 如果 `CPUManager` 无法在节点资源充足的情况下进行最佳对齐,容器仍将使用默认的打包行为进行准入。

内存管理策略

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

Kubernetes **内存管理器(Memory Manager)**支持为 Guaranteed QoS 等级 中的 Pod 提供内存(和大页)保证分配的功能。

内存管理器采用提示生成协议来为 Pod 生成最合适的 NUMA 亲和性。 内存管理器将这些亲和性提示提供给中央管理器(**拓扑管理器(Topology Manager)**)。根据提示和拓扑管理器策略,Pod 被拒绝或准入到节点。

此外,内存管理器确保 Pod 请求的内存是从最少数量的 NUMA 节点分配的。

其他资源管理器

各个管理器的配置在专用文档中详细说明:

最后修改于 2025 年 7 月 2 日太平洋标准时间上午 11:16:node: 将 cpumanager prefer-align-cpus-by-uncorecache 升级到 Beta 版 (ed3d39a2ff)