題幹與適用場景
你維護一個由 Deployment 管理、期望副本數為 5 的服務。叢集升級時需要 drain 節點,團隊擔心同時失去多個副本。面試官要求你設計或審查 PodDisruptionBudget(PDB),並解釋它對滾動發布、節點故障和直接刪除 Pod 的影響。
這道題考察 Kubernetes 可用性邊界和運維推理。PDB 限制的是受 selector 匹配的副本因自願中斷而同時不可用的數量;它不是副本控制器,也不是對所有故障的可用性保證。回答必須把期望副本數、selector、驅逐入口和剩餘容量連在一起。
面試官在評估什麼
- 能否區分 voluntary disruption 與 involuntary disruption。
- 能否正確解釋
minAvailable和maxUnavailable的互斥語義。 - 能否說明 PDB 依賴控制器的期望副本數和正確的 Pod selector。
- 能否判斷 drain 重試、PDB 不生效和滾動更新的邊界。
- 能否從副本、跨區分布、探針和容量角度補足 PDB 之外的可用性措施。
回答前需要釐清的問題
- 服務由 Deployment、StatefulSet 還是其他控制器管理?PDB 需要能推導期望副本數。
- selector 是否只匹配這一份工作負載?匹配過寬會把無關 Pod 混入預算。
- 需要保護的是節點 drain、叢集縮容等自願動作,還是要處理節點斷電?後者不能靠 PDB 阻止。
- 服務是否有跨可用區副本、足夠容量和正確 readiness?PDB 只限制驅逐,不創造容量。
- 維護窗口允許 drain 等待多久?預算過緊會延長操作,過鬆會降低可用副本數。
30 秒回答框架
「PDB 只約束透過 Eviction API 發起的自願中斷。5 個副本可以用 minAvailable: 4 或 maxUnavailable: 1 表達一次最多少一個,但兩者不能同時設定。它依賴工作負載的期望副本數和精確 selector;節點故障、直接刪除 Deployment 或應用滾動更新不由 PDB 完全阻止。drain 被拒絕時應檢查預算、健康副本、容量和驅逐入口,同時用副本、跨區分布與探針補足可用性。」
深度回答步驟
先定義中斷類型
節點 drain、節點升級和叢集自動縮容通常透過 Eviction API 請求 Pod 遷移,屬於自願中斷,PDB 可以讓 API 暫時拒絕驅逐。節點斷電、核心崩潰或網路隔離屬於非自願中斷,PDB 不能阻止它們;這些 Pod 變為不可用後仍會計入預算狀態。
解釋兩個互斥欄位
minAvailable 表示驅逐後至少要保持多少個匹配 Pod 可用;maxUnavailable 表示驅逐後最多允許多少個匹配 Pod 不可用。二者不能同時設定。對期望 5 個副本的服務,minAvailable: 4 和 maxUnavailable: 1 在目前規模下表達相近意圖,但百分比會隨副本數變化,必須先說明期望副本數和取整行為。
預算依賴期望副本和 selector
控制面透過 Pod 的 ownerReferences 找到管理它的工作負載,並從 .spec.replicas 推導 intended 數量。selector 應與 Deployment 或 StatefulSet 的 Pod 標籤一致且足夠窄。若 selector 匹配多個應用,預算可能錯誤地把它們視為一組;若沒有受支援的 owning resource,Kubernetes 無法可靠推導總數。
用一個配置說明邊界
以下配置表示期望 5 個匹配 Pod 時最多允許 1 個因自願驅逐不可用:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: checkout-api
spec:
maxUnavailable: 1
selector:
matchLabels:
app: checkout-api這段配置不保證總有 4 個健康 Pod:副本可能本來就不健康,節點也可能突然失效。上線前要核對 selector、readiness、期望副本數和多區容量。
解釋 drain 被拒絕或重試
當可驅逐數量為零、健康副本已低於 minAvailable,或預算控制器暫時無法計算狀態時,Eviction API 可以返回拒絕。kubectl drain 會週期性重試失敗請求,直到 Pod 被終止或達到逾時。排查時先確認 PDB 狀態、匹配 Pod、目前健康數、未就緒原因和維護動作是否真的走 Eviction API。
區分滾動更新和直接刪除
工作負載的 Deployment 或 StatefulSet 滾動更新由自身的更新策略處理,不會被 PDB 當成完全相同的限制;PDB 也不能約束直接刪除 Pod 或 Deployment 的操作。發布系統應同時配置 maxUnavailable、maxSurge、readiness 和回滾策略,不能把所有發布保護都交給 PDB。
補足 PDB 之外的可靠性
PDB 只處理一類中斷。要抵禦節點或可用區故障,還需要足夠副本、拓撲分布、容量餘量、正確的 readiness/liveness、優雅終止和連線排空。對有法定人數的狀態服務,預算應結合法定人數需求;對無狀態服務,先用真實流量、恢復時間和容量壓測驗證「可用」的定義。
高品質示範回答
「這個 Deployment 的期望副本數是 5,我會先確認 PDB selector 只匹配 checkout-api,並確認 readiness 和跨區容量。若要求自願驅逐後至少保留 4 個可用副本,可以寫 minAvailable: 4 或 maxUnavailable: 1,兩者互斥;我會根據副本規模變化選擇絕對數或百分比。
PDB 保護的是透過 Eviction API 的節點 drain、節點維護和某些縮容動作。節點斷電、核心故障和直接刪除 Pod 不會被它阻止,滾動更新也主要由 Deployment 的更新策略控制。drain 被拒絕時我會檢查目前健康副本、預算狀態、selector、Pod 未就緒原因和容量,並確認請求是否走 Eviction API;kubectl drain 可能會重試直到逾時。
最後我會把 PDB 與副本、拓撲分布、readiness、優雅終止和發布回滾一起驗證。PDB 過緊會讓維護長期卡住,過鬆則不能滿足服務的最低容量,所以閾值應來自流量和故障演練,而不是套用一個通用百分比。」
常見錯誤
- 說 PDB 能阻止節點故障:混淆自願與非自願中斷 → 明確 PDB 只約束 Eviction API 路徑。
- 同時設定
minAvailable和maxUnavailable:兩個欄位互斥 → 選擇一個表達預算。 - 只看目前 Pod 數量:預算基於控制器期望副本數 → 檢查 ownerReferences 和
.spec.replicas。 - selector 匹配整個命名空間:不同應用共享預算 → 使用與工作負載一致的窄 selector。
- 認為 PDB 保護滾動更新和直接刪除:發布控制器與刪除路徑有獨立語義 → 分別檢查更新策略和操作權限。
- drain 卡住就刪除 PDB:可能把容量風險擴大 → 先查健康副本、探針、預算狀態和容量,再調整維護窗口。
- 只配 PDB 不配拓撲和容量:剩餘 Pod 可能集中在同一故障域 → 配合多區分布、餘量和演練。
- 把百分比當固定副本數:擴縮容後預算含義變化 → 寫出期望規模、取整和擴縮容行為。
追問與回答
追問 1:minAvailable: 80% 對 5 個副本意味著什麼?
它表達至少保持按規則取整後的可用副本數,具體結果應以目前 Kubernetes 版本和 API 語義驗證,不能直接把百分比當成固定的 4 個。面試中應說明要檢查取整和擴縮容後的狀態。
追問 2:為什麼 drain 仍然可能導致服務不可用?
PDB 只限制可接受的自願驅逐數量,不能修復本來就不健康的 Pod、容量不足、單區集中或應用不承受連線遷移的問題。readiness、拓撲、容量和優雅終止需要一起驗證。
追問 3:直接 kubectl delete pod 會被 PDB 攔截嗎?
不應假設會。文件明確指出直接刪除 Pod 或 Deployment 可以繞過 PDB;需要透過權限、稽核和發布流程約束這類操作。
追問 4:PDB 狀態顯示沒有允許驅逐,先改大預算嗎?
先檢查 selector、期望副本、健康副本、未就緒原因和控制器狀態。盲目放寬預算可能把真實健康問題掩蓋;若維護確實需要,可在評估容量和回滾後臨時調整,並記錄窗口。
追問 5:狀態服務和無狀態服務的預算有什麼不同?
狀態服務要先滿足 quorum 或一致性協議的最低副本數,並驗證重平衡和恢復;無狀態服務通常關注剩餘容量、延遲和連線排空。兩者都不能只從副本數量推導真實可用性。
追問 6:如何驗證 PDB 配置真的有效?
在預生產或受控窗口執行一次 Eviction API 和 drain 演練,觀察拒絕、重試、終止寬限期、流量、錯誤率和恢復時間;再測試節點故障與直接刪除路徑,確認團隊沒有把 PDB 的保護邊界誤當成全故障保證。