如何在 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 等流量控制組件,常見如下幾種策略。具體對比分析與實現,可參考網上文章 ,這裏不做過多展開:

  1. 滾動 Rolling:漸進式創建新版本,然後停止老版本,自動完成整個流程。

  1. 金絲雀 Canary:小部分流量,升級並導入新版本,手工驗證完畢後,全量升級部署。

  1. 藍綠 Blue/Green:創建出新版本,與老版本並存,通過切換流量實現發佈與回滾。

  1. 重建 Recreate:殺死所有老版本,再用新版本重建。適用於開發、測試環境重新初始化。

  2. 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的開發和維護工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章