具代表性的面試主題

系統設計面試:如何安全利用 Kubernetes nominatedNodeName 加速排程?

系統設計困難
Offer.cc 編輯團隊發佈 更新

題幹

一個外部排程元件會為 Pending Pod 推薦目標節點,希望減少搶佔後的重複過濾成本。請依 Kubernetes nominatedNodeName 設計協作協定,並說明為什麼它不能取代 nodeName、如何處理 scheduler 覆寫、資源變化和回滾。

題幹與適用場景

一個外部排程元件會為 Pending Pod 推薦目標節點,希望減少搶佔後的重複過濾成本。請依 Kubernetes nominatedNodeName 設計協作協定,並說明為什麼它不能取代 nodeName、如何處理 scheduler 覆寫、資源變化和回滾。

Kubernetes v1.35 將 nominatedNodeName 標為 beta。它是 Pod status 中供外部元件提名節點的欄位,提名是 best effort,scheduler 仍可覆寫,即使欄位存在也可能判斷該節點不適合。題目考察候選人能否把提示狀態與最終 binding 分離。

面試官考察點

重點包括:status 寫入權限和所有權、提名與過濾迴圈的時序、搶佔受害者優雅退出、nodeName 與 nominatedNodeName 的語義差異、外部排程器的冪等與過期處理、指標設計,以及 feature gate 的灰度和回滾。

30 秒回答框架

「我把 nominatedNodeName 當作可撤銷提示,不把它當作承諾。外部元件只在明確授權下更新 status,並附帶版本和原因;scheduler 每輪先驗證提名節點,失敗就回退到全量候選。提名節點可能被更高優先級 Pod 搶走,欄位也可能被 scheduler 改寫或清空。最終以 nodeName 和 binding 事件為準,觀測提名命中率、回退率、排程延遲和搶佔受害者退出時間,異常時關閉 feature gate 或停用外部寫入。」

分步驟深入解答

第一步:劃分欄位語義

nodeName 是 Pod spec 中的硬綁定提示,scheduler 會被繞過,節點不存在或資源不足時可能直接失敗。nominatedNodeName 位於 status,用於表達某個 Pending Pod 的候選節點,外部提名和 scheduler 搶佔都可寫入,屬於軟狀態。

第二步:定義外部元件權限

外部元件應使用最小 RBAC,只能更新目標 Pod 的 status,並在註解或事件中記錄提名原因、演算法版本和時間。它不能修改 spec.nodeName,也不能假設 status 更新後 kubelet 會立即執行綁定。

yaml
apiVersion: v1
kind: Pod
metadata:
  name: batch-worker
status:
  nominatedNodeName: worker-07

第三步:處理 scheduler 的優先級

scheduler 可能因搶佔找到提名節點,也可能在進入 WaitOnPermit 或 PreBind 時寫入。外部元件必須接受欄位被覆寫,不能持續搶寫造成控制器震盪。每次更新前比較 resourceVersion,衝突時重新讀取並重新計算。

第四步:設計過濾與回退

scheduler 先驗證 nominatedNodeName 是否仍通過資源、親和、污點和拓撲過濾;不通過時繼續標準候選節點流程。外部元件也應在提名前做相同級別的快速檢查,但不能把自己的檢查結果當成 scheduler 的最終結論。

第五步:處理搶佔時間窗

搶佔會給受害 Pod 留出優雅終止時間,提名節點在這段時間內可能仍不符合新 Pod。scheduler 可能先清空提名欄位,或因另一個更高優先級 Pod 到達而讓出節點。業務側應等待 binding 事件,不應在 status 提名後立即發流量。

第六步:保證冪等與過期安全

外部元件為每次提名產生可追蹤的決策 ID,並設定短 TTL。節點資源變化、Pod spec 更新、優先級變化或排程佇列重排後,舊提名應視為過期;重複 reconcile 只在決策仍有效時寫入相同值。

第七步:設計觀測指標

至少記錄提名寫入成功率、status 衝突、提名節點過濾失敗率、回退後排程延遲、Pod 從 Pending 到 binding 的時間、受害 Pod 終止耗時和 nominatedNodeName 被清空次數。按叢集、優先級、排程器和外部演算法版本切分,才能定位回退退化。

第八步:規劃灰度與回滾

先在少量 namespace 和低風險 PriorityClass 上啟用,比較啟用前後的排程延遲與搶佔結果。發現過濾耗時上升、錯誤綁定或狀態震盪時,停止外部 status 更新並關閉相關 scheduler feature gate;保留普通排程路徑,避免透過寫 nodeName 強制回退。

設計取捨與邊界

nominatedNodeName 還是 nodeName

nominatedNodeName 保留 scheduler 的過濾、搶佔和 binding 責任,適合外部元件提供建議。nodeName 繞過 scheduler,適用於明確知道節點且能承擔資源與故障責任的進階場景,不能作為通用加速手段。

先驗提名還是全量過濾

先驗提名可減少大型叢集中搶佔後的重複過濾,但提名節點可能已釋放資源或變得不合適。回退掃描是正確性底線,效能最佳化不能刪除它。

狀態可見性還是控制權

status 讓外部系統和維運看到排程意圖,卻不授予最終控制權。告警、控制器和業務自動化都應監聽 binding、FailedScheduling 和事件,而不是只看 nominatedNodeName。

失敗演練與演進計畫

提名節點資源被占用

在提名寫入後啟動更高優先級 Pod,驗證 scheduler 能覆寫或清空欄位,並讓原 Pod 回退到其他節點,而不是永久 Pending。

status 更新衝突

並發修改同一 Pod status,確認外部元件遇到 resourceVersion 衝突後重新讀取,不會使用舊物件覆蓋 scheduler 的決定。

優雅終止延遲

讓搶佔受害者設定較長 termination grace period,確認提名節點在等待期間不會被誤報為已可用,並監控 Pending 到 binding 的尾延遲。

常見誤區與追問

誤區一:把 nominatedNodeName 當成綁定結果

追問:欄位存在後 Pod 一定在該節點嗎?不一定,scheduler 仍會重新過濾,最終 nodeName 和 binding 事件才是結果。

誤區二:用 nodeName 取代提名

追問:為什麼不直接寫 nodeName?它會繞過 scheduler,失去資源、污點、親和與搶佔保護,節點不合適時可能直接失敗。

誤區三:外部控制器持續搶寫 status

追問:scheduler 改寫欄位怎麼辦?接受所有權競爭,使用 resourceVersion、決策 TTL 和冪等 reconcile,避免控制器來回覆蓋。

延伸追問與參考答案

提名節點為什麼仍可能不是最終節點?

搶佔受害者退出期間,其他節點可能釋放資源,或更高優先級 Pod 先占用提名節點;scheduler 會繼續嘗試,並可能清空或改寫提名。

如何判斷最佳化是否有效?

比較提名前後過濾耗時、Pending 到 binding 延遲、提名命中率、回退率和搶佔受害者退出時間;只看寫入次數不能證明排程變快。

外部元件最小安全邊界是什麼?

只更新獲授權 Pod 的 status,不寫 nodeName,不修改優先級或資源 spec,並以 binding 事件確認結果;所有決策都要能過期、稽核和回滾。

公開來源

同類題目

相關面試工具

用 Solve 整理系統設計回答

從澄清需求開始,展開規模、架構、元件選擇和取捨。

查看工具