Kubernetes 使用 podAntiAffinity 与 topologySpreadConstraints 跨节点传播 pod

Jus*_*tin 12 kubernetes kubernetes-deployment kubernetes-pod

我目前正在使用以下方法尝试将给定部署中的 Kubernetes Pod 均匀地分布在所有 Kubernetes 节点上:

    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              topologyKey: kubernetes.io/hostname
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - api
Run Code Online (Sandbox Code Playgroud)

然而,我注意到topologySpreadConstraintsKubernetes 最近添加了一个新属性。在 Kubernetes 部署中从使用切换affinity.podAntiAffinity到使用有什么优势?topologySpreadConstraints有什么理由要转行吗?该语法会是什么样子来匹配我目前在上面所做的事情?

zer*_*er0 33

概括

TL;DR - 切换到的优点topologySpreadConstraints是,您将能够更好地表达Pod 调度的底层基础topology设施structure。将此视为affinity可以做的事情的超集。

一个概念不能替代另一个概念,但两者都可以用于不同的目的。您可以组合pod/nodeAffinitytopologySpreadConstraints并且在调度 pod 时,Kubernetes 调度程序将对它们进行 AND 运算。简而言之,pod/nodeAffinity是针对线性拓扑(所有节点都在同一级别),并且topologySpreadConstraints是针对分层拓扑(节点分布在拓扑的逻辑域中)。当组合起来时,调度程序确保两者都得到尊重,并且两者都用于确保某些标准,例如应用程序的高可用性。

继续阅读了解更多详情!

亲和力与拓扑分布

affinities您可以根据(根据您的情况)决定您的nodes日程pods安排。node labelkubernetes.io/hostname

topologySpreadConstraints可以使用一组更广泛的标签来定义您nodes的. 因此,这是一个简单概念的概括,从逻辑上讲,所有节点都“处于同一拓扑级别”,并且在较小的规模上,这是管理 Pod 调度的简化视图。podstopology domainaffinity

一个例子

Atopology domain只是基础设施的一个逻辑单元。想象一下,您有一个包含 10 个节点的集群,这些节点在逻辑上处于同一级别,并且您的topology domain集群仅表示一个平面拓扑,其中所有这些节点都处于同一级别。

node1, node2, node3 ... node10
Run Code Online (Sandbox Code Playgroud)

现在,假设您的集群增长到拥有 20 个节点,其中 10 个节点位于一个可用区(在您的云提供商中),10 个节点位于另一个可用区。现在,您topology domain可以是一个可用区,因此,所有节点都不同一级别,您的拓扑现在已变为“多区域”,并且您现在有 20 个节点,其中 10 个在同一拓扑中,而不是在同一拓扑中拥有 20 个节点。每个拓扑域 (AZ)。

AZ1 => node1, node2, node3 ... node10
AZ2 => node11, node12, node13 ... node20
Run Code Online (Sandbox Code Playgroud)

想象一下,它进一步增长到 40 个节点,每个节点 20 个region,其中每个区域可以有 2 个 AZ(每个 10 个节点)。具有 2 种类型的“多区域”拓扑topology domains:AZ 和区域。现在看起来像:

Region1: => AZ1 => node1, node2, node3 ... node10
         => AZ2 => node11, node12, node13 ... node20
Region2: => AZ1 => node21, node22, node23 ... node30
         => AZ2 => node31, node32, node33 ... node40
Run Code Online (Sandbox Code Playgroud)

现在,这是一个想法。在调度工作负载 Pod 时,您希望调度程序了解提供 Kubernetes 节点的底层基础设施的拓扑。这可以是您自己的数据中心、云提供商等。这是因为您希望确保:

  1. 您在各个区域中获得相同数量的 Pod,因此您的多区域应用程序具有相似的容量。
  2. 您可以在一个区域内的可用区中拥有相同数量的 pod,这样可用区就不会过载。
  3. 您有扩展限制,您希望跨区域等量地扩展应用程序。

为了让 Kubernetes 调度程序了解您设置的底层拓扑,您可以使用topologySpreadConstraints告诉调度程序如何解释它看到的“节点列表”。因为请记住,对于调度程序来说,所有节点都只是节点的平面列表,没有拓扑的概念。您可以通过将特殊标签附加到称为标签的节点来构建拓扑topologyKey。例如,您将标记集群中的每个节点,以使 Kubernetes 调度程序了解您拥有哪种底层“拓扑”。喜欢,

node1 =>  az: 1, region: 1
...
node11 => az: 2, region: 1
...
node21 => az: 1, region: 2
...
node31 => az: 2, region: 2
Run Code Online (Sandbox Code Playgroud)

现在每个节点已被配置为“两个”拓扑域的一部分;每个节点必须位于 anAZ和 a 中Region。因此,您可以开始配置您的调度程序topologySpreadConstraints,使 pod 跨区域、可用区等(您的topology domains)分布并满足您的要求。

这是一个非常常见的用例,许多组织在其工作负载中实施这种用例,以确保应用程序在变得非常庞大并成为多区域时的高可用性。您可以topologySpreadConstraints 在此处阅读更多相关信息。