為你的應用程式指定中斷預算

功能狀態: Kubernetes v1.21 [穩定]

本頁說明如何限制您的應用程式所經歷的並行中斷次數,以便在允許叢集管理員管理叢集節點的同時,實現更高的可用性。

準備開始

您的 Kubernetes 伺服器版本必須為 v1.21 或更新版本。若要檢查版本,請輸入 kubectl version

使用 PodDisruptionBudget 保護應用程式

  1. 識別您要使用 PodDisruptionBudget (PDB) 保護的應用程式。
  2. 思考您的應用程式如何應對中斷。
  3. 以 YAML 檔案建立 PDB 定義。
  4. 從 YAML 檔案建立 PDB 物件。

識別要保護的應用程式

當您想要保護由其中一個內建 Kubernetes 控制器指定的應用程式時,最常見的使用案例

  • Deployment
  • ReplicationController
  • ReplicaSet
  • StatefulSet

在這種情況下,請記下控制器的 .spec.selector;相同的選擇器會進入 PDB 的 .spec.selector

從 1.15 版開始,PDB 支援自訂控制器,其中擴充子資源已啟用。

您也可以將 PDB 與非由上述控制器之一控制的 Pod,或任意 Pod 群組一起使用,但有一些限制,詳述於任意工作負載和任意選擇器

思考您的應用程式如何應對中斷

決定在自願性中斷期間,短時間內可以有多少個執行個體關閉。

  • 無狀態前端
    • 考量:服務容量的降幅不要超過 10%。
      • 解決方案:例如,使用 minAvailable 為 90% 的 PDB。
  • 單一執行個體具狀態應用程式
    • 考量:未經我的同意,請勿終止此應用程式。
      • 可能的解決方案 1:不要使用 PDB 並容忍偶爾的停機時間。
      • 可能的解決方案 2:設定 maxUnavailable=0 的 PDB。與叢集操作員達成共識 (在 Kubernetes 之外),在終止之前需要諮詢您。當叢集操作員與您聯絡時,請為停機時間做好準備,然後刪除 PDB 以表明已準備好進行中斷。之後重新建立。
  • 多個執行個體具狀態應用程式,例如 Consul、ZooKeeper 或 etcd
    • 考量:不要將執行個體數量減少到仲裁數以下,否則寫入會失敗。
      • 可能的解決方案 1:將 maxUnavailable 設定為 1 (適用於應用程式的不同規模)。
      • 可能的解決方案 2:將 minAvailable 設定為仲裁大小 (例如,當規模為 5 時為 3)。(允許更多同時發生的中斷)。
  • 可重新啟動的批次工作
    • 考量:在發生自願性中斷時,工作需要完成。
      • 可能的解決方案:不要建立 PDB。Job 控制器將建立一個替換 Pod。

指定百分比時的四捨五入邏輯

minAvailablemaxUnavailable 的值可以表示為整數或百分比。

  • 當您指定整數時,它代表 Pod 的數量。例如,如果您將 minAvailable 設定為 10,則即使在發生中斷期間,也必須始終有 10 個 Pod 可用。
  • 當您透過將值設定為百分比的字串表示形式 (例如 "50%") 來指定百分比時,它代表 Pod 總數的百分比。例如,如果您將 minAvailable 設定為 "50%",則在中斷期間,至少 50% 的 Pod 保持可用。

當您將值指定為百分比時,它可能不會對應到確切的 Pod 數量。例如,如果您有 7 個 Pod,並且將 minAvailable 設定為 "50%",則不清楚這是否表示必須有 3 個 Pod 或 4 個 Pod 可用。Kubernetes 會四捨五入到最接近的整數,因此在本例中,必須有 4 個 Pod 可用。當您將值 maxUnavailable 指定為百分比時,Kubernetes 會將可能中斷的 Pod 數量向上四捨五入。因此,中斷可能會超過您定義的 maxUnavailable 百分比。您可以檢查控制此行為的程式碼

指定 PodDisruptionBudget

PodDisruptionBudget 具有三個欄位

  • 標籤選擇器 .spec.selector,用於指定它所適用的 Pod 集合。此欄位為必要欄位。
  • .spec.minAvailable,它描述在逐出後,即使在沒有被逐出的 Pod 的情況下,該集合中仍必須可用的 Pod 數量。minAvailable 可以是絕對數字或百分比。
  • .spec.maxUnavailable (在 Kubernetes 1.7 及更高版本中可用),它描述在逐出後,該集合中可能不可用的 Pod 數量。它可以是絕對數字或百分比。

在單個 PodDisruptionBudget 中,您只能指定 maxUnavailableminAvailable 中的一個。maxUnavailable 只能用於控制逐出具有關聯控制器管理它們的 Pod。在下面的範例中,「所需的副本數」是管理由 PodDisruptionBudget 選取的 Pod 的控制器的 scale

範例 1:在 minAvailable 為 5 的情況下,只要在 PodDisruptionBudget 的 selector 選取的 Pod 中留下 5 個或更多健康的 Pod,就允許逐出。

範例 2:在 minAvailable 為 30% 的情況下,只要至少有 30% 的所需副本數是健康的,就允許逐出。

範例 3:在 maxUnavailable 為 5 的情況下,只要在所需副本總數中,最多只有 5 個不健康的副本,就允許逐出。

範例 4:在 maxUnavailable 為 30% 的情況下,只要不健康副本的數量不超過所需副本總數的 30%(向上取整數),就允許驅逐。如果所需副本總數只有一個,則仍然允許中斷該單一副本,從而導致 100% 的有效不可用性。

