本文发表已超过一年。较早的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes 1.27:更细粒度的 Pod 拓扑分布策略进入 Beta 阶段
在 Kubernetes v1.19 中,Pod 拓扑分布约束已正式发布 (GA)。
随着时间的推移,我们 - SIG 调度 - 收到了用户的反馈,因此,我们正在积极地通过三个 KEP 来改进拓扑分布功能。所有这些功能在 Kubernetes v1.27 中都已达到 Beta 版,并且默认启用。
这篇博文介绍了每个功能及其背后的用例。
KEP-3022:Pod 拓扑分布中的最小域
Pod 拓扑分布具有 maxSkew
参数来定义 Pod 可能分布不均的程度。
但是,没有办法控制我们应该在其上分布的域的数量。一些用户希望强制将 Pod 分布在最少数量的域上,如果当前没有足够的域,则让集群自动扩缩器配置它们。
Kubernetes v1.24 为 pod 拓扑分布约束引入了 minDomains
参数,作为 alpha 功能。通过 minDomains
参数,您可以定义最小域数。
例如,假设有 3 个节点具有足够的容量,并且新创建的 ReplicaSet 的 Pod 模板中具有以下 topologySpreadConstraints
。
...
topologySpreadConstraints:
- maxSkew: 1
minDomains: 5 # requires 5 Nodes at least (because each Node has a unique hostname).
whenUnsatisfiable: DoNotSchedule # minDomains is valid only when DoNotSchedule is used.
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
foo: bar
在这种情况下,3 个 Pod 将被调度到这 3 个节点,但是此副本集中的其他 2 个 Pod 将无法调度,直到有更多节点加入集群。
您可以想象,集群自动扩缩器会根据这些无法调度的 Pod 配置新节点,因此,副本最终会分布在 5 个节点上。
KEP-3094:在计算 podTopologySpread 倾斜时考虑污点/容忍
在此增强之前,当您部署配置了 podTopologySpread
的 pod 时,kube-scheduler 会考虑满足 Pod 的 nodeAffinity 和 nodeSelector 的节点进行过滤和评分,但不会关心节点污点是否被传入的 pod 容忍。 这可能导致具有不容忍污点的节点成为唯一用于分布的候选者,因此,如果 pod 不容忍污点,则该 pod 将卡在 Pending 状态。
为了允许更精细地决定在计算分布倾斜时考虑哪些节点,Kubernetes 1.25 在 topologySpreadConstraints
中引入了两个新字段来定义节点包含策略:nodeAffinityPolicy
和 nodeTaintPolicy
。
应用这些策略的清单如下所示
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
# Configure a topology spread constraint
topologySpreadConstraints:
- maxSkew: <integer>
# ...
nodeAffinityPolicy: [Honor|Ignore]
nodeTaintsPolicy: [Honor|Ignore]
# other Pod fields go here
nodeAffinityPolicy
字段指示 Kubernetes 如何处理 Pod 的 nodeAffinity
或 nodeSelector
以进行 pod 拓扑分布。 如果为 Honor
,则 kube-scheduler 会在计算分布倾斜时过滤掉与 nodeAffinity
/nodeSelector
不匹配的节点。 如果为 Ignore
,则将包括所有节点,无论它们是否与 Pod 的 nodeAffinity
/nodeSelector
匹配。
为了向后兼容,nodeAffinityPolicy
默认为 Honor
。
nodeTaintsPolicy
字段定义 Kubernetes 如何考虑节点污点以进行 pod 拓扑分布。 如果为 Honor
,则仅包含传入 pod 具有容忍的受污节点,将包含在分布倾斜的计算中。 如果为 Ignore
,则 kube-scheduler 在计算分布倾斜时将完全不考虑节点污点,因此,还将包括具有 pod 不容忍污点的节点。
为了向后兼容,nodeTaintsPolicy
默认为 Ignore
。
该功能在 v1.25 中作为 alpha 功能引入。默认情况下,它是禁用的,因此,如果您想在 v1.25 中使用此功能,则必须显式启用功能门 NodeInclusionPolicyInPodTopologySpread
。在接下来的 v1.26 版本中,关联的功能已升级到 beta 版,并且默认启用。
KEP-3243:在滚动升级后遵守 Pod 拓扑分布
Pod 拓扑分布使用字段 labelSelector
来标识将计算分布的 pod 组。 当将拓扑分布与 Deployments 一起使用时,通常的做法是使用 Deployment 的 labelSelector
作为拓扑分布约束中的 labelSelector
。 但是,这意味着 Deployment 的所有 pod 都是分布计算的一部分,无论它们是否属于不同的修订版。 因此,当新的修订版推出时,分布将应用于来自旧的和新的 ReplicaSet 的 pod,因此,当新的 ReplicaSet 完全推出并且旧的 ReplicaSet 回滚时,我们剩下的实际分布可能与预期不符,因为来自较旧 ReplicaSet 的已删除 pod 会导致其余 pod 的分布倾斜。 为了避免此问题,过去用户需要在 Deployment 中添加修订版标签,并在每次滚动升级时手动更新它(包括 pod 模板上的标签和 topologySpreadConstraints
中的 labelSelector
)。
为了使用更简单的 API 解决此问题,Kubernetes v1.25 在 topologySpreadConstraints
中引入了一个名为 matchLabelKeys
的新字段。 matchLabelKeys
是 pod 标签键的列表,用于选择将计算分布的 pod。 这些键用于查找正在调度的 Pod 的标签中的值,这些键值标签与 labelSelector
进行 AND 运算,以选择将为传入 pod 计算分布的现有 pod 组。
使用 matchLabelKeys
,您无需在不同的修订版之间更新 pod.spec
。 管理 rollouts 的控制器或操作员只需要为不同修订版的相同标签键设置不同的值。 调度程序将根据 matchLabelKeys
自动假定这些值。 例如,如果您正在配置 Deployment,则可以使用带有 pod-template-hash 键的标签,该标签由 Deployment 控制器自动添加,以区分单个 Deployment 中的不同修订版。
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: foo
matchLabelKeys:
- pod-template-hash
参与其中
这些功能由 Kubernetes SIG 调度管理。
请加入我们并分享您的反馈。我们期待收到您的来信!