examlab .net 用最有效率的方法,考取最有價值的證照
本篇導覽 約 25 分鐘

CodeDeploy — Blue/Green、Canary 與 Rolling 部署

5,000 字 · 約 25 分鐘閱讀 ·

DOP-C02 深度解析 EC2 與內部部署伺服器的 CodeDeploy:藍綠部署 vs 就地部署、CodeDeployDefault 組態 (AllAtOnce, OneAtATime, HalfAtATime, Canary, Linear)、appspec.yml 生命週期掛鉤、自動回滾觸發器以及 ASG 整合。

立即做 20 題練習 → 免費 · 不用註冊 · DOP-C02

EC2 上的 CodeDeploy 是 AWS 期望每位 DOP-C02 考生都必須熟練掌握的部署協調器。與 ECS 或 Lambda 不同 —— 在那裡 CodeDeploy 主要是在路由層轉移流量 —— EC2 部署涉及代理程式 (agent) 安裝、檔案複製、在每台主機上執行生命週期指令碼,以及與 Auto Scaling 群組 (ASG) 和負載平衡器 (load balancer) 的緊密耦合。考試測試 appspec.yml 掛鉤 (hook) 順序、部署組態權衡、自動回滾 (auto rollback) 觸發器,以及就地 (in-place) 部署與藍綠 (blue/green) 部署之間的區別,情境通常是多個選項在技術上都可行,但只有一個能最大程度地減少停機時間、爆炸半徑或回滾時間。

本指南專注於專業級機制:在就地部署 vs 藍綠部署期間,哪些生命週期掛鉤按什麼順序觸發;CodeDeploy 在建立綠色機群 (green fleet) 期間如何與 ASG 互動;何時基於警示的回滾優於基於健康檢查的回滾;為什麼 OneAtATimeHalfAtATime 等部署組態帶有不同的營運風險;以及如何偵錯代理程式故障。讀完後,你應該能看穿任何 CodeDeploy EC2 問題並識別出缺失的部分 —— 通常是掛鉤順序、服務角色權限或警示組態 —— 而無需反覆閱讀題目。

為什麼 EC2 上的 CodeDeploy 在 DOP-C02 中如此重要

考試將 CodeDeploy 視為「部署安全思維」的代表。問題很少關於管線的銜接,而是探討你是否理解在部署期間主機上發生了什麼、在部分失敗的情況下回滾如何運作,以及哪種部署組態符合指定的 SLA。只有將 CodeDeploy 與 Auto Scaling 生命週期掛鉤、ELB 目標群組健康檢查和 CloudWatch 警示相結合時,才能展現其完整實力 —— 這正是 DOP-C02 所重視的多服務整合。

三個限制因素塑造了 CodeDeploy EC2 的設計選擇。第一,代理程式安裝:每個目標執行個體都必須執行 CodeDeploy 代理程式,並透過標籤或 ASG 成員身份註冊到部署群組。第二,部署組態:具名政策 (AllAtOnce, OneAtATime, HalfAtATime 以及自訂百分比組態) 決定了並行部署的執行個體數量和最低健康數量。第三,回滾政策:部署失敗、警示觸發或手動叫用時會自動回滾,但前提是必須存在先前成功的修訂版 (revision)。

  • 部署群組 (Deployment group):CodeDeploy 應用程式的一組邏輯目標執行個體或 Auto Scaling 群組;透過標籤或 ASG 名稱匹配目標。
  • 部署組態 (Deployment configuration):一個具名政策 (CodeDeployDefault.AllAtOnce, OneAtATime, HalfAtATime, 自訂百分比),控制並行性和最低健康數量。
  • 就地部署 (In-place deployment):將新修訂版部署到現有執行個體,停止並重新啟動每台主機上的應用程式。
  • 藍綠部署 (Blue/green deployment):佈建一個全新的 (綠色) 機群,在那裡部署新修訂版,轉移流量,然後視需求終止舊的 (藍色) 機群。
  • appspec.yml:來源套件中的一個 YAML 檔案,聲明檔案映射、權限和生命週期掛鉤指令碼。
  • 生命週期掛鉤 (Lifecycle hook):部署期間的一個具名點 (例如 BeforeInstall, ApplicationStart, ValidateService),在該點會於目標執行個體上執行指令碼。
  • CodeDeploy 代理程式 (CodeDeploy agent):安裝在每個目標執行個體上的常駐程式 (daemon),負責輪詢部署並執行掛鉤。
  • 自動回滾 (Auto rollback):一種部署群組設定,當部署失敗或警示觸發時,重新部署上一個已知的良好修訂版。
  • 原始環境 (Original Environment):藍綠部署中的藍色 (目前) 機群;替換環境 (Replacement Environment) 是綠色 (新) 機群。
  • 參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/welcome.html

白話文解釋 EC2 上的 CodeDeploy

EC2 部署在一次操作中混合了基礎設施、組態和協調。以下三個類比可以讓你掌握其機制。

類比 1:連鎖餐廳菜單更新

想像一家擁有 20 家分店的連鎖餐廳正在推出新菜單。就地部署是輪流向每家分店派遣一位企業培訓師;培訓師關閉廚房、更換菜單、重新培訓員工,然後重新營業。當廚房關閉時,無法接受訂單。部署組態 OneAtATime 是謹慎的版本 —— 一次只更新一家分店,速度慢但保留了營運能力。HalfAtATime 同時關閉十家分店以縮短更新時間。AllAtOnce 同時關閉所有 20 家 —— 速度最快但風險最大。

藍綠部署是在每家現有分店旁邊租用一棟新建築,配備新菜單和設備,開始營業,只有在新分店的訂單源源不斷後,連鎖店才會關閉舊建築。如果新菜單在綠色地點開張的第一個小時就遭到負評,顧客會立即被引導回仍然溫暖的藍色地點 —— 這就是回滾。

appspec.yml 是培訓師遵循的推出手冊:抵達、分發新制服 (BeforeInstall)、設置新菜單看板 (Install)、向廚房進行簡報 (AfterInstall)、開張營業 (ApplicationStart),以及為前 100 名顧客提供服務作為冒煙測試 (ValidateService)。每個掛鉤都是一個編號的清單項;弄錯順序 (在分發制服前進行簡報) 是常見的失敗原因。

類比 2:醫院設備升級

一家正在升級影像設備的醫院分階段部署軟體。就地是在週末修補現有機器 —— 每台機器速度慢、沒有額外的設備成本,但在修補期間放射科是離線的。藍綠是引進新機器,並行對其進行認證,一旦驗證通過就將病患流量轉向新機器;舊機器在正式停用前會保留 24 小時以備緊急回滾。

生命週期掛鉤是生物醫學工程師遵循的認證協定步驟BeforeInstall 是拆箱並驗證序號。AfterInstall 是開機診斷。ApplicationStart 是使用模型進行校準。ValidateService 是放射科醫生簽署驗收報告。每個步驟都是強制性且有序的。基於警示的自動回滾是醫院的安全官員在病患事件激增的那一刻自動將新機器移出場地 —— 無需人工即可實現緊急復原。

類比 3:航空母艦艦載機換裝

當一艘航空母艦更換其戰鬥機中隊時,聯隊長會精心策劃過渡。就地是停飛現有中隊進行改裝 —— 在換裝期間航艦沒有空中掩護。藍綠是將新中隊帶到補給艦上,在航艦上對其進行資格鑑定,然後移交指揮權 —— 舊中隊保持武裝並隨時待命,直到新中隊完成了三次戰鬥巡邏。

部署組態中隊輪換政策AllAtOnce 是戰時緊急情況:今晚更換所有飛機。OneAtATime 是平時流程:改裝一架飛機,另外 11 架保持警戒。HalfAtATime 是折衷方案 —— 六架上線,六架卸下 —— 用於大型演習。CloudWatch 警示觸發的回滾安全委員會主席,有權在失事率超過閾值的瞬間中止輪換並恢復先前的水準。

餐廳類比最能對應部署組態和客戶體驗。醫院類比在考試強調驗證掛鉤和驗收門檻時是正確的模型。航艦類比最適合理解高風險回滾和警示驅動的安全。參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-configurations.html

EC2 上的就地部署 vs 藍綠部署

在就地與藍綠之間做出選擇,是 CodeDeploy EC2 最常被考到的設計問題。

就地 (In-place):停止現有執行個體上的應用程式,複製新檔案,執行掛鉤,然後啟動應用程式。優點:成本最低 (無需重複機群)、回滾最簡單 (重新部署先前修訂版)、設置最快。缺點:交換期間各執行個體有停機時間、彙總更新速度較慢、部署期間容量會下降。

藍綠 (Blue/green):佈建一個與現有 ASG (或執行個體集) 匹配的新 ASG,在那裡部署新修訂版,可選用驗證流量,將負載平衡器轉向綠色機群,然後在終止藍色機群前等待一段可配置的終止期間。優點:零停機切換、即時回滾 (將流量重新導回仍然溫暖的藍色機群)、更好的驗證視窗。缺點:部署期間需支付 2 倍運算成本、設置較慢 (佈建綠色機群需要幾分鐘)、需要與負載平衡器整合。

考試的經驗法則:任何提到「零停機時間」、「快速回滾」或「在流量切換前進行驗證」的題目背景都暗示使用藍綠部署。提到「成本敏感的開發環境」或「小型機群,短暫維護視窗可接受」的題目則暗示使用就地部署。

部署組態詳解

CodeDeploy 內建了多種組態,並支援自訂組態。

CodeDeployDefault.AllAtOnce:同時向所有執行個體部署。最低健康數量為 0。更新速度最快,爆炸半徑最大。適用於開發/測試環境。

CodeDeployDefault.OneAtATime:一次向一個執行個體部署。最低健康數量為 總數 - 1。最安全,速度最慢。適用於更新時間可接受的小型機群。

CodeDeployDefault.HalfAtATime:向機群的一半部署,等待成功,然後再部署剩餘的一半。最低健康數量為機群的一半。平衡的選擇。

自訂組態 (Custom configurations):透過 CreateDeploymentConfig API 建立,使用 MinimumHealthyHosts (數量或百分比),或是針對 ECS/Lambda 使用 TrafficRoutingConfig。例如:MinimumHealthyHostsPercentage 75 允許同時有 25% 的執行個體離線。

對於藍綠部署,組態加上原始環境 (Original Environment) vs 替換環境 (Replacement Environment) 的行為非常重要:AllAtOnce 在綠色機群準備就緒後一次轉移所有流量;HalfAtATime 則分塊轉移 (較少見但支援)。

將組態與部署 SLA 匹配。AllAtOnce 以容量為代價將更新時間縮至最短。OneAtATime 以更新時間為代價將容量損失縮至最低。考試經常問「團隊希望在整個部署期間保持 75% 的容量,應選擇哪種組態?」 —— 答案是自訂組態 MinimumHealthyHostsPercentage 75,而不是任何預設組態。參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-configurations.html

appspec.yml 生命週期掛鉤順序

appspec.yml 檔案聲明了在具名生命週期事件中執行的掛鉤指令碼。掛鉤順序是固定的,也是考試的重點。

對於 EC2 上的就地部署,各執行個體上的掛鉤按此順序執行:

  1. ApplicationStop —— 停止執行中的應用程式 (在首次部署時會略過)。
  2. DownloadBundle (由 CodeDeploy 代理程式管理,使用者無法編寫指令碼)。
  3. BeforeInstall —— 在檔案複製前執行;用於安裝依賴項、設定目錄。
  4. Install (由 CodeDeploy 代理程式管理,根據 files 區段複製檔案)。
  5. AfterInstall —— 在檔案複製後執行;用於配置檔案、設定權限。
  6. ApplicationStart —— 啟動應用程式。
  7. ValidateService —— 執行冒煙測試;非零結束代碼會使該執行個體的部署失敗。

