控制节点上的拓扑管理策略
Kubernetes v1.27 [稳定]
越来越多的系统利用 CPU 和硬件加速器的组合来支持延迟关键型执行和高吞吐量并行计算。这些包括电信、科学计算、机器学习、金融服务和数据分析等领域的负载。这些混合系统构成了高性能环境。
为了提取最佳性能,需要与 CPU 隔离、内存和设备局部性相关的优化。但是,在 Kubernetes 中,这些优化由一组分离的组件处理。
拓扑管理器 是一个 Kubelet 组件,旨在协调负责这些优化的组件集。
在开始之前
您需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。建议在至少有两个节点(不充当控制平面主机)的集群上运行本教程。如果您还没有集群,可以使用 minikube 创建一个,或者您可以使用以下 Kubernetes 游乐场之一
您的 Kubernetes 服务器必须为 v1.18 或更高版本。要检查版本,请输入kubectl version
。拓扑管理器的工作原理
在引入拓扑管理器之前,Kubernetes 中的 CPU 和设备管理器独立地做出资源分配决策。这会导致在多插槽系统上出现不希望的分配,性能/延迟敏感型应用程序将因这些不希望的分配而受到影响。在这种情况下,不希望的分配是指例如,CPU 和设备从不同的 NUMA 节点分配,从而导致额外的延迟。
拓扑管理器是一个 Kubelet 组件,它充当真相来源,以便其他 Kubelet 组件可以做出与拓扑相关的资源分配选择。
拓扑管理器为组件提供了一个接口,称为提示提供程序,用于发送和接收拓扑信息。拓扑管理器有一组节点级策略,将在下面解释。
拓扑管理器从提示提供程序接收拓扑信息,作为表示可用 NUMA 节点的位掩码和首选分配指示。拓扑管理器策略对提供的提示执行一组操作,并收敛到由策略确定的提示,以给出最佳结果,如果存储了不希望的提示,则该提示的首选字段将设置为 false。在当前策略中,首选是范围最窄的首选掩码。选定的提示将存储为拓扑管理器的一部分。根据配置的策略,pod 可以根据选定的提示被节点接受或拒绝。然后,该提示将存储在拓扑管理器中,供提示提供程序在做出资源分配决策时使用。
拓扑管理器范围和策略
拓扑管理器目前
- 对齐所有 QoS 类别的 Pod。
- 对齐提示提供程序提供拓扑提示的请求资源。
如果满足这些条件,拓扑管理器将对齐请求的资源。
为了自定义如何执行此对齐,拓扑管理器提供了两个不同的旋钮:scope
和 policy
。
scope
定义了您希望执行资源对齐的粒度(例如,在pod
或container
级别)。而policy
定义了用于执行对齐的实际策略(例如,best-effort
、restricted
、single-numa-node
等)。有关今天可用的各种scope
和policy
的详细信息,请参见下文。
注意
要将 CPU 资源与 Pod Spec 中的其他请求资源对齐,应启用 CPU 管理器,并在节点上配置适当的 CPU 管理器策略。请参见 控制 CPU 管理策略。注意
要将内存(和巨页)资源与 Pod Spec 中的其他请求资源对齐,应启用内存管理器,并在节点上配置适当的内存管理器策略。查看 内存管理器 文档。拓扑管理器范围
拓扑管理器可以处理几个不同范围内的资源对齐
container
(默认)pod
可以在 kubelet 启动时选择其中一个选项,使用--topology-manager-scope
标志。
容器范围
container
范围是默认使用的范围。
在此范围内,拓扑管理器执行一系列顺序资源对齐,即,为每个容器(在 pod 中)计算单独的对齐。换句话说,对于此特定范围,没有将容器分组到特定 NUMA 节点的概念。实际上,拓扑管理器对单个容器到 NUMA 节点的任意对齐执行操作。
在以下范围内,故意认可并实现了将容器分组的概念,例如pod
范围。
pod 范围
要选择pod
范围,请使用命令行选项--topology-manager-scope=pod
启动 kubelet。
此范围允许将 pod 中的所有容器分组到一组通用的 NUMA 节点。也就是说,拓扑管理器将 pod 作为一个整体进行处理,并尝试将整个 pod(所有容器)分配到单个 NUMA 节点或一组通用的 NUMA 节点。以下示例说明了拓扑管理器在不同情况下产生的对齐方式
- 所有容器都可以分配到单个 NUMA 节点,并且确实分配到单个 NUMA 节点;
- 所有容器都可以分配到共享的 NUMA 节点集,并且确实分配到共享的 NUMA 节点集。
整个 pod 的特定资源需求总量是根据 有效请求/限制 公式计算的,因此,此总值等于
- 所有应用程序容器请求的总和,
- 初始化容器请求的最大值,
对于资源。
将pod
范围与single-numa-node
拓扑管理器策略结合使用对于对延迟敏感的负载或执行 IPC 的高吞吐量应用程序特别有价值。通过结合这两个选项,您可以将 pod 中的所有容器放置到单个 NUMA 节点上;因此,可以消除该 pod 的 NUMA 间通信开销。
在single-numa-node
策略的情况下,只有在可能的分配中存在合适的 NUMA 节点集时,才会接受 pod。重新考虑上面的例子
- 仅包含单个 NUMA 节点的集合 - 它会导致 pod 被接受,
- 而包含多个 NUMA 节点的集合 - 它会导致 pod 被拒绝(因为需要两个或多个 NUMA 节点来满足分配,而不是一个 NUMA 节点)。
总而言之,拓扑管理器首先计算一组 NUMA 节点,然后根据拓扑管理器策略对其进行测试,这会导致 pod 被拒绝或接受。
拓扑管理器策略
拓扑管理器支持四种分配策略。您可以通过 Kubelet 标志--topology-manager-policy
设置策略。有四种支持的策略
none
(默认)best-effort
restricted
single-numa-node
注意
如果拓扑管理器配置为pod 范围,则策略考虑的容器反映了整个 pod 的要求,因此 pod 中的每个容器都将产生相同的拓扑对齐决策。none 策略
这是默认策略,不执行任何拓扑对齐。
best-effort 策略
对于 Pod 中的每个容器,kubelet 使用best-effort
拓扑管理策略调用每个提示提供程序以发现其资源可用性。使用此信息,拓扑管理器存储该容器的首选 NUMA 节点亲和性。如果亲和性不是首选,拓扑管理器将存储此信息并仍然将 pod 接受到节点。
然后,提示提供程序可以在做出资源分配决策时使用此信息。
restricted 策略
对于 Pod 中的每个容器,kubelet 使用restricted
拓扑管理策略调用每个提示提供程序以发现其资源可用性。使用此信息,拓扑管理器存储该容器的首选 NUMA 节点亲和性。如果亲和性不是首选,拓扑管理器将拒绝该 pod 从节点。这将导致 pod 处于Terminated
状态,并出现 pod 准入失败。
一旦 pod 处于Terminated
状态,Kubernetes 调度程序将不会尝试重新调度该 pod。建议使用 ReplicaSet 或 Deployment 来触发 pod 的重新部署。也可以实现外部控制循环来触发具有拓扑亲和性
错误的 pod 的重新部署。
如果 Pod 被接纳,提示提供者 就可以在进行资源分配决策时使用这些信息。
single-numa-node 策略
对于 Pod 中的每个容器,kubelet 使用 single-numa-node
拓扑管理策略,调用每个提示提供者以发现其资源可用性。使用这些信息,拓扑管理器会确定是否可以进行单个 NUMA 节点亲和性。如果可以,拓扑管理器会存储此信息,并且提示提供者 可以在进行资源分配决策时使用这些信息。但是,如果无法进行单个 NUMA 节点亲和性,则拓扑管理器会拒绝 Pod 从节点进入。这将导致 Pod 处于 Terminated
状态,并出现 Pod 接纳失败。
一旦 Pod 处于 Terminated
状态,Kubernetes 调度器将不会尝试重新调度 Pod。建议使用具有副本的部署来触发 Pod 的重新部署。也可以实现外部控制循环来触发具有 Topology Affinity
错误的 Pod 的重新部署。
拓扑管理器策略选项
对拓扑管理器策略选项的支持需要启用 TopologyManagerPolicyOptions
特性门控(默认情况下已启用)。
您可以根据其成熟度级别,使用以下特性门控来打开或关闭选项组
TopologyManagerPolicyBetaOptions
默认启用。启用以显示 beta 级别的选项。TopologyManagerPolicyAlphaOptions
默认禁用。启用以显示 alpha 级别的选项。
您仍然需要使用 TopologyManagerPolicyOptions
kubelet 选项来启用每个选项。
以下策略选项存在
prefer-closest-numa-nodes
(beta,默认情况下可见;TopologyManagerPolicyOptions
和TopologyManagerPolicyBetaOptions
特性门控必须启用)。prefer-closest-numa-nodes
策略选项在 Kubernetes 1.30 中处于 beta 阶段。
如果指定了 prefer-closest-numa-nodes
策略选项,则 best-effort
和 restricted
策略在进行接纳决策时,将优先考虑 NUMA 节点集之间距离较短的节点集。您可以通过在拓扑管理器策略选项中添加 prefer-closest-numa-nodes=true
来启用此选项。默认情况下,如果没有此选项,拓扑管理器会在单个 NUMA 节点或最少数量的 NUMA 节点(在需要多个 NUMA 节点的情况下)上对齐资源。但是,TopologyManager
不了解 NUMA 距离,在进行接纳决策时不会考虑它们。此限制在多插槽系统以及单插槽多 NUMA 系统中出现,如果拓扑管理器决定在非相邻 NUMA 节点上对齐资源,则可能会导致延迟敏感型执行和高吞吐量应用程序的性能显著下降。
Pod 与拓扑管理器策略的交互
考虑以下 Pod 规范中的容器
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 类中运行,因为请求小于限制。
如果选择的策略不是 none
,则拓扑管理器会考虑这些 Pod 规范。拓扑管理器会咨询提示提供者以获取拓扑提示。在 static
的情况下,CPU 管理器策略将返回默认的拓扑提示,因为这些 Pod 没有显式请求 CPU 资源。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
requests:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
此具有整数 CPU 请求的 Pod 在 Guaranteed
QoS 类中运行,因为 requests
等于 limits
。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "300m"
example.com/device: "1"
requests:
memory: "200Mi"
cpu: "300m"
example.com/device: "1"
此具有共享 CPU 请求的 Pod 在 Guaranteed
QoS 类中运行,因为 requests
等于 limits
。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
example.com/deviceA: "1"
example.com/deviceB: "1"
requests:
example.com/deviceA: "1"
example.com/deviceB: "1"
此 Pod 在 BestEffort
QoS 类中运行,因为没有 CPU 和内存请求。
拓扑管理器会考虑上述 Pod。拓扑管理器会咨询提示提供者(即 CPU 和设备管理器)以获取 Pod 的拓扑提示。
在具有整数 CPU 请求的 Guaranteed
Pod 的情况下,static
CPU 管理器策略将返回与独占 CPU 相关的拓扑提示,而设备管理器将发送回请求设备的提示。
在具有共享 CPU 请求的 Guaranteed
Pod 的情况下,static
CPU 管理器策略将返回默认的拓扑提示,因为没有独占 CPU 请求,而设备管理器将发送回请求设备的提示。
在上述两种 Guaranteed
Pod 的情况下,none
CPU 管理器策略将返回默认的拓扑提示。
在 BestEffort
Pod 的情况下,static
CPU 管理器策略将发送回默认的拓扑提示,因为没有 CPU 请求,而设备管理器将发送回每个请求设备的提示。
使用这些信息,拓扑管理器会计算出 Pod 的最佳提示,并存储此信息,提示提供者在进行资源分配时会使用这些信息。
已知限制
拓扑管理器允许的最大 NUMA 节点数量为 8。如果 NUMA 节点数量超过 8,则在尝试枚举可能的 NUMA 亲和性并生成其提示时,将出现状态爆炸。
调度器不了解拓扑,因此有可能被调度到一个节点上,然后由于拓扑管理器而在这个节点上失败。