节点资源管理器
为了支持对延迟敏感和高吞吐量的工作负载,Kubernetes 提供了一套资源管理器。这些管理器旨在协调和优化节点资源,以满足对 CPU、设备和内存 (hugepages) 资源有特定需求的 Pod 的分配对齐。
硬件拓扑对齐策略
拓扑管理器 是一个 Kubelet 组件,旨在协调负责这些优化的组件集合。整个资源管理过程由你指定的策略控制。要了解更多信息,请阅读 控制节点上的拓扑管理策略。
为 Pod 分配 CPU 的策略
Kubernetes v1.26 [stable]
(默认启用: true)一旦 Pod 绑定到 Node,该节点上的 Kubelet 可能需要多路复用现有硬件(例如,跨多个 Pod 共享 CPU),或者通过专用某些资源来分配硬件(例如,为 Pod 独占使用分配一个或多个 CPU)。
默认情况下,Kubelet 使用 CFS quota 来执行 Pod CPU 限制。当节点运行许多 CPU 密集型 Pod 时,工作负载可以在不同的 CPU 核之间移动,这取决于 Pod 是否受到限制以及调度时哪些 CPU 核可用。许多工作负载对此类迁移不敏感,因此无需任何干预即可正常工作。
然而,在 CPU 缓存亲和性和调度延迟显著影响工作负载性能的场景中,Kubelet 允许采用备选的 CPU 管理策略来决定节点上的一些放置偏好。这是通过 CPU 管理器 及其策略来实现的。目前有两种可用策略:
none
:none
策略显式启用现有的默认 CPU 亲和性方案,除了操作系统调度器自动执行的亲和性外不提供额外亲和性。使用 CFS quota 对 Guaranteed Pod 和 Burstable Pod 的 CPU 使用进行限制。static
:static
策略允许 Guaranteed Pod 中那些请求了整数个 CPU 的容器独占访问节点上的 CPU。这种独占性通过 cpuset cgroup 控制器 实现。
说明
容器运行时和 Kubelet 本身等系统服务仍可在这些独占 CPU 上运行。独占性仅针对其他 Pod。CPU 管理器不支持在运行时离线和上线 CPU。
Static 策略
Static 策略支持更细粒度的 CPU 管理和独占 CPU 分配。此策略管理一个共享 CPU 池,该池最初包含节点上的所有 CPU。可独占分配的 CPU 数量等于节点 CPU 总数减去 Kubelet 配置设置的任何 CPU 预留。这些选项预留的 CPU 会以整数数量从初始共享池中按物理核心 ID 升序取出。这个共享池是 BestEffort 和 Burstable Pod 中所有容器运行的 CPU 集合。Guaranteed Pod 中那些请求了非整数个 CPU 的容器也在共享池中的 CPU 上运行。只有属于 Guaranteed Pod 且请求了整数个 CPU 的容器才被分配独占 CPU。
说明
启用 static 策略时,Kubelet 要求 CPU 预留大于零。这是因为零 CPU 预留会导致共享池变空。符合静态分配条件的 Guaranteed Pod 被调度到节点时,CPU 从共享池中移除并放置到容器的 cpuset 中。CFS quota 不用于限制这些容器的 CPU 使用,因为其使用已由调度域本身限制。换句话说,容器 cpuset 中的 CPU 数量等于 Pod Spec 中指定的整数 CPU limit
。这种静态分配增加了 CPU 亲和性,减少了因 CPU 密集型工作负载节流而引起的上下文切换。
考虑以下 Pod Spec 中的容器:
spec:
containers:
- name: nginx
image: nginx
上述 Pod 属于 BestEffort
QoS 类,因为没有指定资源 requests
或 limits
。它在共享池中运行。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
上述 Pod 属于 Burstable
QoS 类,因为资源 requests
不等于 limits
且未指定 cpu
quantity。它在共享池中运行。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "100Mi"
cpu: "1"
上述 Pod 属于 Burstable
QoS 类,因为资源 requests
不等于 limits
。它在共享池中运行。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "200Mi"
cpu: "2"
上述 Pod 属于 Guaranteed
QoS 类,因为 requests
等于 limits
。且容器 CPU 资源的 limit 是大于或等于一的整数。nginx
容器被分配了 2 个独占 CPU。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "1.5"
requests:
memory: "200Mi"
cpu: "1.5"
上述 Pod 属于 Guaranteed
QoS 类,因为 requests
等于 limits
。但容器 CPU 资源的 limit 是小数。它在共享池中运行。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
上述 Pod 属于 Guaranteed
QoS 类,因为只指定了 limits
,并且在未明确指定 requests
时,requests
被设置为等于 limits
。且容器 CPU 资源的 limit 是大于或等于一的整数。nginx
容器被分配了 2 个独占 CPU。
Static 策略选项
以下是 static CPU 管理策略的可用策略选项,按字母顺序列出:
align-by-socket
(alpha 特性,默认隐藏)- 按物理封装/插槽边界对齐 CPU,而不是按逻辑 NUMA 边界(从 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 特性,默认可见)- 阻止所有 Pod,无论其 QoS 类如何,在预留的 CPU 上运行(从 Kubernetes v1.32 版本可用)
prefer-align-cpus-by-uncorecache
(alpha 特性,默认隐藏)- 尽力按 Uncore(Last-Level)缓存边界对齐 CPU(从 Kubernetes v1.32 版本可用)
你可以使用以下 Feature Gate 根据选项的成熟度级别来启用或禁用成组的选项:
CPUManagerPolicyBetaOptions
(默认启用)。禁用以隐藏 beta 级别的选项。CPUManagerPolicyAlphaOptions
(默认禁用)。启用以显示 alpha 级别的选项。
你仍然需要在 Kubelet 配置文件中使用 cpuManagerPolicyOptions
字段来启用每个选项。
有关可配置的各个选项的更多详细信息,请继续阅读。
full-pcpus-only
如果指定了 full-pcpus-only
策略选项,static 策略将始终分配完整的物理核心。默认情况下,如果没有此选项,static 策略使用拓扑感知的最佳适配分配方式分配 CPU。在启用 SMT 的系统上,该策略可以分配单独的虚拟核心,这些虚拟核心对应于硬件线程。这可能导致不同的容器共享同一个物理核心;这种行为反过来会导致“吵闹的邻居”问题。启用此选项后,只有当 Pod 中所有容器的 CPU 请求可以通过分配完整的物理核心来满足时,Kubelet 才会接纳该 Pod。如果 Pod 未通过接纳,它将进入 Failed 状态并显示消息 SMTAlignmentError
。
distribute-cpus-across-numa
如果指定了 distribute-cpus-across-numa
策略选项,当需要多个 NUMA 节点来满足分配需求时,static 策略将把 CPU 平均分配到不同的 NUMA 节点上。默认情况下,CPUManager
会将 CPU 打包到单个 NUMA 节点上直到填满,剩余的 CPU 会简单地溢出到下一个 NUMA 节点。这可能导致依赖 barriers(以及类似的同步原语)的并行代码出现不期望的瓶颈,因为此类代码往往只能以其最慢的工作者速度运行(而最慢的工作者由于至少一个 NUMA 节点上可用 CPU 较少而变慢)。通过将 CPU 平均分配到 NUMA 节点上,应用程序开发人员可以更容易地确保没有哪个工作者比其他工作者受到更多的 NUMA 影响,从而提高这类应用程序的整体性能。
align-by-socket
如果指定了 align-by-socket
策略选项,在决定如何为容器分配 CPU 时,CPU 将被视为在 socket 边界对齐。默认情况下,CPUManager
在 NUMA 边界对齐 CPU 分配,如果需要从多个 NUMA 节点提取 CPU 来满足分配需求,这可能导致性能下降。尽管它会尽量确保所有 CPU 都从最少数量的 NUMA 节点分配,但不能保证这些 NUMA 节点位于同一个 socket 上。通过指示 CPUManager
明确在 socket 边界而不是 NUMA 边界对齐 CPU,我们可以避免此类问题。注意,此策略选项与 TopologyManager
的 single-numa-node
策略不兼容,并且不适用于 socket 数量大于 NUMA 节点数量的硬件。
distribute-cpus-across-cores
如果指定了 distribute-cpus-across-cores
策略选项,static 策略将尝试将虚拟核心(硬件线程)分配到不同的物理核心上。默认情况下,CPUManager
倾向于将 CPU 打包到尽可能少的物理核心上,这可能导致同一物理核心上的 CPU 之间发生争用,从而导致性能瓶颈。通过启用 distribute-cpus-across-cores
策略,static 策略确保 CPU 分布在尽可能多的物理核心上,从而减少同一物理核心上的争用,进而提高整体性能。然而,需要注意的是,当系统负载很重时,这种策略可能效果不佳。在这种情况下,减少争用的好处会减少。相反,默认行为有助于减少核心间通信开销,可能在高负载条件下提供更好的性能。
strict-cpu-reservation
KubeletConfiguration
中的 reservedSystemCPUs
参数,或者已被弃用的 kubelet 命令行选项 --reserved-cpus
,为操作系统系统守护进程和 Kubernetes 系统守护进程定义了一个明确的 CPU 集合。该参数的更多详细信息可以在明确预留的 CPU 列表页面上找到。默认情况下,这种隔离仅针对请求整数个 CPU 的 guaranteed pod 实现,而不针对 burstable 和 best-effort pod(以及请求非整数个 CPU 的 guaranteed pod)。接纳阶段只比较 CPU 请求与可分配的 CPU。由于 CPU limit 高于请求,默认行为允许 burstable 和 best-effort pod 耗尽 reservedSystemCPUs
的容量,并在实际部署中导致主机 OS 服务饥饿。如果启用了 strict-cpu-reservation
策略选项,static 策略将不允许任何工作负载使用 reservedSystemCPUs
中指定的 CPU 核。
prefer-align-cpus-by-uncorecache
如果指定了 prefer-align-cpus-by-uncorecache
策略,static 策略将为单个容器分配 CPU 资源,使得分配给容器的所有 CPU 共享同一个 uncore 缓存块(也称为 Last-Level Cache 或 LLC)。默认情况下,CPUManager
会紧密打包 CPU 分配,这可能导致容器被分配来自多个 uncore 缓存的 CPU。此选项使 CPUManager
能够以最大化高效利用 uncore 缓存的方式分配 CPU。分配是尽力而为的,旨在在同一 uncore 缓存内亲和尽可能多的 CPU。如果容器的 CPU 需求超过单个 uncore 缓存的 CPU 容量,CPUManager
会最小化使用的 uncore 缓存数量,以维持最佳的 uncore 缓存对齐。特定工作负载可以从减少缓存级别的缓存间延迟和“吵闹的邻居”中获得性能提升。如果在节点资源充足的情况下 CPUManager
无法实现最佳对齐,容器仍将使用默认的打包行为被接纳。
内存管理策略
Kubernetes v1.32 [stable]
(默认启用: true)Kubernetes 内存管理器 为处于 Guaranteed
QoS 类的 Pod 提供了有保证的内存(以及 hugepages)分配功能。
内存管理器采用提示生成协议,为 Pod 生成最合适的 NUMA 亲和性。内存管理器将这些亲和性提示提供给中心管理器(拓扑管理器)。根据提示和拓扑管理器策略,Pod 被拒绝或接纳到节点。
此外,内存管理器确保 Pod 请求的内存在最少数量的 NUMA 节点上分配。
其他资源管理器
各个管理器的配置在专用文档中详细阐述: