K8S Pod 保護之 PodDisruptionBudget
摘要:PDB 只能保證 自願中斷 時的副本數,比如 evict pod 過程中剛好滿足 .spec.minAvailable 或 .spec.maxUnavailable ,這時某個本來正常的Pod突然因爲 Node Down (非自願中斷)掛了,那麼這個時候實際Pods數就比PDB中要求的少了,因此PDB不是萬能的。通過 PodDisruptionBudget 控制器可以設置應用POD集羣處於運行狀態最低個數,也可以設置應用POD集羣處於運行狀態的最低百分比,這樣可以保證在主動銷燬應用POD的時候,不會一次性銷燬太多的應用POD,從而保證業務不中斷或業務SLA不降級。
在 Kubernetes
中,爲了保證業務不中斷或業務SLA不降級,需要將應用進行集羣化部署。通過 PodDisruptionBudget
控制器可以設置應用POD集羣處於運行狀態最低個數,也可以設置應用POD集羣處於運行狀態的最低百分比,這樣可以保證在主動銷燬應用POD的時候,不會一次性銷燬太多的應用POD,從而保證業務不中斷或業務SLA不降級。
PodDisruptionBudget 簡介
Pod Disruption Budget
(pod 中斷 預算) 簡稱 PDB
,含義其實是終止pod前通過 labelSelector
機制獲取正常運行的 pod
數目的限制,目的是對 自願中斷
的保護措施。
Kubernetes version >= 1.7 才支持 PodDisruptionBudget
PDB 應用場景
- 節點維護或升級時 ( kubectl drain )
注意:如果 Node 狀態處於 not ready
,PDB 是不會生效,因爲 PDB 只能針對 自願中斷
生效,什麼叫 自願中斷
下文介紹。
自願中斷和非自願中斷 [1]
Pod 不會消失,直到有人(人類或控制器)將其銷燬,或者當出現不可避免的硬件或系統軟件錯誤。
我們把這些不可避免的情況稱爲應用的 非自願性中斷
。例如:
- 後端節點物理機的硬件故障
- 集羣管理員錯誤地刪除虛擬機(實例)
- 雲提供商或管理程序故障使虛擬機消失
- 內核恐慌(kernel panic)
- 節點由於集羣網絡分區而從集羣中消失
- 由於節點 資源不足 而將容器逐出
除資源不足的情況外,大多數用戶應該都熟悉以下這些情況;它們不是特定於 Kubernetes 的。
我們稱這些情況爲 自願中斷
。包括由應用程序所有者發起的操作和由集羣管理員發起的操作。典型的應用程序所有者操作包括:
- 刪除管理該 pod 的 Deployment 或其他控制器
- 更新了 Deployment 的 pod 模板導致 pod 重啓
- 直接刪除 pod(意外刪除)
集羣管理員操作包括:
- 排空(drain)節點 進行修復或升級。
- 從集羣中排空節點以縮小集羣(瞭解 集羣自動調節 )。
- 從節點中移除一個 pod,以允許其他 pod 使用該節點。
這些操作可能由集羣管理員直接執行,也可能由集羣管理員或集羣託管提供商自動執行。
PDB 關鍵參數與注意事項
-
.spec.minAvailable
:表示發生自願中斷
的過程中,要保證至少可用的Pods數或者比例 -
.spec.maxUnavailable
:表示發生自願中斷
的過程中,要保證最大不可用的Pods數或者比例
上面配置只能用來對應 Deployment
, RS
, RC
, StatefulSet
的Pods,推薦優先使用 .spec.maxUnavailable
。
注意
:
-
同一個 PDB Object 中不能同時定義
.spec.minAvailable
和.spec.maxUnavailable
。 -
前面提到,應用滾動更新時Pod的
delete
和unavailable
雖然也屬於自願中斷
,但是實際上滾動更新有自己的策略控制(marSurge
和maxUnavailable
),因此PDB不會干預這個過程。 -
PDB 只能保證
自願中斷
時的副本數,比如evict pod
過程中剛好滿足.spec.minAvailable
或.spec.maxUnavailable
,這時某個本來正常的Pod突然因爲Node Down
(非自願中斷)掛了,那麼這個時候實際Pods數就比PDB中要求的少了,因此PDB不是萬能的!
使用上,如果設置 .spec.minAvailable
爲 100%
或者 .spec.maxUnavailable
爲 0%
,意味着會完全阻止 evict pods
的過程( Deployment
和 StatefulSet
的 滾動更新除外
)。
PDB 例子
-
下面的例子使用了
minAvailable
參數:apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: nginx-pdb namespace: default spec: minAvailable: 2 selector: matchLabels: app: nginx
-
下面的例子使用了
maxUnavailable
參數:apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: nginx-pdb namespace: default spec: maxUnavailable: 30% selector: matchLabels: app: nginx