進階持續部署 – 使用 Blue/Green、Canary 降低發版風險

POSTED BY   Chris
2021 年 8 月 22 日
進階持續部署 – 使用 Blue/Green、Canary 降低發版風險

繼之前寫過的一篇 持續部署 – 使用 ECS Rolling Update 實現 zero downtime 後,這次來介紹更進階的藍綠部署(Blue/Green) 和金絲雀部署 (Canary),Canary 算是 blue/green 的延伸應用,因為是基於 Blue/Green 的機制下去實現的,相較於 Rolling Update 的方式,Blue/Green 的方式在部署上更具備彈性,因為是新舊版本同時並存,在部署期間測試並發現任何問題後,都可以快速 Rollback 回舊版本,故彈性大、風險小。

 

優缺點

優點

  • Zerodowntime: 這點跟 rolling update 有一樣的優點,這邊就不贅述

  • 相較於 rolling update 在部署期間有 Request 進來時,有一段時間是可能訪問到舊版,也可能訪問到新版本,而 Blue/Green 則可以使用一次性部署 (All-at-once),把流量一次性切換到新版本,此種好處在於,若發版的應用程式因為任何考量不能向下相容(如 DB Schama、Third party API 等等…),使用此方式比較不會有後遺症

  • 降低發版風險: 以實務中,在上 production 前,理應在 staging 環境後就已經測試過,但儘管如此,在 production 中有可能因為 data 的問題,或是相依第三方服務的問題等等…,都可能導致 staging 無法完全模擬和 prodution 一模一樣的環境,故在 production 環境中測試是更直接了當的作法,可以使用 E2E testing(integration testing) 或 回歸測試(Regression Testing) 來確保新版本在生產環境的可靠性,若其間測試發現有問題,都可以快速的 rollback

  • 靈活的部署方式,以 AWS CodeDeploy 來說,目前支援以下 3 種

    • Canary: 金絲雀部署是一開始用小部分的流量轉移至 green(新版本),來達到降低風險,用小部分比例(例如 10% 流量)來實測功能是否有問題,至於要多少比例的流量轉移到新版本,而且需要多久時間來測試都是可以設定的
    • Linear: 線性式部署,例如每 5 分鐘轉換 10 percentage 的流量到新版本,以此例子,最終是 50 分鐘會完全轉換完畢
    • All-at-once: 一次性部署,也就是流量在一次性全部轉移至 green(新版本)
  • 實現 A/B Test: 從上一點的靈活部署方式,不難看出要實現 A/B Test,也是沒問題的,A/B Test 通常搭配埋入相關分析碼 (如 GA、FB Pixel 等…) 來觀測使用者使用狀況

缺點

  • 成本增加: 因為要準備兩套 production 環境可以隨時使用 Load Balancer 做切換,如果在 Cloud 上而且測試時間不長的話是還好,隨需付費,,而如果是地端(on-premise) 就需要準備一樣的硬體規格或 VM等等…,成本

  • 資料庫問題: 如果新版本是需要動到 DB Schema,那問題可能會變的相對複雜很多,近年來許多 DB migraion tool 已經可以跟 application 一起發版,方便管理,也可輕易的 rollback,然而棘手的還有「資料」本身,而這也牽扯許多複雜的問題,而解法例如有 data 本身也需要有版本識別,而也有一種作法是 DB 的異動都做成相容性 (Compatible),類似欄位只新增,不刪除,想要刪除的欄位就標示棄用就好,相容於應用程式新舊版可同時使用等等…

 

AWS CodeDeploy 應用於 ECS 部署的生命週期事件

這邊先看一下 CodeDeploy 支援 ECS 部署中,可以使用哪些生命週期事件 Hook,這些 Hook 可以對應到部署流程中的過程(稍後會說明),先了解再搭配部署流程會更清楚,先來看一張圖

Hint: 點圖片可放大

圖片出處在 AWS 官方文件

這些 hook 是定義在 appspec.yaml 檔案中,可以看到淺藍色方塊就是可以自訂義 lambda 的部分,有 5 個可以自訂義的 event 如下

  • BeforeInstall – 安裝 green instance 之前

  • AfterInstall – 安裝 green instance 之後

  • AfterAllowTestTraffic – Test traffic 已經可以導到 green instance,也就是 ALB or NLB Listener 已經導到 Green Target Group,可以測試新版本而不影響舊版本

  • BeforeAllowTraffic – 切換到生產環境流量到 green instances 之前

  • AfterAllowTraffic – 切換到生產環境流量到 green instances 之後

 

部署流程

以下是 AWS ECS on Fargate 使用 AWS CodeDeploy 來實現 Blue/Green Deployment 來說明 (以下圖片來源取自AWS 官方文件)

1. 進入部署流程之前

Hint: 點圖可放大

這邊對應到生命週期 Hook 會執行 BeforeInsall ,可以看一下圖式架構,基本上需要 ALB or NLB,並且需要兩個 Listener 和 Target Group,才能實作切換流量,而一開始當初就只有 Blue instance (此例為 ECS Task)

 

2. 安裝 Green instances

這邊對應到生命週期 Hook 是 Install,會把 Green instances 安裝好,以此例子,就是 ECS Service 中的新 task 都會啟動,並且把 Test Listener 的 Target Group 指向 Green 中的 ECS Task,而這一步完成之後,會執行生命週期 Hook AfterInstall

 

3. Test Listener 指向 Green Target Group

這邊對應到生命週期 Hook 的 AllowTestTraffic,到此階段,算是完整運行兩套 production 環境

再來會對應到生命週期 Hook 會執行 *** BeforeAllowTraffic***,注意這邊是把流量切換到新版 (green) 的最後一個 event hook,所以這階段就適合放 E2E Testing 等…,若測試失敗就可以 rollback,也不會影響任何線上的使用者

 

4. 流量切換到新版

這邊對應到生命週期 Hook 的 AllowTraffic,也就是 Production Listener 指向新版的 Target Group (green),而這邊也就是之前提到的可以用 3 種靈活的部署方式,分別為 Canary、Linear、All-at-once,差別在流量切換的比例

 

5. 刪除舊版實例 (blue instances)

這邊對應到生命週期 Hook 的 AfterAllowTraffic,到此結束,CodeDeploy 部署會回傳 Succeeded 狀態

以上為整個 Blue/Green Deployment 流程,因為有不少 event hook 可以用,所以靈活性相當高,相信要執行哪一種 Testing 都是可行的

 

結論

Blue/Green 的部署方式相較 Rolling Update,複雜度比較高,而如果產品很在乎在部署階段時,需要追蹤哪個用戶是用哪一個版本時,建議是用 Blue/Green,才能精準得知使用哪個版本,另外如果團隊很重視測試 Production 的穩定性後才正式發佈的話,Blue/Green 也是比較適合的

對於實作的部分,下一篇會再介紹,先提供完成的 CDK App Repo lab-ecs-fargate-cd-infra

歡迎留言
0

您可能也想看

Workaround for AWS Grafana alerting
2023 年 8 月 3 日
AWS, DevOps
AWS VPC Endpoint 使用場景
2022 年 3 月 14 日
AWS, CDK, Network
CDK 指定 Physical names 運作方式
2021 年 12 月 4 日
AWS, CDK, Cloudformation