在节点上控制拓扑管理策略

特性状态: Kubernetes v1.27 [稳定]

越来越多的系统利用 CPU 和硬件加速器的组合来支持延迟敏感的执行和高吞吐量的并行计算。其中包括电信、科学计算、机器学习、金融服务和数据分析等领域的工作负载。这种混合系统构成了一个高性能环境。

为了获得最佳性能,需要进行与 CPU 隔离、内存和设备局部性相关的优化。然而,在 Kubernetes 中,这些优化由一组不相关的组件处理。

拓扑管理器是 kubelet 组件,旨在协调负责这些优化的一组组件。

开始之前

你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与你的集群通信。建议在至少有两个不充当控制平面主机的节点的集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个集群,或者可以使用以下 Kubernetes 游乐场之一

你的 Kubernetes 服务器必须是 v1.18 或更高版本。要检查版本,请输入 kubectl version

拓扑管理器的工作原理

在引入拓扑管理器之前,Kubernetes 中的 CPU 和设备管理器彼此独立地做出资源分配决策。这可能会导致在多插槽系统上出现不良分配,并且对性能/延迟敏感的应用程序将因这些不良分配而受到影响。此处的不良分配意味着,例如,从不同的 NUMA 节点分配 CPU 和设备,从而导致额外的延迟。

拓扑管理器是一个 kubelet 组件,它充当事实来源,以便其他 kubelet 组件可以做出拓扑对齐的资源分配选择。

拓扑管理器为组件(称为提示提供程序)提供接口,以发送和接收拓扑信息。拓扑管理器有一组节点级策略,这些策略将在下面进行解释。

拓扑管理器从提示提供程序接收拓扑信息,该信息是一个位掩码,表示可用的 NUMA 节点和一个首选的分配指示。拓扑管理器策略对提供的提示执行一组操作,并收敛到策略确定的提示,以提供最佳结果。如果存储了不良提示,则该提示的首选字段将设置为 false。在当前策略中,首选是最窄的首选掩码。所选提示作为拓扑管理器的一部分存储。根据配置的策略,可以根据所选提示从节点接受或拒绝 Pod。然后,将该提示存储在拓扑管理器中,供提示提供程序在做出资源分配决策时使用。

Windows 支持

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

可以通过使用 WindowsCPUAndMemoryAffinity 特性门控在 Windows 上启用拓扑管理器支持,并且它需要在容器运行时中提供支持。

拓扑管理器作用域和策略

拓扑管理器当前

  • 对齐所有 QoS 类的 Pod。
  • 对齐提示提供程序提供拓扑提示的请求资源。

如果满足这些条件,拓扑管理器将对齐请求的资源。

为了自定义如何执行此对齐,拓扑管理器提供了两个不同的选项:scopepolicy

scope 定义你希望执行资源对齐的粒度,例如,在 podcontainer 级别。policy 定义用于执行对齐的实际策略,例如,best-effortrestrictedsingle-numa-node。有关当前可用的各种 scopepolicy 的详细信息,请参见下文。

拓扑管理器作用域

拓扑管理器可以处理几个不同作用域中的资源对齐

  • container(默认)
  • pod

可以通过在kubelet 配置文件中设置 topologyManagerScope,在 kubelet 启动时选择任一选项。

container 作用域

默认情况下使用 container 作用域。你也可以在kubelet 配置文件中将 topologyManagerScope 显式设置为 container

在此作用域内,拓扑管理器执行多个连续的资源对齐,即,对于每个容器(在一个 Pod 中),计算单独的对齐。换句话说,对于此特定作用域,没有将容器分组到一组特定 NUMA 节点的概念。实际上,拓扑管理器对各个容器执行到 NUMA 节点的任意对齐。

为了支持将容器分组的概念,在以下作用域(例如 pod 作用域)中有意地实施了此概念。

pod 作用域

要选择 pod 作用域,请在kubelet 配置文件中将 topologyManagerScope 设置为 pod

此作用域允许将 Pod 中的所有容器分组到一组公共的 NUMA 节点。也就是说,拓扑管理器将 Pod 视为一个整体,并尝试将整个 Pod(所有容器)分配给单个 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

none 策略

这是默认策略,不执行任何拓扑对齐。

best-effort 策略

对于 Pod 中的每个容器,kubelet 在使用 best-effort 拓扑管理策略时,会调用每个 Hint Provider 来发现它们的资源可用性。利用这些信息,拓扑管理器会存储该容器的首选 NUMA 节点亲和性。如果亲和性不是首选的,拓扑管理器会存储此信息,但仍然允许 Pod 进入节点。

Hint Providers 可以在做出资源分配决策时使用此信息。

restricted 策略

对于 Pod 中的每个容器,kubelet 在使用 restricted 拓扑管理策略时,会调用每个 Hint Provider 来发现它们的资源可用性。利用这些信息,拓扑管理器会存储该容器的首选 NUMA 节点亲和性。如果亲和性不是首选的,拓扑管理器将拒绝该 Pod 进入节点。这将导致 Pod 进入 Terminated 状态,并出现 Pod 准入失败。

一旦 Pod 进入 Terminated 状态,Kubernetes 调度器将不会尝试重新调度该 Pod。建议使用 ReplicaSet 或 Deployment 来触发 Pod 的重新部署。也可以实现外部控制循环来触发具有 Topology Affinity 错误的 Pod 的重新部署。

如果 Pod 被允许进入,那么 Hint Providers 可以在做出资源分配决策时使用此信息。

single-numa-node 策略