對於 EC2 上的藍綠部署,在負載平衡器切換之前會在綠色機群上觸發額外的掛鉤:

  • BeforeBlockTraffic, BlockTraffic, AfterBlockTraffic —— 從負載平衡器中取消註冊藍色執行個體時。
  • BeforeAllowTraffic, AllowTraffic, AfterAllowTraffic —— 註冊綠色執行個體時。

考試會測試字面上的掛鉤名稱和順序。常見陷阱:將 ValidateService (在啟動後執行) 與 BeforeAllowTraffic (在藍綠部署的流量轉移前執行) 混淆;將應用程式組態邏輯放在 ApplicationStart 而非 AfterInstall

當修訂版首次部署到某個執行個體時,ApplicationStop 不會執行,因為沒有安裝先前的修訂版。假設 ApplicationStop 總會執行 (例如清理目錄) 的指令碼在首次部署時會默默失敗。修正方法是讓 BeforeInstall 具備冪等性 (idempotent) —— 在那裡顯式清理狀態,不要依賴 ApplicationStop。考試非常喜歡考這個點。參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html

自動回滾政策 (Auto Rollback Policy)

當觸發以下情況時,自動回滾會重新部署上一個已知的良好修訂版:

  1. 部署失敗 (Deployment failure) —— 任何執行個體回報失敗 (可配置閾值)。
  2. 警示觸發 (Alarm trigger) —— 部署期間或部署後不久,與部署群組關聯的 CloudWatch 警示進入 ALARM 狀態。
  3. 手動 (Manual) —— 營運人員在主控台或透過 API 點擊回滾。

在部署群組中配置自動回滾:autoRollbackConfiguration.enabled: true, events: [DEPLOYMENT_FAILURE, DEPLOYMENT_STOP_ON_ALARM, DEPLOYMENT_STOP_ON_REQUEST],加上列出 CloudWatch 警示的 alarmConfiguration

基於警示的回滾是強大的專業級功能:將 ALB 目標群組的 5xx 錯誤率 警示與部署群組綁定,破壞生產環境健康的部署將在無需人工干預的情況下自動回滾。這是考試中典型的「部署安全」答案。

一個細微的限制:回滾是以新部署上一個修訂版的方式實作的,而不是對失敗部署進行事務性的撤銷。它會再次跑完所有掛鉤、需要時間,且回滾本身也可能失敗。對於藍綠部署,回滾速度更快 —— 它只需保持藍色機群存活並恢復負載平衡器即可。

Auto Scaling 群組整合

當部署目標為 ASG 時,CodeDeploy 會掛鉤到 ASG 生命週期以處理擴展事件。

對於到 ASG 的就地部署,CodeDeploy 在 ASG 上安裝一個生命週期掛鉤:當 ASG 向外擴展時,新執行個體進入 Pending:Wait 狀態,CodeDeploy 偵測到它,部署當前修訂版,然後執行個體進入 InService。這保證了新啟動的執行個體執行與機群其餘部分相同的修訂版。

對於藍綠部署,CodeDeploy 會佈建一個與原始 ASG 匹配的新 ASG (相同的啟動範本、相同的期望容量、相同的子網)。新 ASG 註冊到負載平衡器的目標群組;原始 ASG 則被取消註冊。在一段可配置的等待期後,原始 ASG 會被終止。

一個常見的 DOP-C02 模式:將 ASG 擴展政策與 CodeDeploy 結合,意味著擴展期間的新執行個體會自動接收當前的應用程式修訂版 —— 無需人工干預。請確保 ASG 的啟動範本引用的 AMI 已預先安裝 CodeDeploy 代理程式,或將代理程式安裝包含在使用者資料中。

用於部署安全的 CloudWatch 警示整合

透過部署群組中的三個開關將部署安全與警示聯繫起來:alarmConfiguration.enabled, alarmConfiguration.alarms[], 以及 alarmConfiguration.ignorePollAlarmFailure

當警示武裝後,CodeDeploy 在每次部署開始時和執行期間都會檢查它們。如果清單中的任何警示進入 ALARM,部署就會停止,並且 (如果啟用了自動回滾) 會重新部署先前的修訂版。

