題幹與適用場景
你負責一個 5 副本的有狀態服務,需要在節點維護和叢集縮容時保持法定人數。請設計 PDB,說明 minAvailable 與 maxUnavailable 如何選擇,並解釋為什麼設定後仍可能中斷。假設服務由 StatefulSet 管理,維護工具透過 Eviction API 驅逐 Pod。
面試官考察點
- 能否先定義服務的可用性約束和 quorum,而不是直接寫 YAML。
- 能否區分 voluntary disruption 與節點故障、資源壓力等 involuntary disruption。
- 能否理解 PDB 只限制驅逐速率,不保證一直有指定數量的 Pod。
- 能否發現滾動升級、標籤選擇器、百分比向上取整和資源不足造成的阻塞。
回答前需要釐清的問題
- 法定人數是多少? 5 副本的共識服務可能要求至少 3 個健康副本;一般無狀態服務可能只要求保留 90% 容量。
- 誰執行驅逐? PDB 由 Eviction API 尊重;直接刪除 Deployment 或 Pod 可能繞過它。
- 維護是否包含應用程式滾動升級? PDB 不限制 Deployment/StatefulSet 滾動升級,升級策略要在工作負載中設定。
- 節點是否有足夠餘量排程替代 Pod? PDB 允許驅逐不等於新 Pod 能立即排程,資源不足會讓 drain 卡住。
30 秒回答框架
「我先確認服務需要保留的健康副本數和驅逐來源。5 副本且需要 3 個副本組成 quorum 時,我會設定 minAvailable: 3,或在副本規模會變化時使用等價的 maxUnavailable: 2,並讓選擇器與 StatefulSet 一致。PDB 只約束自願驅逐,不防節點故障,也不取代滾動升級策略。上線前用 kubectl drain 檢查 disruptionsAllowed,同時驗證替代 Pod 有資源可排程。」
分步驟深入解答
1. 把可用性目標轉成預算
PDB 的預算是一次自願干擾允許損失的副本數。若 5 副本服務必須保留 3 個健康副本,預算最多為 2。minAvailable: 3 直接表達剩餘健康數;maxUnavailable: 2 表達允許不可用數。兩者不能同時設定。
2. 選擇適合伸縮的表達
固定 quorum 通常使用 minAvailable 更直觀。若工作負載副本會伸縮,官方文件建議考慮 maxUnavailable,它按預期副本數計算,會隨規模變化。百分比會向上取整:7 個預期副本設定 maxUnavailable: 30%,允許的不可用數是 3,不是向下的 2,因此必須把取整納入容量評估。
3. 綁定正確的工作負載
PDB 的 label selector 必須匹配 StatefulSet 的 selector,否則預算可能保護不到目標 Pod,或錯誤地把多個應用程式算在一起。選擇器要保持穩定,發布時不要臨時改標籤逃避預算。
4. 說明 PDB 的邊界
PDB 只約束 voluntary disruption,例如 kubectl drain 和叢集自動維護。硬體故障、節點消失、資源壓力驅逐屬於 involuntary disruption,PDB 無法阻止它們,而且這些故障仍會計入預算。直接刪除 Pod 或 Deployment 也可能繞過 PDB。
5. 處理 drain 阻塞
如果預算已用完,Eviction API 會拒絕新的驅逐並重試。即使允許驅逐,替代 Pod 仍可能因沒有節點資源而 Pending,讓 drain 無法繼續。應把 Pod requests、跨區分布、啟動時間和節點餘量一起納入方案,而不是把 PDB 當成容量系統。
6. 與滾動升級和健康策略分開
PDB 不限制 Deployment 或 StatefulSet 自身的滾動升級;更新策略中的 maxUnavailable、maxSurge 和 readiness 才控制發布期間的替換。Kubernetes 也提供 unhealthy pod eviction policy,需結合故障 Pod 是否應先清理來決定。發布、維護和事故恢復要分別測試。
高品質示範回答
我會先確認 5 副本服務的 quorum 是 3,並確認維護工具使用 Eviction API。基本設定使用 minAvailable: 3,選擇器嚴格複用 StatefulSet 的標籤;如果副本會自動伸縮,我會評估 maxUnavailable: 2 或經過取整驗證的百分比。PDB 只限制自願驅逐,不能阻止節點故障、資源壓力或直接刪除,也不控制滾動升級。
上線時我會檢查 disruptionsAllowed,執行受控 drain,觀察被驅逐 Pod 的終止時間、替代 Pod 的排程和 quorum 狀態。如果預算耗盡,drain 暫停是預期行為;如果替代 Pod Pending,應補足節點餘量或調整 requests,而不是把預算設得更寬。最後分別驗證升級、節點故障和維護回滾路徑。
常見錯誤
- 錯誤表現 → 認為 PDB 能防止所有宕機。 失敗原因:PDB 不控制 involuntary disruption。修正方法:明確說明節點故障、資源壓力和維護驅逐的邊界。
- 錯誤表現 → 只寫
maxUnavailable: 50%。 失敗原因:百分比向上取整可能允許超出直覺的副本損失。修正方法:用實際預期副本數計算取整結果。 - 錯誤表現 → 認為 PDB 控制滾動升級。 失敗原因:Deployment/StatefulSet 更新不受 PDB 限制。修正方法:在工作負載更新策略中設定發布行為。
- 錯誤表現 → 把 drain 卡住歸咎於 PDB 錯誤。 失敗原因:預算或節點資源不足都能讓驅逐無法完成。修正方法:同時檢查
disruptionsAllowed、Pending Pod、requests 和節點容量。
追問及應對
如果 5 副本中只有 3 個健康 Pod,還能驅逐嗎?
若 minAvailable: 3,不能再允許自願驅逐;Eviction API 應拒絕請求。先恢復健康副本或接受維護暫停,不能為了 drain 臨時刪除 PDB 而失去 quorum 保護。
如果叢集自動縮容一直卡住,應該放寬 PDB 嗎?
先確認縮容屬於 voluntary disruption、預算是否耗盡以及替代 Pod 是否能排程。對 quorum 服務放寬預算可能直接破壞一致性;可以增加節點餘量、調整縮容批次,或讓無狀態服務使用容量百分比,而不是統一放寬。
直接刪除 Pod 為什麼會繞過 PDB?
PDB 約束的是 Eviction API 的自願驅逐請求,不是所有刪除操作。治理上應限制直接刪除權限,讓維護自動化呼叫 Eviction API;事故處置仍需保留明確的管理員旁路。
maxUnavailable: 0 有什麼風險?
它要求零個自願不可用 Pod,節點 drain 可能永遠無法完成。只有在業務確實不能承受任何自願中斷、且團隊有人工協調維護窗口時才使用,並準備解除預算後再恢復。