对于 Pod 中的每个容器,kubelet 在使用 single-numa-node 拓扑管理策略时,会调用每个 Hint Provider 来发现它们的资源可用性。利用这些信息,拓扑管理器会确定是否可以实现单一 NUMA 节点亲和性。如果可以,拓扑管理器将存储此信息,并且 Hint Providers 可以在做出资源分配决策时使用此信息。但是,如果这不可能,则拓扑管理器将拒绝该 Pod 进入节点。这将导致 Pod 进入 Terminated 状态,并出现 Pod 准入失败。

一旦 Pod 进入 Terminated 状态,Kubernetes 调度器将不会尝试重新调度该 Pod。建议使用带有副本的 Deployment 来触发 Pod 的重新部署。也可以实现外部控制循环来触发具有 Topology Affinity 错误的 Pod 的重新部署。

拓扑管理器策略选项

对拓扑管理器策略选项的支持需要启用 TopologyManagerPolicyOptions 特性门控(默认情况下已启用)。

您可以根据其成熟度级别,使用以下特性门控来切换各组选项的启用和禁用状态

  • TopologyManagerPolicyBetaOptions 默认启用。启用后显示 Beta 级别的选项。
  • TopologyManagerPolicyAlphaOptions 默认禁用。启用后显示 Alpha 级别的选项。

您仍然必须使用 TopologyManagerPolicyOptions kubelet 选项来启用每个选项。

prefer-closest-numa-nodes

prefer-closest-numa-nodes 选项自 Kubernetes 1.32 起为 GA。在 Kubernetes 1.32 中,只要启用了 TopologyManagerPolicyOptions 特性门控,默认情况下此策略选项是可见的。

默认情况下,拓扑管理器不了解 NUMA 距离,并且在做出 Pod 准入决策时不会考虑它们。此限制在多插槽以及单插槽多 NUMA 系统中都会出现,并且如果拓扑管理器决定将资源对齐在非相邻的 NUMA 节点上,则可能导致延迟敏感型执行和高吞吐量应用程序的性能显著下降。

如果您指定 prefer-closest-numa-nodes 策略选项,则 best-effortrestricted 策略在做出准入决策时会倾向于选择彼此之间距离较短的 NUMA 节点集。

您可以通过将 prefer-closest-numa-nodes=true 添加到拓扑管理器策略选项来启用此选项。

默认情况下(没有此选项),拓扑管理器会将资源对齐在单个 NUMA 节点上,或者在需要多个 NUMA 节点的情况下,使用最少数量的 NUMA 节点。

max-allowable-numa-nodes (beta)

max-allowable-numa-nodes 选项自 Kubernetes 1.31 起为 Beta 版本。在 Kubernetes 1.32 中,只要启用了 TopologyManagerPolicyOptionsTopologyManagerPolicyBetaOptions 特性门控,默认情况下此策略选项是可见的。

准入 Pod 的时间与物理机器上的 NUMA 节点数量相关。默认情况下,Kubernetes 不会在检测到超过 8 个 NUMA 节点的任何(Kubernetes)节点上运行启用拓扑管理器的 kubelet。

您可以通过将 max-allowable-numa-nodes=true 添加到拓扑管理器策略选项来启用此选项。

设置 max-allowable-numa-nodes 的值本身不会影响 Pod 准入的延迟,但是将 Pod 绑定到具有许多 NUMA 的(Kubernetes)节点确实会产生影响。未来,Kubernetes 的潜在改进可能会提高 Pod 准入性能,并改善随着 NUMA 节点数量增加而出现的高延迟问题。

Pod 与拓扑管理器策略的交互

考虑以下 Pod 清单中的容器

spec:
  containers:
  - name: nginx
    image: nginx

此 Pod 在 BestEffort QoS 类中运行,因为未指定任何资源 requestslimits

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

此 Pod 在 Burstable QoS 类中运行,因为 requests 小于 limits。

如果选择的策略不是 none,拓扑管理器将考虑这些 Pod 规范。拓扑管理器将咨询 Hint Providers 以获取拓扑提示。在 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。拓扑管理器将咨询 Hint Providers,即 CPU 和设备管理器,以获取 Pod 的拓扑提示。

对于具有整数 CPU 请求的 Guaranteed Pod,static CPU 管理器策略将返回与独占 CPU 相关的拓扑提示,设备管理器将返回所请求设备的提示。

对于具有共享 CPU 请求的 Guaranteed Pod,由于没有独占 CPU 请求,static CPU 管理器策略将返回默认拓扑提示,设备管理器将返回所请求设备的提示。

在上述两个 Guaranteed Pod 的案例中,none CPU 管理器策略将返回默认拓扑提示。

对于 BestEffort Pod,由于没有 CPU 请求,static CPU 管理器策略将返回默认拓扑提示,设备管理器将返回每个请求设备的提示。

使用此信息,拓扑管理器计算 Pod 的最佳提示并存储此信息,Hint Providers 在进行资源分配时将使用该信息。

已知限制

  1. 拓扑管理器允许的最大 NUMA 节点数为 8。当尝试枚举可能的 NUMA 亲和性并生成它们的提示时,超过 8 个 NUMA 节点会导致状态爆炸。有关更多选项,请参阅 max-allowable-numa-nodes (beta)。

  2. 调度器不感知拓扑,因此可能会被调度到某个节点上,然后由于拓扑管理器而在该节点上失败。

上次修改时间:2024 年 11 月 21 日下午 7:38 PST:更新 content/en/docs/tasks/administer-cluster/topology-manager.md (7f411ed891)