題幹與適用場景
一個批次平台會同時建立數千個 Pod,但映像、配額、拓撲或外部資源尚未準備好。請設計一種機制,讓 Pod 建立後暫不進入 Kubernetes scheduler,條件滿足時再放行;同時說明如何避免調度器和 Cluster Autoscaler 被大量無效 Pending Pod 消耗,如何處理閘門逾時、控制器故障和多租戶隔離。
面試官考察點
- 能否把「已建立」與「可調度」拆成獨立狀態。
- 是否理解
spec.schedulingGates的建立、移除和不可追加約束。 - 能否設計冪等解閘、逾時、權限和復原流程。
- 能否區分 SchedulingGated、Unschedulable 與執行失敗。
- 能否用指標、事件和稽核紀錄證明系統沒有靜默卡死。
回答前需要釐清的問題
- 閘門由誰加入,哪些條件由誰負責確認?
- 條件是 Pod 級、批次級還是租戶級?是否要求 gang scheduling?
- 放行延遲、過期策略、最大並發和成本目標是多少?
- 控制器重啟、API 重試、節點擴縮和權限撤銷如何處理?
30 秒回答框架
我會在 Pod 建立時寫入命名空間限定的 schedulingGates,把映像預熱、配額和外部資源準備做成可觀測條件。控制器只負責冪等移除已有 gate,不在建立後追加新 gate;放行前再次檢查租戶配額和批次策略。指標區分 gated 與真正不可調度,逾時進入明確的失敗或人工處理狀態,所有變更帶條件版本和稽核紀錄。
分步驟深入解答
1. 定義狀態機
建議區分 Created、SchedulingGated、ReadyToSchedule、Unschedulable、Running 和 Expired。Pod 仍可被 API 讀取,但 scheduler 不會嘗試處理非空 gate 的 Pod。
2. 選擇 gate 命名
每個 gate 是字串條件名,例如 batch.example.com/image-ready。命名空間、批次和控制器版本寫入 labels 或 annotations,gate 本身只表達未滿足的條件,避免把動態資料塞進 gate 名稱。
3. 在建立時寫入 gate
gate 只能在 Pod 建立時由用戶端或准入變更器初始化。建立後可以按任意順序移除已有 gate,但不能追加新 gate;因此所有可能的阻塞條件必須在建立階段完成列舉。
4. 設計解閘控制器
控制器監聽 Pod、配額、映像預熱和外部資源事件,計算條件集合後執行帶資源版本的 patch。重複事件應得到同一結果;只移除自己擁有的 gate,避免與其他控制器互相覆蓋。
5. 處理批次與並發
批次級資源可由獨立物件記錄,Pod gate 只等待批次控制器的結論。放行時按租戶配額、優先級和最大並發分批刪除 gate,避免瞬間把調度壓力轉移到 scheduler 和 autoscaler。
6. 設計逾時與人工介入
建立時間、最後條件更新時間和截止時間都應持久化。逾時後不要偷偷移除 gate;應寫入原因、發出事件並選擇取消、重試或轉人工佇列。重試必須有退避和最大次數。
7. 觀測真實佇列
Kubernetes 提供 schedulerpendingpods 的 gated 標籤,用於區分明確未準備好調度與已嘗試但不可調度。配合 Pod condition、事件、控制器佇列長度、gate 年齡分位數和 autoscaler 活動,才能定位瓶頸。
8. 約束權限與復原
准入策略限制誰能建立 gate,控制器只允許移除指定命名空間和前綴的 gate。控制器重啟後從 API 重建狀態;patch 衝突重新讀取並比較資源版本。若控制器長期不可用,值班流程應能按稽核紀錄安全取消或放行。
設計取捨與邊界
Scheduling gates 只控制 Pod 是否進入調度,不取代節點親和性、資源請求、拓撲約束或執行時 readiness。gate 過多會把真實容量問題隱藏在應用層;gate 過少則會讓未準備的 Pod 進入 scheduler。控制器必須把「條件未滿足」和「叢集沒有容量」保持為不同訊號,也不能把 gate 當作鎖來實作任意跨物件交易。
落地計畫與證據
- 記錄每類 gate 的擁有者、條件來源、逾時和刪除權限。
- 在准入層驗證 gate 前綴、租戶配額和建立時的完整條件集合。
- 先用小批次壓測 scheduler、autoscaler、API Server 和控制器 patch 衝突。
- 監控
schedulerpendingpods{queue="gated"}、gate 年齡、逾時率、放行吞吐和每租戶並發。 - 演練控制器重啟、網路分區、權限撤銷、批次取消和重複 patch,並核對稽核日誌。
常見誤區與追問
誤區一:建立後再追加 gate
API 約束是 gate 只能建立時設定,之後只能移除。動態條件應由控制器在建立前彙總,或使用獨立物件等待後再建立 Pod。
誤區二:把 SchedulingGated 當成調度失敗
非空 gate 的 Pod 尚未被 scheduler 嘗試。回答必須區分 gated、Unschedulable、ImagePullBackOff 和應用 readiness。
誤區三:用刪除 gate 代替配額控制
移除 gate 只表示允許嘗試調度,不能保證資源存在。放行前仍要檢查配額、優先級和批次並發。
誤區四:沒有 gate 年齡和逾時告警
沒有年齡分位數就無法發現靜默卡死。應記錄條件、責任控制器、最後進展和明確的取消路徑。
誤區五:忽略 autoscaler 成本
大量未準備 Pod 會觸發無意義的擴容評估。使用 gated 佇列指標和放行節流驗證成本是否真正下降。