為你的應用程式指定中斷預算
Kubernetes v1.21 [穩定]
本頁說明如何限制您的應用程式所經歷的並行中斷次數,以便在允許叢集管理員管理叢集節點的同時,實現更高的可用性。
準備開始
您的 Kubernetes 伺服器版本必須為 v1.21 或更新版本。若要檢查版本,請輸入kubectl version
。- 您是 Kubernetes 叢集上執行之應用程式的擁有者,該應用程式需要高可用性。
- 您應該知道如何部署複寫的無狀態應用程式及/或複寫的具狀態應用程式。
- 您應該已閱讀關於Pod 中斷的內容。
- 您應該向叢集擁有者或服務提供者確認他們是否尊重 Pod 中斷預算。
使用 PodDisruptionBudget 保護應用程式
- 識別您要使用 PodDisruptionBudget (PDB) 保護的應用程式。
- 思考您的應用程式如何應對中斷。
- 以 YAML 檔案建立 PDB 定義。
- 從 YAML 檔案建立 PDB 物件。
識別要保護的應用程式
當您想要保護由其中一個內建 Kubernetes 控制器指定的應用程式時,最常見的使用案例
- Deployment
- ReplicationController
- ReplicaSet
- StatefulSet
在這種情況下,請記下控制器的 .spec.selector
;相同的選擇器會進入 PDB 的 .spec.selector
。
從 1.15 版開始,PDB 支援自訂控制器,其中擴充子資源已啟用。
您也可以將 PDB 與非由上述控制器之一控制的 Pod,或任意 Pod 群組一起使用,但有一些限制,詳述於任意工作負載和任意選擇器。
思考您的應用程式如何應對中斷
決定在自願性中斷期間,短時間內可以有多少個執行個體關閉。
- 無狀態前端
- 考量:服務容量的降幅不要超過 10%。
- 解決方案:例如,使用 minAvailable 為 90% 的 PDB。
- 考量:服務容量的降幅不要超過 10%。
- 單一執行個體具狀態應用程式
- 考量:未經我的同意,請勿終止此應用程式。
- 可能的解決方案 1:不要使用 PDB 並容忍偶爾的停機時間。
- 可能的解決方案 2:設定 maxUnavailable=0 的 PDB。與叢集操作員達成共識 (在 Kubernetes 之外),在終止之前需要諮詢您。當叢集操作員與您聯絡時,請為停機時間做好準備,然後刪除 PDB 以表明已準備好進行中斷。之後重新建立。
- 考量:未經我的同意,請勿終止此應用程式。
- 多個執行個體具狀態應用程式,例如 Consul、ZooKeeper 或 etcd
- 考量:不要將執行個體數量減少到仲裁數以下,否則寫入會失敗。
- 可能的解決方案 1:將 maxUnavailable 設定為 1 (適用於應用程式的不同規模)。
- 可能的解決方案 2:將 minAvailable 設定為仲裁大小 (例如,當規模為 5 時為 3)。(允許更多同時發生的中斷)。
- 考量:不要將執行個體數量減少到仲裁數以下,否則寫入會失敗。
- 可重新啟動的批次工作
- 考量:在發生自願性中斷時,工作需要完成。
- 可能的解決方案:不要建立 PDB。Job 控制器將建立一個替換 Pod。
- 考量:在發生自願性中斷時,工作需要完成。
指定百分比時的四捨五入邏輯
minAvailable
或 maxUnavailable
的值可以表示為整數或百分比。
- 當您指定整數時,它代表 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,policy/v1beta1 和 policy/v1 API 之間,空選擇器的行為有所不同。對於 policy/v1beta1,空選擇器會比對零個 Pod,而對於 policy/v1,空選擇器會比對命名空間中的每個 Pod。在單個 PodDisruptionBudget
中,您只能指定 maxUnavailable
和 minAvailable
中的一個。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。
注意
中斷預算並不能真正保證指定數量/百分比的 Pod 始終處於運作狀態。例如,當叢集處於預算中指定的最小大小時,託管叢集中 Pod 的節點可能會發生故障,從而使叢集中可用的 Pod 數量低於指定的大小。預算只能防止自願驅逐,而不能防止所有不可用的原因。如果您將 maxUnavailable
設定為 0% 或 0,或者將 minAvailable
設定為 100% 或副本數,則您要求零自願驅逐。當您為工作負載物件(例如 ReplicaSet)設定零自願驅逐時,您將無法成功排空執行這些 Pod 之一的節點。如果您嘗試排空執行不可驅逐 Pod 的節點,則排空永遠不會完成。根據 PodDisruptionBudget
的語意,這是允許的。
您可以在下面找到定義的 Pod 中斷預算範例。它們匹配帶有標籤 app: zookeeper
的 Pod。
使用 minAvailable 的 PDB 範例
使用 maxUnavailable 的 PDB 範例
例如,如果上面的 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
狀況。
注意
Pending
、Succeeded
或 Failed
階段的 Pod 始終被視為可驅逐。任意工作負載和任意選擇器
如果您僅將 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 時。