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

ECS 與 EKS 容器部署策略

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

DOP-C02 深入探討 ECS 與 EKS 的容器部署策略:滾動更新、透過 CodeDeploy 實現的藍/綠部署、在 EKS 上透過 Argo Rollouts 與 Flagger 實現的金絲雀部署、ECS 服務部署斷路器、EKS 部署模式以及使用 ALB 進行流量轉移。

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

AWS 上的容器部署跨越了兩個截然不同的平台 —— ECS(具備 Fargate 或 EC2 啟動類型)和 EKS —— 每個平台都有其自身的部署策略機制、整合模式和考試相關的注意事項。DOP-C02 期望考生能流暢地掌握這兩個平台,因為現實世界中的 DevOps 工程師會根據團隊技能、生態系統擬合度和營運開銷在它們之間做出選擇。考試會測試您是否理解 ECS 的三種部署類型(滾動更新、透過 CodeDeploy 實現的藍/綠部署、外部控制器)、EKS 的 Kubernetes 原生滾動更新,以及在每個平台上進行金絲雀部署和漸進式交付的 AWS 推薦路徑。

本指南將 ECS 和 EKS 視為同一個問題的兩個軌道:如何安全地將新的容器映像從建置推送到生產環境?在 ECS 上,答案主要依賴於 CodeDeploy 針對 ECS 的藍/綠部署部署斷路器 (Deployment Circuit Breaker);在 EKS 上,則依賴於 Kubernetes Deployment 物件的語義,通常還會搭配 AWS App MeshArgo RolloutsFlagger 來實現金絲雀部署。到最後,您應該能夠面對任何容器部署問題並挑選出正確的原語,而不會在兩個生態系統之間產生混淆。

為什麼容器部署策略是專業級關注點

在 API 層級,容器部署看似簡單 —— aws ecs update-service --task-definition foo:42kubectl set image deployment/foo foo=registry/foo:42 —— 但底層卻極其複雜。這兩個 API 都會觸發編排流程,涉及新任務或 Pod 的排程、在負載平衡器目標群組中的註冊、舊任務的排空、健康檢查評估以及失敗時的回滾。考試會測試您是否理解這些編排選擇如何影響停機時間、爆炸半徑和回滾時間。

有三種力量將容器部署推向專業級難度。首先是任務和 Pod 的生命週期:任務/Pod 是逐漸啟動的,負載平衡器的健康檢查決定了流量何時開始流入;配置錯誤的健康檢查會將部署演變成故障。其次是部署配置微調:ECS 的 minimumHealthyPercentmaximumPercent,以及 Kubernetes 的 maxSurgemaxUnavailable,決定了舊任務被替換的激進程度 —— 正確的值取決於容量、成本和 SLA 約束。第三是與部署安全服務的整合:CodeDeploy 為 ECS 增加了金絲雀/線性流量轉移和基於警示的回滾;EKS 原生的替代方案包括 Argo Rollouts 和 Flagger,而這兩者都不是 AWS 受管的。

  • ECS 滾動更新 (Rolling Update):預設的 ECS 部署類型;受 minimumHealthyPercentmaximumPercent 控制逐漸替換任務。
  • ECS 藍/綠 (Blue/Green, CodeDeploy):服務上的部署類型 CODE_DEPLOY;CodeDeploy 配置一組綠色任務,轉移 ALB 流量,然後排空藍色任務。
  • ECS 部署斷路器 (Deployment Circuit Breaker):一種選用設定,用於監控部署健康狀況,並在任務重複失敗時自動回滾。
  • 任務集 (Task Set):一個 ECS 建構,代表服務中具備版本的任務集合;藍/綠部署為每次部署建立一個新的任務集。
  • minimumHealthyPercent / maximumPercent:ECS 服務配置,控制在滾動更新期間必須保持運行的任務數量以及可以額外啟動的任務數量。
  • EKS Deployment:一個 Kubernetes 物件,具有 RollingUpdateRecreate 策略;AWS 不會修改 Deployment 的語義。
  • maxSurge / maxUnavailable:Kubernetes Deployment 欄位,控制滾動更新的激進程度 —— 類似於 ECS 的百分比設定。
  • Argo Rollouts / Flagger:第三方 Kubernetes 控制器,提供金絲雀、藍/綠和漸進式交付;在 EKS 金絲雀場景中非常受歡迎。
  • 外部部署控制器 (External Deployment Controller, ECS):部署類型 EXTERNAL,透過任務集 API 將生命週期交由您自己的控制器管理。
  • 參考:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-types.html