在一般用法中,單一預算會用於控制器管理的一組 Pod,例如,單一 ReplicaSet 或 StatefulSet 中的 Pod。

如果您將 maxUnavailable 設定為 0% 或 0,或者將 minAvailable 設定為 100% 或副本數,則您要求零自願驅逐。當您為工作負載物件(例如 ReplicaSet)設定零自願驅逐時,您將無法成功排空執行這些 Pod 之一的節點。如果您嘗試排空執行不可驅逐 Pod 的節點,則排空永遠不會完成。根據 PodDisruptionBudget 的語意,這是允許的。

您可以在下面找到定義的 Pod 中斷預算範例。它們匹配帶有標籤 app: zookeeper 的 Pod。

使用 minAvailable 的 PDB 範例

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: zk-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: zookeeper

使用 maxUnavailable 的 PDB 範例

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: zk-pdb
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      app: zookeeper

例如,如果上面的 zk-pdb 物件選擇大小為 3 的 StatefulSet 的 Pod,則這兩個規範具有完全相同的含義。建議使用 maxUnavailable,因為它可以自動回應相應控制器副本數量的變更。

建立 PDB 物件

您可以使用 kubectl 建立或更新 PDB 物件。

kubectl apply -f mypdb.yaml

檢查 PDB 的狀態

使用 kubectl 檢查您的 PDB 是否已建立。

假設您的命名空間中實際上沒有符合 app: zookeeper 的 Pod,那麼您會看到類似這樣的內容

kubectl get poddisruptionbudgets
NAME     MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
zk-pdb   2               N/A               0                     7s

如果存在符合條件的 Pod(例如,3 個),那麼您會看到類似這樣的內容

kubectl get poddisruptionbudgets
NAME     MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
zk-pdb   2               N/A               1                     7s

ALLOWED DISRUPTIONS 的非零值表示中斷控制器已看到 Pod、計算了符合條件的 Pod,並更新了 PDB 的狀態。

您可以使用以下命令取得有關 PDB 狀態的更多資訊

kubectl get poddisruptionbudgets zk-pdb -o yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  annotations:

  creationTimestamp: "2020-03-04T04:22:56Z"
  generation: 1
  name: zk-pdb

status:
  currentHealthy: 3
  desiredHealthy: 2
  disruptionsAllowed: 1
  expectedPods: 3
  observedGeneration: 1

Pod 的健康狀態

目前的實作將健康的 Pod 視為具有 type="Ready"status="True".status.conditions 項目。這些 Pod 會透過 PDB 狀態中的 .status.currentHealthy 欄位進行追蹤。

不健康 Pod 驅逐策略

功能狀態: Kubernetes v1.31 [stable] (預設啟用:true)

PodDisruptionBudget 保護應用程式可確保 .status.currentHealthy Pod 的數量不低於 .status.desiredHealthy 中指定的數量,方法是不允許驅逐健康的 Pod。透過使用 .spec.unhealthyPodEvictionPolicy,您還可以定義應考慮驅逐不健康 Pod 的標準。未指定策略時的預設行為對應於 IfHealthyBudget 策略。

原則

IfHealthyBudget
只有在受保護的應用程式未中斷(.status.currentHealthy 至少等於 .status.desiredHealthy)的情況下,才能驅逐正在執行(.status.phase="Running")但尚未健康的 Pod。

此策略確保已中斷應用程式的執行中 Pod 有最佳機會變得健康。這對排空節點產生負面影響,節點可能會被 PDB 保護的行為異常應用程式阻止。更具體地說,應用程式的 Pod 處於 CrashLoopBackOff 狀態(由於錯誤或設定錯誤),或 Pod 只是無法報告 Ready 狀況。

AlwaysAllow
正在執行(.status.phase="Running")但尚未健康的 Pod 被視為已中斷,並且可以驅逐,無論是否滿足 PDB 中的條件。

這表示已中斷應用程式的預期執行中 Pod 可能無法獲得變得健康的機會。透過使用此策略,叢集管理員可以輕鬆驅逐 PDB 保護的行為異常應用程式。更具體地說,應用程式的 Pod 處於 CrashLoopBackOff 狀態(由於錯誤或設定錯誤),或 Pod 只是無法報告 Ready 狀況。

任意工作負載和任意選擇器

如果您僅將 PDB 與內建工作負載資源(Deployment、ReplicaSet、StatefulSet 和 ReplicationController)或具有實作 scale 自訂資源子資源一起使用,並且 PDB 選擇器與 Pod 擁有資源的選擇器完全匹配,則可以跳過本節。

您可以將 PDB 與由另一個資源、「運算子」或裸 Pod 控制的 Pod 一起使用,但有以下限制

  • 只能使用 .spec.minAvailable,而不能使用 .spec.maxUnavailable
  • .spec.minAvailable 只能使用整數值,而不能使用百分比。

由於 Kubernetes 無法在沒有支援的擁有資源的情況下推導出 Pod 的總數,因此無法使用其他可用性配置。

您可以使用選擇器,該選擇器選擇屬於工作負載資源的 Pod 的子集或超集。驅逐 API 將不允許驅逐多個 PDB 涵蓋的任何 Pod,因此大多數使用者會希望避免重疊的選擇器。重疊 PDB 的一個合理用途是在 Pod 從一個 PDB 轉換到另一個 PDB 時。

上次修改時間:2024 年 2 月 21 日下午 11:53 PST:將 PDBUnhealthyPodEvictionPolicy 升級為 GA (f364b4c247)