<aside> ⏰
本文主要介绍调度器中的调度插件 PodTopologySpread 的工作原理。
</aside>
在 k8s 集群调度中,“亲和性”相关的概念本质上都是控制 Pod 如何被调度——**堆叠或是打散。**目前 k8s 提供了 podAffinity
以及 podAntiAffinity
两个特性对 Pod 在不同拓扑域的分布进行了一些控制,podAffinity 可以将无数个 Pod 调度到特定的某一个拓扑域,这是堆叠的体现;podAntiAffinity 则可以控制一个拓扑域只存在一个 Pod,这是打散的体现。但这两种情况都太极端了,在不少场景下都无法达到理想的效果,例如为了实现容灾和高可用,将业务 Pod 尽可能均匀的分布在不同可用区就很难实现。
PodTopologySpread
特性的提出正是为了对 Pod 的调度分布提供更精细的控制,以提高服务可用性以及资源利用率,PodTopologySpread 由 EvenPodsSpread
特性门所控制,在 v1.16 版本第一次发布,并在 v1.18 版本进入 beta 阶段默认启用。再了解这个插件是如何实现之前,我们首先需要搞清楚这个特性是如何使用的。
在 Pod 的 Spec 规范中新增了一个 topologySpreadConstraints
字段:
spec:
topologySpreadConstraints:
- maxSkew: <integer>
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
由于这个新增的字段是在 Pod spec 层面添加,因此更高层级的控制 (Deployment、DaemonSet、StatefulSet) 也能使用 PodTopologySpread
功能。
让我们结合上图来理解 topologySpreadConstraints
中各个字段的含义和作用:
app:foo
,那么 zone1 的匹配个数为 2, zone2 的匹配个数为 0。zone=zone1
标签的 Node 被分在一个拓扑域,具有 zone=zone2
标签的 Node 被分在另一个拓扑域。skew[i] = 拓扑域[i]中匹配的 Pod 个数 - min{其他拓扑域中匹配的 Pod 个数}
。在上图中,我们新建一个带有 app=foo
标签的 Pod:
下面我们用两个实际的示例来进一步说明。
假设你拥有一个 4 节点集群,其中标记为 foo:bar
的 3 个 Pod 分别位于 node1、node2 和 node3 中:
如果希望新来的 Pod 均匀分布在现有的可用区域,则可以按如下设置其约束: