題幹與適用場景
這是發布控制面問題,不只是把 Deployment 副本數改幾次。控制器要記錄期望版本、目前階段、流量權重、分析結果和人工決策,並把動作可靠反映到資料面。Google SRE 將金絲雀定義為部分且有時間限制的部署與評估;Kubernetes 原生 RollingUpdate 提供基礎可用性,漸進式控制器還要補足按流量分析、暫停、批准和自動回滾。
面試官考察點
- 能否區分控制面狀態、工作負載狀態、流量路由和指標分析狀態。
- 能否把階段推進建模為冪等狀態機,而不是一串不可恢復腳本。
- 能否定義可比較的 canary/control 窗口、樣本量、保護指標和統計延遲。
- 能否處理新發布覆蓋舊發布、控制器重啟、指標源不可用和跨地域部分成功。
- 能否保留誰批准、何時暫停、為何回滾以及最終版本的稽核鏈。
回答前需要釐清的問題
- 流量按請求、使用者、地域還是實例分配?是否需要穩定分桶?
- 哪些指標是硬門禁,哪些只是觀察項?錯誤預算和最小樣本如何定義?
- 回滾只切流量,還是也要停止並縮容 canary?資料庫和訊息格式如何相容?
- 階段由自動策略推進,還是每階段都需人工批准?批准權限如何授權?
- 多地域是統一推進、獨立推進,還是一個地域失敗就全域停止?
30 秒回答框架
「我會把發布建模成持久化狀態機:一個發布版本包含階段、目標權重、暫停策略、分析模板、逾時和回滾版本。控制器透過冪等 reconcile 把期望狀態寫入工作負載和流量路由,再讀取實際狀態和按版本分組的指標。只有樣本量和窗口滿足門檻,且錯誤率、尾延遲和業務護欄都通過,才推進下一階段;指標源失聯預設暫停。每次動作帶版本和冪等鍵,控制器重啟後可恢復,所有批准、暫停、回滾和路由變更寫入稽核日誌。」
分步深入解答
第一步:定義資源與狀態機
發布資源至少包含 release_id、候選版本、穩定版本、階段列表、目前階段、目標流量、分析模板、暫停原因、逾時和回滾策略。狀態可包括 PENDING、RUNNING、PAUSED、PROMOTING、ABORTING、SUCCEEDED、FAILED。每個狀態轉換都要有前置條件和冪等動作。
第二步:拆分控制面與資料面
控制面保存期望狀態和分析結論;資料面執行 Pod、Service、Ingress 或服務網格路由。控制器不能把「寫入 API 成功」當作發布成功,必須觀察可用副本、實際權重、就緒探針和版本標籤。Kubernetes 的 maxUnavailable 與 maxSurge 只約束滾動替換,不等於按使用者流量的金絲雀。
第三步:設計穩定的流量分配
按使用者或請求鍵做一致分桶,避免同一使用者在 canary 和 control 間頻繁跳轉。路由層應返回實際權重和版本命中計數。跨地域要記錄每個地域的目標與實際權重,不能用全域平均掩蓋單一地域失敗。
第四步:定義分析窗口與護欄
分析模板聲明查詢、取樣週期、最小樣本、允許誤差、連續失敗次數和最大等待時間。指標至少覆蓋可用性、尾延遲、資源飽和與關鍵業務結果;每個指標綁定版本、地域和流量分母。窗口不足或資料不完整時暫停,不要把缺失當作通過。
第五步:實作可恢復 reconcile
控制器週期性讀取發布資源、工作負載、路由和分析結果,計算下一動作。每個外部寫入帶 release_id 與階段版本;重複執行不會重複建立規則或重複記錄批准。重啟後從持久化與實際狀態重新收斂,發現權重偏離先暫停並修復。
第六步:處理暫停、批准和逾時
階段可以自動暫停、按時長暫停或無限等待人工批准。批准必須包含身分、作用域和目前階段版本;舊批准不能推進新版本。逾時預設暫停或回滾,不能繼續擴大流量。強制推進要經過權限檢查並寫明原因。
第七步:設計回滾與相容性邊界
應用程式回滾通常先把流量切回穩定版本,再決定是否縮容 canary。資料庫遷移、事件 schema 和快取格式要滿足新舊版本重疊窗口;只回滾二進位不能撤銷不可逆資料寫入。回滾也要冪等、可觀測並保留前一穩定版本。
第八步:驗證、稽核與演練
驗證階段推進、路由權重、指標分組、暫停、控制器重啟、指標源故障、地域故障、重複 webhook 和新版本覆蓋。稽核記錄期望、實際、操作者、時間、原因和指標快照。演練要證明失敗會停止擴大,而不是只證明 API 回傳 200。
設計取捨與邊界
原生 RollingUpdate 與漸進式控制器
RollingUpdate 適合只需要副本逐步替換和就緒檢查的服務。按流量、業務指標、人工批准和自動回滾出現時,需要額外控制器或平台能力;不能把副本比例當成請求比例。
自動回滾與人工決策
硬門禁適合高置信度、可快速檢測的故障;業務指標延遲大或解釋成本高時,自動動作應先暫停並通知負責人。策略必須明確誰擁有最終停止權。
全域統一與地域獨立
統一推進簡單但放大單地域風險;地域獨立更安全卻需要更多狀態和容量。選擇取決於流量隔離、資料駐留和故障域邊界。
失敗演練與演進計畫
失敗:把 canary 副本比例當作流量比例
實例數不等於請求數,連線重用和地域流量會讓實際權重偏離。用路由層按請求鍵分配並記錄命中計數。
失敗:指標缺失時繼續推進
查詢延遲、標籤錯誤或小樣本可能返回空結果。缺失預設暫停,恢復後重新建立完整窗口。
失敗:只回滾應用映像
不可逆 schema、事件或快取寫入可能讓舊版本無法讀取。發布前做相容性門禁,回滾先切流量,再按資料策略處理。
常見誤區與追問
誤區:狀態機寫在控制器記憶體裡
重啟會丟失階段、批准和回滾版本。持久化發布資源與稽核事件,記憶體只做快取。
追問:如何防止舊控制器覆蓋新發布?
用資源版本、階段版本和條件更新;寫入前重新讀取,發現版本變化就停止舊動作。
追問:如何處理兩個發布同時進行?
按服務或路由建立互斥策略,或明確定義多候選流量預算;不能讓兩個控制器獨立修改同一權重。
追問:為什麼 p99 變差但平均延遲正常?
平均值會隱藏少量嚴重慢請求。護欄應按相同版本、地域和分母比較尾延遲與錯誤率。
追問:指標系統掛了怎麼辦?
暫停推進並標記 ANALYSIS_UNAVAILABLE,保留目前權重;恢復後重新跑窗口,不把缺失資料當成功。
追問:如何衡量發布控制器本身?
監控階段停留時間、實際與目標權重偏差、誤回滾率、檢測延遲、恢復時間、稽核完整性和人工覆蓋次數。