最佳實務警示:ALB 目標群組的 5xx 比率、應用程式發出的自訂指標 (請求延遲、錯誤數)、超過容量閾值的 CPU 使用率、非同步工作負載的 SQS 佇列深度。結合每小時對暫存環境執行的 CloudWatch Synthetic Canaries —— 失敗的 Canary 觸發警示,警示中止生產部署。

alarmConfiguration.alarms[] 中列出的警示必須存在於與部署群組相同的區域中。不支援跨區域警示。對於多區域部署,請在每個區域的部署群組中配置區域當地的警示。參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/deployments-rollback-and-redeploy.html

常見陷阱模式

陷阱 1:將就地回滾 (重新部署舊修訂版,慢) 與藍綠回滾 (重新導向流量,快) 混淆。提到「數秒內回滾」的題目背景暗示使用藍綠部署。

陷阱 2:忘記每個目標都必須執行 CodeDeploy 代理程式。沒有代理程式的新 AMI 會默默失敗,並顯示 agent not connected

陷阱 3:將配置邏輯放在 ApplicationStart 而非 AfterInstall。當 ApplicationStart 執行時,應用程式正在啟動;如果配置錯誤,應用程式會在 ValidateService 之前崩潰。

陷阱 4:假設 OneAtATime 意味著每個執行個體耗時一秒;它意味著一次一個執行個體,但每個執行個體仍需跑完完整的掛鉤生命週期 (可能耗時數分鐘)。

陷阱 5:在從未成功部署修訂版的情況下啟用自動回滾;第一次部署無法回滾,因為沒有先前的已知良好修訂版。

自動回滾會重新部署上一個成功的修訂版。在第一次成功部署之前,沒有先前的修訂版,因此失敗的首次部署無法回滾 —— 它會讓應用程式處於損壞狀態。在新的部署群組中,務必將一個已知的良好基準作為第一次部署。考試會透過「第一次金絲雀失敗且執行個體現在已損壞」的情境來測試這一點。參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/deployments-rollback-and-redeploy.html

端到端部署模式

典型的 DOP-C02 EC2 部署管線組裝如下:Source 從 CodeCommit 提取。CodeBuild 中的 Build 產生部署套件 (包含應用程式檔案和 appspec.yml 的 Zip)。使用 CodeDeployDefault.OneAtATime 部署到暫存環境,針對具有 4 個執行個體的 ASG;警示組態監控目標群組的 5xx 比率。核准 (Approval) 動作暫停以待發行經理簽署。生產部署使用藍綠部署,配合自訂組態,在綠色機群驗證後一次性轉移所有流量;針對四個生產警示 (5xx, p99 延遲, CPU, 佇列深度) 武裝自動回滾。

記住這個形狀 —— 它是考試不斷變換考法的參考架構。

對於任何 CodeDeploy EC2 問題,請錨定這四個部分:

  1. 部署類型:就地部署 (成本較低、回滾較慢) 或藍綠部署 (零停機、快速回滾)。
  2. 部署組態AllAtOnce / OneAtATime / HalfAtATime / 自訂 MinimumHealthyHostsPercentage
  3. appspec.yml 掛鉤順序:ApplicationStop → BeforeInstall → AfterInstall → ApplicationStart → ValidateService (加上藍綠部署特有的掛鉤)。
  4. 自動回滾:由部署失敗或 CloudWatch 警示觸發,需要先前的成功修訂版。

任何 CodeDeploy EC2 問題都可以對應到這四個部分之一。參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/welcome.html

