具代表性的面試主題

系統設計面試:如何設計 Kubernetes Pod 原地資源調整?

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

題幹

平台團隊希望在不重建 Pod 的情況下調整 CPU 與記憶體。請設計 Kubernetes 原地 Pod 調整流程,說明何時容器必須重啟、如何處理資源不足,以及怎樣觀測與回復。

題幹與適用場景

平台團隊希望在不重建 Pod 的情況下調整 CPU 與記憶體。請設計 Kubernetes 原地 Pod 調整流程,說明何時容器必須重啟、如何處理資源不足,以及怎樣觀測與回復。

Kubernetes 1.33 將容器原地調整提升為 Beta;1.36 的 Pod 層級資源調整也處於 Beta。請求修改執行中 Pod 的 CPU 與記憶體資源時,kubelet 依 resizePolicy、節點容量與 cgroup 狀態執行或延遲處理,不能把「修改規格」誤解為「永不重啟」。

面試官考察點

重點包括:區分 Pod 層級上限與容器資源、resizePolicy 的 CPU/記憶體語意、Pending/InProgress 狀態、不可行與延遲重試、scheduler 與 kubelet 的職責、QoS 與優先級,以及灰度與回復邊界。

30 秒回答框架

「我會把原地調整設計成宣告式請求加狀態機。控制器更新資源規格,kubelet 檢查節點可行性並更新 PodResizePendingPodResizeInProgress;CPU 通常可以不重啟,記憶體是否重啟由容器的 resizePolicy 決定。不可行請求要保留原因並按優先級重試,不能假裝已生效。平台需要觀測 observedGeneration、實際 cgroup、重啟次數與 QoS 變化,並以小批量灰度和反向 patch 回復。」

分步驟深入解答

第一步:定義資源模型

容器資源決定單一容器的請求與限制;支援的版本中,Pod 層級資源提供聚合邊界。Pod 層級限制是所有容器使用量的上界,但單一容器限制不能超過 Pod 層級限制。API 必須明確修改 spec.containers[*].resources 還是 spec.resources

第二步:建立宣告式調整流程

平台接收目標資源與原因,寫入 Pod 資源欄位,保存原值、操作者與變更代次。API 層不直接操作節點 cgroup;kubelet 觀察新的 generation,完成可行性檢查與執行,再把結果寫回狀態。

第三步:處理重啟策略

容器可按資源分別設定重啟策略:

yaml
resizePolicy:
  - resourceName: cpu
    restartPolicy: NotRequired
  - resourceName: memory
    restartPolicy: RestartContainer

NotRequired 嘗試在執行中套用;RestartContainer 允許透過重啟使新值生效。對 restartPolicy: Never 的 Pod,所有容器資源都必須使用 NotRequired,否則請求無效。

第四步:設計可行性與延遲狀態

節點無法提供目標資源時,kubelet 設定 PodResizePending,原因可以是 InfeasibleDeferred;成功處理時進入 PodResizeInProgress。控制器應讀取狀態而非只看 API spec,並透過 observedGeneration 確認狀態對應的請求代次。

第五步:處理 CPU 與記憶體差異

CPU 調整通常可更新 cgroup 配額而不重啟應用程式。記憶體縮容可能受目前工作集限制,部分執行時需要重啟才能安全套用;不能以 CPU 的無重啟行為推斷記憶體。控制器應按資源讀取策略並為每種結果提供明確事件。

第六步:協調排程與 QoS

原地調整不等於節點重新排程。擴大請求可能需要節點容量,延遲請求應按 PriorityClass、QoS 類別與等待時間重試。調整後要重新計算 QoS、資源配額與監控告警,避免突破 namespace 配額或低估 Guaranteed 工作負載。

第七步:觀測實際生效值

同時採集期望 spec、status 條件、observedGeneration、容器實際 cgroup 配額、重啟次數、OOM、CPU throttling 與記憶體工作集。若狀態顯示完成但 cgroup 未變化,應視為失敗並阻止下一次調整,而非繼續疊加 patch。

第八步:灰度、限速與回復

按工作負載與節點池分批執行,限制並發調整數,設定 Pending 超時與最大重試次數。異常時恢復保存的舊資源;若記憶體策略導致重啟,先摘除流量並驗證就緒,再擴大灰度。所有請求都要支援冪等鍵,避免控制器重複提交。

設計取捨與邊界

無重啟連續性還是資源確定性

原地調整減少服務中斷,但延遲與節點容量會讓結果非同步。對延遲敏感服務可保守使用小步調整;對批次工作可接受重啟以換取確定性。

Pod 層級邊界還是容器層級精度

Pod 層級資源適合表達共享上限,容器層級資源適合保護關鍵容器。兩者同時存在時,平台必須驗證容器限制不超過 Pod 上限,並在 UI 與稽核中顯示有效邊界。

自動重試還是人工批准

暫時不足適合有限重試;涉及記憶體重啟、QoS 變化或生產高峰時,應要求批准或維護窗口,不能無限自動重試。

失敗演練與演進計畫

節點資源不足

提交超過節點容量的擴容請求,確認狀態為 InfeasibleDeferred,驗證重試不會修改已生效的舊值。

記憶體調整觸發重啟

為記憶體設定 RestartContainer,觀察流量摘除、容器重啟、就緒恢復與事件順序,確認控制器不會把重啟誤報為業務故障。

代次競爭

快速提交兩個不同目標,確認舊 generation 的完成狀態不會覆蓋新目標,且最終狀態的 observedGeneration 與實際 cgroup 一致。

常見誤區與追問

誤區一:原地調整保證永不重啟

追問:什麼會觸發重啟?容器的 resizePolicy 可以要求重啟,尤其是記憶體變化;Pod 層級資源調整本身沒有獨立重啟策略,但容器策略仍生效。

誤區二:只更新 spec 就算完成

追問:如何確認成功?檢查狀態條件、observedGeneration、實際 cgroup、容器事件與重啟次數,不能只讀期望欄位。

誤區三:節點不足時持續 patch

追問:正確做法是什麼?保留 Pending 原因,按優先級與等待時間有限重試,並提供遷移、縮小目標或人工批准路徑。

延伸追問與參考答案

為什麼 CPU 與記憶體要分開設計?

CPU 配額通常能線上改變;記憶體縮容受工作集與執行時限制,可能需要重啟。統一介面仍應保留按資源的策略與狀態。

如何防止重複調整覆蓋新目標?

用資源版本或 generation 做條件更新,控制器只接受最新目標,狀態透過 observedGeneration 與實際 cgroup 對帳。

何時不應使用原地調整?

需要強隔離、節點無法穩定提供容量、應用程式不能承受重啟或資源變化會破壞執行時假設時,應採用新 Pod 滾動替換,並保留原地功能作為受控最佳化。

公開來源

同類題目

相關面試工具

用 Solve 整理系統設計回答

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

查看工具