白話文解釋 ECS 與 EKS 容器部署

容器部署可能會讓人感到抽象,因為任務和 Pod 的壽命很短,且編排過程是不透明的。以下三個不同領域的類比使這些機制變得具體。

類比 1:劇院演員更換

想像一個長期運行的劇院節目正在更換其主角。ECS 滾動更新就像是替補演員交換協議:在演出之間,更換一兩個演員,其餘人員繼續演出;觀眾每晚都會體驗到稍有不同的演員陣容,直到輪換完成。minimumHealthyPercent: 100maximumPercent: 200豪華輪換 —— 先讓新演員作為額外成員上場(因此舞台短暫地比平時更擠),一旦新演員就位,就遣散舊演員。minimumHealthyPercent: 50精簡輪換 —— 在交換期間允許演員陣容縮減到一半規模;成本較低,但如果有人感冒,風險較高。

透過 CodeDeploy 實現的 ECS 藍/綠部署則是第二階段排練:租下第二間劇院,在那裡完整排練新演員,進行總彩排,然後在首演之夜將持票者導向新劇院,而舊劇院則作為備案運行最後一場演出。如果首演之夜的評論很差,製作人可以立即將觀眾導回舊劇院。

EKS 滾動更新在機制上與 ECS 幾乎相同,但編排軟體不同 —— Kubernetes 是舞台經理而非 ECS。其原則映射得很清楚:maxSurge: 25% 表示在輪換期間可以增加 25% 的額外演員,maxUnavailable: 25% 表示最多可以缺席 25% 的演員。

類比 2:餐廳廚房班組交接

一家高流量餐廳在晚餐服務期間輪換其生產線廚師。任務Pod 就是在工作站上的廚師服務就是班組 —— 即全速出菜所需的廚師集合。滾動更新就是一次帶進一名新廚師;舊廚師完成當前訂單 (stopTimeout) 後下班,新廚師接手。minimumHealthyPercent: 100 表示班組永遠不會人手不足(新廚師加入,然後舊廚師離開)。minimumHealthyPercent: 50 表示最多有一半的人員同時離線 —— 出菜會變慢。

部署斷路器就是主廚取消輪換的權力:如果連續三個新廚師都燒焦了他們做的前三盤菜,主廚會取消輪換,送失敗的廚師回家,並召回經驗豐富的廚師來完成服務。客戶(負載平衡器流量)永遠不會知道出了問題 —— 他們只會注意到服務短暫變慢。

類比 3:飛航管制塔台軟體更新

更換航班追蹤軟體的 ATC 塔台對停機時間零容忍。就地滾動更新是不可想像的 —— 您不能在飛行途中重啟雷達。藍/綠部署是唯一可接受的方法:機場設立第二個控制室並安裝新軟體,管制員在那裡接受為期一週的培訓和認證,然後在週二凌晨 2 點流量較小時,將所有無線電通訊和雷達回傳導向新房間,同時舊房間保持預熱 4 小時以備回退。如果出現不可預見的軟體問題,管制員可以立即切換回去。

CodeDeploy 基於警示的回滾就是自動安全系統:CloudWatch 警示監控「管制員偵測到的飛機偏航」,如果在投用新房間的第一個小時內偵測到任何異常,則自動中止切換。無需人為決策。

劇院類比最適合視覺化滾動更新和百分比設定。餐廳類比最能對應到部署斷路器。當考試強調零停機時間、基於警示的安全性和預熱回退時,ATC 塔台類比是正確的模型。參考:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-types.html

ECS 部署類型一 —— 滾動更新 (Rolling Update)

預設的 ECS 部署是滾動更新,由兩個服務設定控制:minimumHealthyPercent(預設 100,範圍 0–100)和 maximumPercent(預設 200,範圍 100–200)。

minimumHealthyPercent 定義了部署期間運行任務的下限。maximumPercent 定義了上限 —— 即 ECS 超出預期數量可以啟動的額外任務。組合方式決定了激進程度:

  • min 100, max 200:先啟動新任務,待新任務健康後排空舊任務。容量不損失,部署期間成本加倍。預設且最常見。
  • min 50, max 100:縮減至一半,替換,再擴展回來。容量損失,無額外成本。適用於非生產或低流量環境。
  • min 100, max 100:不允許 —— 無法在不激增或不縮減的情況下替換任務。
  • min 0, max 100:ECS 可能在啟動新任務之前停止所有任務。部署期間完全停機。僅適用於批次作業。

滾動更新是 ECS 最簡單的路徑。權衡:回滾速度慢(需重新部署舊任務定義),且沒有內建的流量加權(您無法將 5% 的流量發送到新版本 —— 每個任務要麼接收完整流量,要麼完全沒有)。

ECS 部署類型二 —— 透過 CodeDeploy 實現藍/綠部署

對於需要流量加權和切換前驗證的部署,ECS 服務部署類型 CODE_DEPLOY 會將生命週期交給 CodeDeploy。

CodeDeploy 配置一個新任務集並使用新的任務定義,將其註冊到 ALB 上獨立的測試目標群組,運行 BeforeAllowTestTrafficAfterAllowTestTraffic 勾點(Lambda 函數),然後根據部署配置將生產流量從藍色任務集轉移到綠色任務集:

  • CodeDeployDefault.ECSAllAtOnce:綠色就緒後立即轉移所有流量。
  • CodeDeployDefault.ECSLinear10PercentEvery1Minutes(或 3 分鐘):線性遞增。
  • CodeDeployDefault.ECSCanary10Percent5Minutes(或 15 分鐘、30 分鐘):10% 金絲雀,然後一次性轉移 90%。

自定義部署配置允許任意的金絲雀或線性排程。

藍/綠部署需要兩個 ALB 目標群組(測試和生產群組),透過兩個接聽程式規則註冊到同一個接聽程式。CodeDeploy 切換每個規則路由到哪個目標群組 —— 這就是流量轉移在機械上的實際運作方式。

透過 CodeDeploy 實現的 ECS 藍/綠部署僅支持 ALB;NLB 和傳統負載平衡器 (CLB) 均不支持。部署需要兩個預先建立的目標群組(一個給藍色,一個給綠色),CodeDeploy 會在兩者之間輪換。題目提到「團隊使用 NLB」則排除了 ECS 藍/綠部署 —— 他們必須使用滾動更新或切換到 ALB。參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/deployments-create-ecs-bg.html

ECS 部署類型三 —— 外部控制器 (External Controller)

第三種部署類型 EXTERNAL 透過任務集 API 將所有生命週期交由您自己的控制器管理。適用於自定義漸進式交付工具或由服務網格驅動的部署。在考試中很少見,但值得知道它的存在。

ECS 部署斷路器 (Deployment Circuit Breaker)

當新任務重複無法啟動或無法通過健康檢查時,部署斷路器會自動回滾滾動更新部署。在服務中配置:deploymentConfiguration.deploymentCircuitBreaker.enable: truerollback: true

行為:ECS 在滾動部署期間監控任務啟動失敗情況。如果失敗次數超過閾值(閾值隨預期數量縮放,例如 1-3 個任務的閾值為 2,大型服務則更高),部署將被標記為失敗,並且(如果 rollback: true)將使用之前的任務定義重新部署。

這是藍/綠部署中 CodeDeploy 自動回滾的滾動更新對等功能。常見的 DOP-C02 干擾項模式:描述滾動更新無法偵測到錯誤部署的情境 —— 缺失的部分就是啟用斷路器。

部署斷路器在任務啟動失敗(映像提取錯誤、容器啟動失敗、任務立即崩潰)時觸發。它不會在任務變為健康後觸發應用程式層的 5xx 錯誤。若要捕捉應用程式錯誤,請結合 ALB 目標群組 5xx 上的 CloudWatch 警示,並讓該警示觸發 EventBridge 規則,運行 Lambda 調用 aws ecs update-service 並切回舊的任務定義。參考:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-circuit-breaker.html

EKS 部署機制

EKS 不會修改 Kubernetes Deployment 的語義。Kubernetes 內建的兩種策略是:

  • RollingUpdate(預設):受 maxSurgemaxUnavailable(計數或百分比)控制逐漸替換 Pod。類似於 ECS 滾動更新。
  • Recreate:停止所有舊 Pod,然後啟動新 Pod。相當於 ECS 的 min 0, max 100。僅適用於無法平行運行舊/新版本的狀態全應用程式。

原生 Kubernetes 直接支持金絲雀或真正的藍/綠部署。常見模式:

  • Argo Rollouts:一個基於 CRD 的控制器,增加了金絲雀、藍/綠和實驗策略,並與 ALB Ingress 控制器整合以進行流量加權。
  • Flagger:類似的功能,與 App Mesh、Istio 和 ALB 整合。
  • 雙 Deployment 交換:手動建立 v1 和 v2 Deployment,交換 Service 的選擇器 (selector)。較原始但有效。

對於 DOP-C02 來說,了解 EKS 金絲雀部署需要第三方控制器或基於 App Mesh 的流量轉移是關鍵見解。考試很少會要求深入了解 Argo Rollouts 的內部原理。

EKS 上的服務網格與流量轉移

AWS App Mesh(對新客戶已停用但在考試範圍內)和開源替代方案 (Istio, Linkerd) 可以在服務網格層實現細粒度的流量轉移。對於 DOP-C02,相關模式為:

  1. 將 v2 與 v1 一起部署,並使用相同的 Service 路由。
  2. 配置服務網格的虛擬服務,將 10% 的流量發送到 v2。
  3. 監控指標;逐步按 10% → 25% → 50% → 100% 遞增。
  4. 透過還原虛擬服務的權重來進行回滾。

隨著 AWS 將重心轉向 Amazon VPC Lattice,App Mesh 正在步入停用階段;對於目前的考試題目,提到「具備流量加權和 AWS 受管網格的 EKS 金絲雀部署」仍隱含指 App Mesh。新的設計可能會傾向於 Lattice。

針對容器的 ALB 目標群組健康檢查

容器部署的成敗取決於健康檢查的配置。ECS 和 EKS 都會將任務/Pod 註冊到 ALB 目標群組;配置錯誤的健康檢查會導致:

  • 錯誤的健康 (False healthy):任務在應用程式就緒之前就報告健康(例如框架啟動完成但資料庫連線仍在進行中) —— 流量被導入損壞的任務。
  • 錯誤的不健康 (False unhealthy):任務確實需要 60 秒來預熱,但健康檢查在 30 秒後就失敗 —— 部署不斷震盪,永遠無法穩定。

調整 HealthyThresholdCountUnhealthyThresholdCountHealthCheckIntervalSecondsHealthCheckTimeoutSeconds 以匹配應用程式真實的就緒狀況。對於 ECS,還要設定服務參數 healthCheckGracePeriodSeconds,在任務啟動後的初期給予寬限期。

當應用程式啟動時間長於 ALB 目標群組的 HealthCheckIntervalSeconds * UnhealthyThresholdCount 時,ECS 部署可能會重複失敗。修復方法是在 ECS 服務上設定 healthCheckGracePeriodSeconds —— 它會在任務啟動後的首個 N 秒內忽略健康檢查失敗。如果沒有它,啟動緩慢的應用程式會觸發斷路器回滾,即使沒有出錯。參考:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/update-service.html

ECS 容量提供者與部署互動

對於 EC2 啟動類型的 ECS,容量提供者 (Capacity Providers) 管理執行個體的縮放。在部署期間,容量提供者會自動擴展叢集底層的 ASG,以容納 maximumPercent 的任務激增。

一個常見的 DOP-C02 陷阱:在叢集尺寸剛好等於預期數量且無閒置容量的情況下,以 maximumPercent: 200 進行部署。新任務會排隊等待容量,部署停滯,最終觸發回滾。解決方案是預留叢集空間、啟用具備受管縮放功能的容量提供者,或使用 Fargate(無需容量規劃)。

EKS Pod 中斷預算與部署安全

EKS 增加了 ECS 所缺少的 Kubernetes 原生安全機制:Pod 中斷預算 (PodDisruptionBudgets, PDB)。PDB 宣告了在自願中斷(滾動更新、節點排空、叢集升級)期間,工作負載必須保持可用的最小 Pod 數量。

為了部署安全,PDB 確保滾動更新不會違反預算 —— 如果驅逐 Pod 會導致違反 PDB,Kubernetes 將拒絕驅逐。這對於狀態全或基於法定人數 (quorum-based) 的服務尤其重要,因為違反預算會導致停機。

常見陷阱模式

陷阱一:混淆 ECS 滾動更新百分比與 Kubernetes 的 maxSurge/maxUnavailable。它們行為相似但語義不同;考試不允許翻譯錯誤。

陷阱二:假設 ECS 藍/綠部署適用於 NLB。事實並非如此 —— 僅限 ALB。

陷阱三:啟用了斷路器,但期望它能捕捉應用程式的 5xx 錯誤;它僅能捕捉任務啟動失敗。

陷阱四:部署至 ECS 時未針對啟動緩慢的應用程式設定 healthCheckGracePeriodSeconds

陷阱五:假設 EKS 原生支持金絲雀部署;在沒有第三方控制器或服務網格的情況下,它是不支持的。

一個常見症狀:ECS 服務顯示 (service abc) was unable to place a task。原因通常是容量問題(叢集沒有足夠 CPU/記憶體的執行個體來容納激增的新任務)或網絡問題(awsvpc 模式任務在亞區中無可用 ENI)。解決方法是使用具備受管縮放功能的容量提供者,或者對於 Fargate,確保子網有足夠可用 IP 且未超過 ENI 配額。參考:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/update-service.html

端對端容器管道模式

一個正統的 DOP-C02 ECS 管道組成如下。來源在 CodeCommit 中。建置在 CodeBuild 中產生 Docker 映像,推送到 ECR,並發出 imagedefinitions.jsonappspec.yml 成品。部署至預備環境 (Staging) 使用啟用了斷路器的 ECS 滾動更新,部署到 Fargate 服務。核准動作暫停以等待發佈經理簽署。部署至生產環境使用 CodeDeploy for ECS 並配置藍/綠部署和 ECSCanary10Percent15Minutes 設定,並增加基於 ALB 5xx 錯誤率的警示自動回滾。

對於 EKS,將部署動作替換為 kubectl apply(通常透過運行配置了叢集權限的 kubectl 的 CodeBuild 階段)加上金絲雀部署的 Argo Rollouts 清單。

對於任何 ECS 或 EKS 部署問題,請錨定於:

  1. 平台:ECS (Fargate 或 EC2) 或 EKS。
  2. 部署類型:滾動更新 / 透過 CodeDeploy 實現的藍/綠 / 外部控制器 (ECS);RollingUpdate / Recreate / Argo Rollouts / Flagger / 基於網格 (EKS)。
  3. 容量激增:ECS min/maxPercent 或 Kubernetes maxSurge/maxUnavailable
  4. 安全網:ECS 部署斷路器、具備寬限期的 ALB 健康檢查、基於警示的回滾 (CodeDeploy)、Pod 中斷預算 (EKS)。

任何容器問題都能清晰地映射到這四點之一。參考:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-types.html