常考陷阱(Common Exam Traps)

  1. 首次部署無法自動回滾 —— 自動回滾會重新部署先前的成功修訂版;如果沒有成功紀錄,失敗的首次部署會導致執行個體損壞。
  2. 混淆 ValidateService 與 BeforeAllowTraffic —— ValidateServiceApplicationStart 之後執行 (各執行個體的冒煙測試);BeforeAllowTraffic 僅限藍綠部署,且在流量註冊到綠色機群前執行。
  3. 自訂 AMI 中未安裝 CodeDeploy 代理程式 —— 沒有代理程式,執行個體永遠收不到部署;請在 AMI 中預裝或使用使用者資料。
  4. MinimumHealthyHosts 百分比取整錯誤 —— 對於具有 4 個執行個體且 MinimumHealthyHostsPercentage 75 的機群,CodeDeploy 會進位至需要 3 個健康執行個體,僅允許 1 個離線;假設 6 個執行個體機群可有 25% 離線 (1 個執行個體) 的設計可能不符合預期行為。
  5. 警示跨區域不匹配 —— alarmConfiguration.alarms[] 中列出的警示必須與部署群組位於同一區域;跨區域警示會被默默忽略。

FAQ

Q1:如果同時配置了藍綠和就地部署,CodeDeploy 會如何選擇? 部署群組的 deploymentStyle 設定 (IN_PLACEBLUE_GREEN) 在建立群組時就固定了。要切換樣式,請建立一個新的部署群組。不存在自動的按次部署切換開關。

Q2:單個部署群組可以同時以 EC2 執行個體和 ASG 為目標嗎? 可以,透過基於標籤的目標定義。獨立 EC2 執行個體和由 ASG 啟動的執行個體上的標籤都符合條件。但是,部署群組必須具有 ASG 名稱目標或基於標籤的目標 —— 在同一個群組中結合 autoScalingGroupsec2TagFilters 意味著 CodeDeploy 的目標是兩者的聯集 (union)

Q3:如何在成功的藍綠切換後保持藍色機群執行 24 小時? 將部署群組的 terminateBlueInstancesOnDeploymentSuccess.action 設定為 KEEP_ALIVE,並將 terminationWaitTimeInMinutes 設定為 1440 (24 小時)。CodeDeploy 會在等待期內保持藍色機群執行,但會從負載平衡器中取消註冊;如果觸發回滾,藍色機群會重新註冊。

Q4:部署失敗回滾與基於警示的回滾有什麼區別? 部署失敗回滾在 CodeDeploy 本身回報部署失敗時 (掛鉤指令碼結束代碼非零、執行個體無法存取等) 觸發。基於警示的回滾在綁定的 CloudWatch 警示於部署期間進入 ALARM 時觸發,即使所有掛鉤都成功了也是如此 —— 這能捕捉到 CodeDeploy 無法直接偵測到的應用程式層失敗。

Q5:EC2 上的 CodeDeploy 與 ECS 上的 CodeDeploy 有何不同? 在 EC2 上,CodeDeploy 透過代理程式直接在主機上執行掛鉤指令碼,並將檔案複製到執行個體檔案系統。在 ECS 上,CodeDeploy 建立新的任務定義並轉移 ALB 目標群組流量;任務中不執行代理程式。ECS 僅支援藍綠部署;EC2 支援就地和藍綠部署。

Q6:我可以在不使用 Auto Scaling 群組的情況下使用 CodeDeploy 嗎? 可以。基於標籤的部署群組以獨立的 EC2 執行個體為目標。權衡是無法自動向新啟動的執行個體部署當前修訂版 —— 如果你啟動了一個帶有該標籤的新執行個體,必須手動對其觸發部署。

Q7:為什麼我的部署卡在 Waiting 狀態? 最常見的原因:(1) 目標執行個體上未執行 CodeDeploy 代理程式,(2) 執行個體沒有具備 codedeploy:* 權限且能存取修訂版儲存桶的 IAM 角色,(3) 執行個體到 CodeDeploy 公開端點的出站網路被封鎖,(4) ASG 生命週期掛鉤使執行個體無限期處於 Pending:Wait 狀態。

Q8:如何使用 CodeDeploy 安全地協調多區域發布? 每個區域一個部署群組,CodePipeline 中每個區域一個階段並具備並行部署動作,每個區域具備基於警示的自動回滾,外加一個頂層的 EventBridge 規則來偵測任何區域的失敗,並觸發 Step Functions 來回滾已完成的區域。這是專業級的多區域模式。

官方資料來源

更多 DOP-C02 主題