本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

Kubernetes 1.31:PodAffinity 中的 MatchLabelKeys 進階至 Beta

Kubernetes 1.29 在 podAffinitypodAntiAffinity 中引入了新的欄位 matchLabelKeysmismatchLabelKeys

在 Kubernetes 1.31 中,此功能進入 Beta 階段,並且相應的功能門控(MatchLabelKeysInPodAffinity)預設啟用。

matchLabelKeys - 增強排程以實現靈活的滾動更新

在工作負載(例如 Deployment)滾動更新期間,叢集中可能同時存在多個版本的 Pod。然而,排程器無法根據 podAffinitypodAntiAffinity 中指定的 labelSelector 來區分新舊版本。因此,它會不分版本地將 Pod 部署在一起或分散開來。

這可能導致不理想的排程結果,例如:

  • 新版本的 Pod 與舊版本的 Pod 部署在一起(podAffinity),而舊版本的 Pod 在滾動更新後最終會被移除。
  • 舊版本的 Pod 分佈在所有可用的拓撲域中,導致新版本的 Pod 因為 podAntiAffinity 規則而找不到合適的節點。

matchLabelKeys 是一組 Pod 標籤鍵,用於解決此問題。排程器會從新 Pod 的標籤中查詢這些鍵的值,並將它們與 labelSelector 結合起來,這樣 podAffinity 就能匹配那些在標籤中具有相同鍵值的 Pod。

透過在 matchLabelKeys 中使用標籤 pod-template-hash,你可以確保只有相同版本的 Pod 會被用於 podAffinitypodAntiAffinity 的評估。

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

上述 matchLabelKeysmismatchLabelKeys 會被轉換成類似下面的形式:

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 管理。

請加入我們並分享你的反饋。我們期待你的迴音!

我如何瞭解更多資訊?