常考陷阱 (Common Exam Traps)

  1. ECS 藍/綠與 NLB 搭配 —— 不支持;僅 ALB 具備 CodeDeploy 所需的接聽程式規則交換機制。
  2. 期望斷路器捕捉 5xx 錯誤 —— 它僅捕捉任務啟動失敗;請搭配 CloudWatch 警示 + EventBridge 進行應用程式層的回滾。
  3. 缺少 healthCheckGracePeriodSeconds —— 啟動緩慢的應用程式在預熱前健康檢查失敗,觸發錯誤的回滾循環。
  4. 無第三方控制器的 EKS 金絲雀部署 —— Kubernetes Deployment 原生不支持流量加權的金絲雀部署;需要 Argo Rollouts、Flagger 或服務網格。
  5. 在無叢集空間的情況下設定 maximumPercent: 200 —— 激增的任務排隊等待容量;輪換停滯並最終失敗。

FAQ

Q1:何時應優先選擇 ECS 滾動更新而非透過 CodeDeploy 實現的藍/綠部署? 滾動更新更簡單、更便宜(無雙倍容量需求),且對於非關鍵工作負載來說速度更快。當題目提到零停機時間、流量加權金絲雀、切換前驗證或基於警示的回滾時,請選擇藍/綠部署。啟用了斷路器的 ECS 滾動更新可滿足大多數非關鍵需求。

Q2:如何在沒有 Argo Rollouts 的情況下在 EKS 上進行金絲雀部署? 使用 AWS App Mesh(雖然正在淡出)或 VPC Lattice 搭配加權目標群組。將 v1 和 v2 部署為獨立的 Deployment 且具備獨立的 Service,將虛擬服務或 Lattice 接聽程式指向兩者並設定權重,手動或透過自動化逐步調整權重。雖然較為繁瑣,但無需第三方 CRD。

Q3:我可以同時使用 ECS 服務自動縮放與滾動更新嗎? 可以。服務自動縮放根據指標調整預期數量;滾動更新在部署期間替換任務。它們可以完美配合:進行中的部署會尊重當前的預期數量,且部署期間的縮放事件會觸發額外的滾動替換。

Q4:如果 CodeDeploy ECS 藍/綠部署在流量轉移期間失敗會發生什麼? CodeDeploy 會自動回滾:它會將 ALB 接聽程式規則恢復為指向藍色任務集,排空綠色任務集並報告失敗。舊任務仍在運行,因此服務不會中斷。如果配置了 terminateBlueInstancesOnDeploymentSuccess,藍色任務集會在配置的等待時間內保留。

Q5:如何處理 EKS 上的狀態全工作負載滾動更新? 使用 Recreate 策略(有停機時間,但無平行運行的舊/新版本),或者對於分散式資料庫,切換到具備 OrderedReady Pod 管理功能的 StatefulSet。Pod 中斷預算確保在輪換期間維持法定人數。

Q6:ECS 滾動更新是否支持像 CodeDeploy 藍/綠那樣的流量加權? 不支持。滾動更新在單個任務的粒度上切換流量 —— 一個任務要麼有流量(在目標群組中註冊且健康),要麼沒有流量。沒有「將 10% 的流量發送到新任務」這種說法。若要實現加權轉移,請使用透過 CodeDeploy 實現的藍/綠部署。

Q7:為什麼我的 ECS 服務部署成功,但應用程式在部署後返回 5xx? 最有可能的原因是新的任務定義存在配置問題(遺漏環境變數、錯誤的映像標籤),導致運行時錯誤。ALB 健康檢查通過了(可能檢查的是 /health,即使業務邏輯失敗也會返回 200)。緩解措施:實作一個會測試真實依賴項的 /ready 端點,或者針對應用程式層錯誤率增加 CloudWatch 警示以觸發外部回滾。

Q8:如何編排多服務部署,其中服務 A 必須在服務 B 之前部署? 在 ECS 上:將 CodePipeline 的部署動作按順序串聯,每個服務一個。在 EKS 上:使用運行 kubectl apply 的 Kubernetes Job 並按順序執行,或將部署包裝在具有 helm.sh/hook: pre-install 註解的 Helm 傘型圖 (umbrella chart) 中。對於複雜的編排,請使用從每個服務拉取部署狀態的 Step Functions 狀態機來驅動部署。

官方資料來源

更多 DOP-C02 主題