如何在 Kubernetes 中對無狀態應用進行分批發布
在 Kubernetes 中針對各種工作負載,提供了多種控制器,其中 Deployment 為官方推薦,被用於管理無狀態應用的 API 物件。本文將結合 Deployment 的特性,與常見的釋出策略,以及我們在分批發布場景下的實踐,做一些分享。
使用 Deployment 的場景
Deployment 在 Kubernetes 1.9 版本後被晉升為 GA 版本,基於 Spec 定義管理 Pod,無需關心每個例項的部署結構差異。
對於日常應用變更,可以滿足如下典型場景:
• 應用變更,提供滾動升級策略,失敗自動暫停。
• 應用變更失敗,回滾到之前版本。
• 應用水平伸縮,支撐更高負載。
• 歷史資源回收,不需要手工回收 Pod 或 ReplicaSet 資源。
Deployment 提供了 RollingUpdate 滾動升級策略,升級過程中根據 Pod 狀態,採用自動狀態機的方式,通過下面兩個配置,對新老 Pod 交替升級,控制升級速率。
• Max Unavailable : 最大不可用例項數 / 比例。
• Max Surge : 排程過程中,可超過最大期望例項數的數 / 比例。
Kubernetes 生態中常見變更策略
基於 Deployment 的基礎功能,結合 Service / Ingress / Istio 等流量控制組件,常見如下幾種策略。具體對比分析與實現,可參考 網上文章 ,這裡不做過多展開:
- 滾動 Rolling:漸進式建立新版本,然後停止老版本,自動完成整個流程。
- 金絲雀 Canary:小部分流量,升級並匯入新版本,手工驗證完畢後,全量升級部署。
- 藍綠 Blue/Green:創建出新版本,與老版本並存,通過切換流量實現釋出與回滾。
-
重建 Recreate:殺死所有老版本,再用新版本重建。適用於開發、測試環境重新初始化。
-
A/B 測試:部署新版本,流量控制倒流,長期線上。嚴格來說,這是一種線上業務與商業化驗證的模式,不是變更策略。
為何需要分批暫停
在日常變更中,上述機制會讓變更變得簡單和便捷,但 Deployment 有如下限制:
• 需要手工回滾。
• 無法暫停滾動升級過程。
那麼客戶釋出過程中,經常會遇到哪些情況,導致釋出失敗呢?我們 在整理與分析客戶失敗的釋出時發現,主要出現在下面階段:
• 開始灰度釋出:因配置錯誤、打包異常、程式碼 BUG,或灰度後功能驗證中發現了問題。
• 灰度驗證成功,分批發布過程中:因網路白名單、資源不足、單機配置錯誤。
• 釋出上線後:客戶反饋、監控報警。
不難看出,一次常見的釋出,在不同釋出階段,需要一個手動的、可以更細粒度的控制,減少對線上的不良影響。所以滾動升級的分批暫停功能,對核心業務釋出來說,是質量保障必不可少的一環。那有沒有什麼方法,即可使用 Deployment 的滾動升級機制,又可以在釋出過程中,結合金絲雀釋出,分階段暫停釋出流程呢?
阿里在 K8s 中的分批發布實踐:手動灰度 + 自動 / 手動分批發布
在阿里巴巴內部,分批發布是最常見的釋出手段,用於保障線上釋出。結合“可灰度、可監控、可回滾”作為基本釋出要求,釋出階段可以分為主要兩個階段:
• 灰度階段:先灰度 1-2 臺,線上驗證流量正確性。該階段出現問題後,影響面可控、可快速回滾。大部分應用變更過程中,可能會出現的問題,均會在此階段被發現或暴露。
• 自動 / 手動分批階段:灰度成功後,一批批發布,為監控和報警,留足時間視窗,提前發現問題。
結合上述場景,我們採用管控 + 雙 Deployment 方式實踐了可暫停的分批發布。主要是基於如下兩種釋出策略的組合使用:
• Canary + Batch Rolling 策略結合。
• Canary : 灰度釋出 XX 臺,釋出後暫停。線上驗證流量。
• Batch Rolling : 分批發布 XX 批,釋出後自動 / 手動繼續釋出下一批。
針對具體釋出策略,我們的考慮和做法是這樣的:
• 建立新 Deployment : 新版本釋出,作為灰度驗證的部署例項,初始例項數為 0;
• 進入灰度階段:僅選取少量例項,擴容新版本 Deployment,縮容線上 Deployment;
• 進入分批階段:根據分批例項,自動變更新老 Deployment 例項;
• 回滾階段:反向做分批流程,將新版本例項數縮容到 0,老版本重新擴容到原有預期的例項數。
若釋出過程中出現異常狀態,如何及時發現錯誤,設定滾動升級卡點,或做到自動回滾呢?現在考慮如下:
• 自動健康檢查:結合應用 Liveness / Readiness 檢查配置,根據 Kubernetes Pod 狀態,若釋出過程中有任何釋出失敗情況,均停止當前批次新老 Deployment 的滾動升級操作。
• 終止釋出回滾:認為任何的釋出失敗,不應該是等待排查問題再發一次,而是應該第一時間回滾程式碼,保障線上業務質量,然後再考慮第二次變更。所以當未完成本次分批發布時,終止變更,會自動回滾本次變更。
思考
通過擴充套件滾動更新,提供手工分批能力後,還有更多可以保障釋出的策略與釋出。
• 對灰度釋出,結合流量控制規則,進行線上灰度驗證。
• 結合更多監控指標,與線上服務情況,確定指標基線,作為釋出卡點,讓分批發布更自動化。
作者簡介
孫齊(花名:代序),阿里巴巴高階工程師,負責企業級分散式應用服務 EDAS 及 EDAS Serveless 的開發和維護工作。