这篇文章已经一年多了,较旧的文章可能包含过时的内容。请检查从发表以来,页面中的信息是否变得不正确。
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 与旧版本的 Pod(podAffinity)并置在一起,这些旧版本的 Pod 最终将在滚动更新后被移除。
- 旧版本的 Pod 被分布在所有可用的拓扑中,导致新版本的 Pod 由于 podAntiAffinity无法找到节点。
matchLabelKeys 是一组 Pod 标签键,可以解决上述问题。
调度器从新 Pod 的标签中查找这些键的值,并将其与 labelSelector 结合,
以便 podAffinity 匹配到具有相同标签键值的 Pod。
通过在 matchLabelKeys 中使用标签
pod-template-hash,
你可以确保对 podAffinity 或 podAntiAffinity 进行评估时仅考虑相同版本的 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
上述的 matchLabelKeys 和 mismatchLabelKeys 将被转换为:
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 管理。
请加入我们并分享你的反馈。我们期待听到你的声音!