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

Kubernetes 1.27:更精細的 Pod 拓撲分散策略已達 Beta 階段

在 Kubernetes v1.19 中,「Pod 拓撲分散約束」已正式發布 (GA)。

隨著時間推移,我們 - SIG Scheduling - 收到了使用者的回饋,因此,我們正積極透過三個 KEP 來改進拓撲分散功能。所有這些功能都已在 Kubernetes v1.27 中達到 Beta 版,並且預設為啟用。

這篇部落格文章介紹了每個功能以及每個功能背後的使用案例。

KEP-3022:Pod 拓撲分散中的最小網域數

Pod 拓撲分散具有 maxSkew 參數,用於定義 Pod 不均勻分散的程度。

但是,沒有辦法控制我們應該分散到的網域數量。有些使用者希望強制將 Pod 分散到最少數量的網域,如果目前沒有足夠的網域,則讓叢集自動擴展器佈建它們。

Kubernetes v1.24 引入了 minDomains 參數作為 Pod 拓撲分散約束的 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 中引入了兩個新欄位,以定義節點包含策略:nodeAffinityPolicynodeTaintPolicy

應用這些策略的 Manifest 看起來像這樣

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 的 nodeAffinitynodeSelector 以進行 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 群組上計算分散。當將拓撲分散與 Deployment 搭配使用時,常見的做法是使用 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。管理推出的控制器或運營商只需要為不同修訂版本在相同的標籤鍵上設定不同的值。排程器將根據 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 Scheduling 管理。

請加入我們並分享您的回饋。我們期待收到您的來信!

我如何了解更多資訊?