本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes 1.31:PodAffinity 中的 MatchLabelKeys 进阶至 Beta
Kubernetes 1.29 在 podAffinity
和 podAntiAffinity
中引入了新的字段 matchLabelKeys
和 mismatchLabelKeys
。
在 Kubernetes 1.31 中,此功能进入 Beta 阶段,并且相应的功能门控(MatchLabelKeysInPodAffinity
)默认启用。
matchLabelKeys
- 增强调度以实现灵活的滚动更新
在工作负载(例如 Deployment)滚动更新期间,集群中可能同时存在多个版本的 Pod。然而,调度器无法根据 podAffinity
或 podAntiAffinity
中指定的 labelSelector
来区分新旧版本。因此,它会不分版本地将 Pod 部署在一起或分散开来。
这可能导致不理想的调度结果,例如:
- 新版本的 Pod 与旧版本的 Pod 部署在一起(
podAffinity
),而旧版本的 Pod 在滚动更新后最终会被移除。 - 旧版本的 Pod 分布在所有可用的拓扑域中,导致新版本的 Pod 因为
podAntiAffinity
规则而找不到合适的节点。
matchLabelKeys
是一组 Pod 标签键,用于解决此问题。调度器会从新 Pod 的标签中查找这些键的值,并将它们与 labelSelector
结合起来,这样 podAffinity 就能匹配那些在标签中具有相同键值的 Pod。
通过在 matchLabelKeys
中使用标签 pod-template-hash,你可以确保只有相同版本的 Pod 会被用于 podAffinity
或 podAntiAffinity
的评估。
apiVersion: apps/v1
kind: Deployment
metadata:
name: application-server
...
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- database
topologyKey: topology.kubernetes.io/zone
matchLabelKeys:
- pod-template-hash
上述 matchLabelKeys
在 Pod 中会被转换成类似下面的形式:
kind: Pod
metadata:
name: application-server
labels:
pod-template-hash: xyz
...
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- database
- key: pod-template-hash # Added from matchLabelKeys; Only Pods from the same replicaset will match this affinity.
operator: In
values:
- xyz
topologyKey: topology.kubernetes.io/zone
matchLabelKeys:
- pod-template-hash
mismatchLabelKeys
- 服务隔离
mismatchLabelKeys
是一组 Pod 标签键,与 matchLabelKeys
类似,它会从新 Pod 的标签中查找这些键的值,并将其作为 key notin (value)
合并到 labelSelector
中,以便 podAffinity
规则*不*匹配那些在标签中具有相同键值的 Pod。
假设每个租户的所有 Pod 都通过控制器或像 Helm 这样的清单管理工具获得了 tenant
标签。
尽管在编写每个工作负载的清单时 tenant
标签的值是未知的,但集群管理员希望为租户隔离实现独占的 1:1 租户到域的放置。
mismatchLabelKeys
在这种用例中非常有效;通过使用 Mutating Webhook 全局应用以下亲和性规则,集群管理员可以确保来自同一租户的 Pod 将被独占地部署到同一个域中,这意味着其他租户的 Pod 不会部署到该域中。
affinity:
podAffinity: # ensures the pods of this tenant land on the same node pool
requiredDuringSchedulingIgnoredDuringExecution:
- matchLabelKeys:
- tenant
topologyKey: node-pool
podAntiAffinity: # ensures only Pods from this tenant lands on the same node pool
requiredDuringSchedulingIgnoredDuringExecution:
- mismatchLabelKeys:
- tenant
labelSelector:
matchExpressions:
- key: tenant
operator: Exists
topologyKey: node-pool
上述 matchLabelKeys
和 mismatchLabelKeys
会被转换成类似下面的形式:
kind: Pod
metadata:
name: application-server
labels:
tenant: service-a
spec:
affinity:
podAffinity: # ensures the pods of this tenant land on the same node pool
requiredDuringSchedulingIgnoredDuringExecution:
- matchLabelKeys:
- tenant
topologyKey: node-pool
labelSelector:
matchExpressions:
- key: tenant
operator: In
values:
- service-a
podAntiAffinity: # ensures only Pods from this tenant lands on the same node pool
requiredDuringSchedulingIgnoredDuringExecution:
- mismatchLabelKeys:
- tenant
labelSelector:
matchExpressions:
- key: tenant
operator: Exists
- key: tenant
operator: NotIn
values:
- service-a
topologyKey: node-pool
参与进来
这些功能由 Kubernetes SIG Scheduling 管理。
请加入我们并分享你的反馈。我们期待你的回音!