Kubernetes 1.31:podAffinity 中的 matchLabelKeys 进阶至 Beta

Kubernetes 1.29 在 podAffinitypodAntiAffinity 中引入了新的字段 matchLabelKeysmismatchLabelKeys

在 Kubernetes 1.31 中,此特性进阶至 Beta,并且相应的特性门控(MatchLabelKeysInPodAffinity)默认启用。

matchLabelKeys - 为多样化滚动更新增强了调度

在工作负载(例如 Deployment)的滚动更新期间,集群中可能同时存在多个版本的 Pod。
然而,调度器无法基于 podAffinitypodAntiAffinity 中指定的 labelSelector 区分新旧版本。 结果,调度器将并置或分散调度 Pod,不会考虑这些 Pod 的版本。

这可能导致次优的调度结果,例如:

  • 新版本的 Pod 与旧版本的 Pod(podAffinity)并置在一起,这些旧版本的 Pod 最终将在滚动更新后被移除。
  • 旧版本的 Pod 被分布在所有可用的拓扑中,导致新版本的 Pod 由于 podAntiAffinity 无法找到节点。

matchLabelKeys 是一组 Pod 标签键,可以解决上述问题。
调度器从新 Pod 的标签中查找这些键的值,并将其与 labelSelector 结合, 以便 podAffinity 匹配到具有相同标签键值的 Pod。

通过在 matchLabelKeys 中使用标签 pod-template-hash
你可以确保对 podAffinitypodAntiAffinity 进行评估时仅考虑相同版本的 Pod。

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

上述 Pod 中的 matchLabelKeys 将被转换为:

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 # 从 matchLabelKeys 添加; 只有来自同一 ReplicaSet 的 Pod 将与此亲和性匹配
            operator: In
            values:
            - xyz 
        topologyKey: topology.kubernetes.io/zone
        matchLabelKeys: 
        - pod-template-hash

mismatchLabelKeys - 服务隔离

mismatchLabelKeys 是一组 Pod 标签键,类似于 matchLabelKeys
它在新 Pod 的标签中查找这些键的值,并将其与 labelSelector 合并为 key notin (value), 以便 podAffinity 会匹配到具有相同标签键值的 Pod。

假设每个租户的所有 Pod 通过控制器或像 Helm 这样的清单管理工具得到 tenant 标签。

尽管在组合每个工作负载的清单时,tenant 标签的值是未知的,
但集群管理员希望实现租户与域之间形成排他性的 1:1 对应关系,以便隔离租户。

mismatchLabelKeys 适用于这一使用场景;
通过使用变更性质的 Webhook 在全局应用以下亲和性, 集群管理员可以确保来自同一租户的 Pod 将以独占方式落到同一域上,
这意味着来自其他租户的 Pod 不会落到同一域上。

affinity:
  podAffinity:      # 确保此租户的 Pod 落在同一节点池上
    requiredDuringSchedulingIgnoredDuringExecution:
    - matchLabelKeys:
        - tenant
      topologyKey: node-pool
  podAntiAffinity:  # 确保只有此租户的 Pod 落在同一节点池上
    requiredDuringSchedulingIgnoredDuringExecution:
    - mismatchLabelKeys:
        - tenant
      labelSelector:
        matchExpressions:
        - key: tenant
          operator: Exists
      topologyKey: node-pool

上述的 matchLabelKeysmismatchLabelKeys 将被转换为:

kind: Pod
metadata:
  name: application-server
  labels:
    tenant: service-a
spec: 
  affinity:
    podAffinity:      # 确保此租户的 Pod 落在同一节点池上
      requiredDuringSchedulingIgnoredDuringExecution:
      - matchLabelKeys:
          - tenant
        topologyKey: node-pool
        labelSelector:
          matchExpressions:
          - key: tenant
            operator: In
            values:
            - service-a 
    podAntiAffinity:  # 确保只有此租户的 Pod 落在同一节点池上
      requiredDuringSchedulingIgnoredDuringExecution:
      - mismatchLabelKeys:
          - tenant
        labelSelector:
          matchExpressions:
          - key: tenant
            operator: Exists
          - key: tenant
            operator: NotIn
            values:
            - service-a 
        topologyKey: node-pool

参与其中

这些特性由 Kubernetes SIG Scheduling 管理。

请加入我们并分享你的反馈。我们期待听到你的声音!

了解更多