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

以 ECS 與 ECR 部署容器

6,800 字 · 約 34 分鐘閱讀 ·

以開發者視角撰寫的 DVA-C02 容器部署學習指南:Dockerfile 最佳實踐(多階段建置、最小基礎映像檔、層次排序、非 root 使用者)、Amazon ECR 推送與認證、ECS 任務定義、網路模式、Secrets 注入、Log Driver、ECS 服務與部署斷路器、Fargate 啟動類型、EFS 與 FSx 掛載、AWS App Runner、AWS Copilot CLI 鷹架工具、ECS Exec、映像檔簽署、部署護欄等完整內容。

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

容器部署是 DVA-C02 開發者最需要紮實掌握的核心主題。DVA-C02 考試指南的任務陳述 3.1「將應用程式構件準備好以部署至 AWS」,以及任務陳述 3.2「在開發環境中測試應用程式」,都以容器部署技能為核心轉軸。本章將以 Developer Associate 真正需要的深度,完整講解 AWS 上的容器部署:包含多階段建置與非 root 使用者的 Dockerfile 實作演練、使用 AWS CLI 認證輔助工具的 Amazon ECR 推送流程、整合 Secrets Manager 的 ECS 任務定義、具備部署斷路器的 ECS 服務、AWS Fargate 平台版本、有狀態工作負載的 EFS 與 FSx 磁碟區掛載、零決策部署的 AWS App Runner、鷹架工具 AWS Copilot CLI,以及生產環境除錯用的 ECS Exec。容器部署在 DVA-C02 是以開發者為中心的主題,本章全程緊貼程式碼路徑展開。

AWS 上容器部署的定義

AWS 上的容器部署,是指開發者將應用程式程式碼打包成符合 OCI 標準的映像檔、推送至 Registry、宣告執行期契約(CPU、記憶體、網路、IAM、Secrets、日誌),再交由受管服務穩定執行容器的完整工作流程。DVA-C02 考試從六個具體面向測驗容器部署:

  • Dockerfile 撰寫 — 如何建置出小巧、安全且善用快取的映像檔。
  • Amazon ECR — 私有與公開 Registry、認證、標籤不可變性、生命週期政策、漏洞掃描。
  • ECS 任務定義 — 將 Dockerfile 輸出對應至執行中任務的 JSON 藍圖。
  • ECS 服務 — 維持期望數量、執行滾動部署並整合負載平衡器的長駐控制器。
  • Fargate 啟動類型 — 無需管理 EC2 主機的 Serverless 容器運算。
  • 開發者工具 — AWS Copilot CLI、ECS Exec、AWS App Runner 以及部署護欄。

容器部署在 DVA-C02 中與 iac-sam-cloudformation(同類的部署主題)緊密相鄰——CloudFormation 與 SAM 常將 ECS 任務定義和服務封裝成可重複執行的 Stack,而容器部署負責映像檔層與執行期契約。考試情境中預期兩者並用:「開發者希望零停機上線新映像檔版本」的答案是 ECS 滾動部署;「開發者希望在範本中宣告完整 Stack」則偏向 CloudFormation 或 CDK。

為何容器部署是開發者主題,而非架構師主題

SAA-C03 問的是「ECS vs EKS vs Lambda」,DVA-C02 假設你已選定容器,問的是「現在如何交付程式碼」。這個轉移改變了深度。DVA-C02 的容器部署期望你知道 ECR 登入的精確 docker CLI 參數、Secrets 注入的精確任務定義欄位、當新任務健康檢查失敗時 ECS 部署斷路器的精確行為,以及任務角色與執行角色的精確 IAM 分工。容器部署在 DVA-C02 是以考試題目形式呈現的開發者肌肉記憶。

白話文解釋

將容器部署印進腦海最快的方法,是從三個截然不同的視角做三角定位——夜市攤位、便當工廠與樂高展示盒。每個故事各自凸顯工作流程的一個支柱(映像檔 Registry、任務定義契約、執行期啟動選擇),合在一起就能讓 ECS、ECR、Fargate 不再混成一碗模糊的縮寫湯。

類比一 — 夜市攤位、中央廚房與食品安全局

把整個流程想像成台灣夜市的運作生態。docker build 就像師傅把菜單上的料理統一封進真空包裝袋,一旦封好,內容物就不可變動,外面只需要印上品項條碼(映像檔 tag)。Amazon ECR 是負責統籌管理的中央廚房倉儲——每袋食品進倉都要掃描條碼(tag)、過 X 光機(scan on push),並依保存期限制定上架規則(lifecycle policy)。夜市攤車師傅根據條碼從倉儲取貨,就是 ECS agent 用 digest 拉取映像檔;攤車本身駛入現場開始服務,就是 Fargate 任務啟動執行你的工作負載。若事後食藥署要稽查,查的是封裝時的批號(sha256 digest),而不是包裝袋的顏色(mutable tag)。這個類比讓 ECR 的角色一目了然:它不只是儲存空間,而是每個容器在出貨前必經的管制查核點。

類比二 — 連鎖便當工廠、品管手冊與換班機制

換個場景,想像一家連鎖便當工廠。你的應用程式是菜單,ECS 任務定義是每間門市都必須遵守的標準化作業手冊:要備哪些食材(環境變數)、哪個上鎖的保險箱存放秘方(透過 valueFrom 從 Secrets Manager 取得的 Secrets)、瓦斯桶容量上限是多少才算安全(CPU 與記憶體限制)、廚師必須穿什麼制服(IAM 任務角色),以及開店前哪位衛生稽查員要驗收(healthCheck 與 Target Group 探針)。幕後的中央工廠就是 ECS 服務控制器,確保任何時刻都有剛好 N 輛便當車在現場,任一輛故障就立即派車替補。當你改版手冊(新增任務定義 revision),服務會先並排讓新舊便當車同時上線,等稽查員給新車綠燈,再讓舊車有序退場。部署斷路器就是活動主辦人——若連續三輛新車都未通過驗收,他會直接喊停,確保午餐時段不會出現一堆壞掉的便當車讓客人餓肚子。

類比三 — 樂高積木、說明書與展示櫃

最後,想像一家樂高專賣店。Dockerfile 是零件清單加上組裝說明:一層一層地拼底板、牆壁、屋頂、公仔。多階段建置的差別在於:你是把成品連同所有備用零件和料件一起塞進箱子(又大又亂),還是只把完成品放進乾淨的展示盒(精巧又防竄改)。三種執行期選項就是三種展示方式。AWS Fargate 是博物館恆溫展示櫃——無塵、零維護,按分鐘計費,完全不碰硬體。ECS on EC2 是自家的玻璃展示架——若你本來就有家具,每平方公分的費用更低,但你得自己換燈泡、吸架上的灰塵、注意鉸鏈會不會鬆脫。AWS App Runner 是百貨公司裡的自動販賣機展示格——你遞進一組樂高,它負責打燈、安保,甚至能直接從你的 GitHub 書架上自動補貨。同一套積木模型,三種展示方式,考試最愛考哪種情境對應哪個展示格。

AWS 容器部署的 Dockerfile 最佳實踐

DVA-C02 考生必須能流暢地讀寫 Dockerfile。AWS 並未發明專屬的 Dockerfile 語法;同一份符合 OCI 標準的 Dockerfile,可在 ECS、EKS、Fargate、App Runner、Lambda 容器映像檔及本機 Docker 上執行。容器部署的品質,因此在 Dockerfile 這一層就已決定。

原則一 — 多階段建置以獲得小巧安全的映像檔

多階段建置使用一個階段來編譯或安裝相依套件,再用第二個(更小的)階段產生最終執行期映像檔。只有輸出的構件會被複製過去,因此建置工具、編譯器與開發相依套件永遠不會進入正式環境。

# Stage 1 — build
FROM public.ecr.aws/docker/library/node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2 — runtime
FROM public.ecr.aws/docker/library/node:20-slim
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
USER node
EXPOSE 8080
CMD ["node", "dist/server.js"]

多階段建置通常能將映像檔大小削減 60 至 80 百分比,攻擊面也等比例縮小。在 DVA-C02 中,任何「縮減映像檔大小」搭配 Dockerfile 的情境,答案都是多階段建置。

原則二 — 選擇最小化的基礎映像檔

基礎映像檔的選擇決定了映像檔大小、冷啟動時間(Fargate 佈建時需要拉取映像檔),以及 CVE 數量。AWS 容器部署的選擇優先順序:

  • 語言專屬 slim 映像檔node:20-slimpython:3.12-slim)— 通常是 Debian slim,維護良好。
  • Alpine 映像檔 — 更小,但使用 musl libc;偶爾對 native module 有相容性問題。
  • Distrolessgcr.io/distroless/...)— 只含執行期與你的二進位檔,沒有 Shell;適合 Go 與 Java,但沒有 ECS Exec 時較難除錯。
  • Amazon Linux 2023 基礎映像檔public.ecr.aws/amazonlinux/amazonlinux:2023)— 由 AWS 維護,與 Lambda 及 EC2 基礎 AMI 對齊。

在正式環境中,除非有明確理由,否則避免使用完整的 ubuntudebian 基礎映像檔。暗示「最小化映像檔大小」的容器部署情境,實際上是要你多階段建置並選擇 slim、Alpine 或 distroless 執行期映像檔。

原則三 — 依快取效益排列層次順序

Docker 根據每條指令及其輸入 hash 來快取各層。規則很簡單:把不常變動的指令放在常變動的指令之前。標準順序如下:

  1. FROM 基礎映像檔。
  2. 安裝系統套件(apt-get installapk add)。
  3. 複製相依套件清單(package.jsonrequirements.txtgo.mod)。
  4. 安裝相依套件。
  5. 複製應用程式原始碼。
  6. 若有需要,執行建置或編譯。
  7. CMDENTRYPOINT

若你在 RUN pip install -r requirements.txt 之前就 COPY . .,任何原始碼變動都會讓相依套件安裝快取失效。Dockerfile 層次排序是 DVA-C02 反覆出現的考題暗示。

原則四 — 正式環境絕不以 root 執行

Fargate 的 Firecracker 隔離讓容器逃逸更難發生,但深度防禦仍要求使用非 root 使用者。可以使用語言執行期映像檔內建的非 root 使用者(官方 node 映像檔已內建 node 使用者),或自行建立:

RUN addgroup -S app && adduser -S app -G app
USER app

若應用程式必須綁定 port 80,可執行反向代理,或在任務定義中使用 port 映射(容器 port 8080 透過負載平衡器對應至主機或目標 port 80)。

原則五 — 單一行程、宣告式 Entrypoint

容器執行一個行程(加上其子行程)。避免使用 supervisord 或 init wrapper;這些屬於有獨立任務定義容器項目的 Sidecar。使用 exec 形式的 CMDENTRYPOINT

CMD ["node", "dist/server.js"]

Shell 形式(CMD node dist/server.js)會將命令包在 /bin/sh -c 中執行,這會破壞訊號處理——ECS 在任務關閉時送出的 SIGTERM 永遠無法到達你的 Node 行程,任務逾時,滾動部署因此卡住。

在所有部署至 ECS 的 Dockerfile 中,CMDENTRYPOINT 必須使用 exec 形式。Shell 形式會將你的行程包在 /bin/sh 中,無法轉送 SIGTERM,導致 ECS 滾動部署觸及 stopTimeout(預設 30 秒,最長 120 秒)才強制 SIGKILL 終止容器。修正方式是改用 exec 形式,或以 tini 作為 PID 1 的 init。 Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

原則六 — 在 ECS 原生健康檢查不足時才加入 HEALTHCHECK

ECS 的健康狀態來源有二:任務定義中的 healthCheck 欄位(Docker 層級的 HEALTHCHECK),或負載平衡器的 Target Group。對 Web 工作負載,優先使用負載平衡器 Target Group(同時兼具流量路由功能);Dockerfile HEALTHCHECK 只保留給非 HTTP 工作負載或本機開發使用。

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD curl -fsS http://localhost:8080/healthz || exit 1

若服務位於 ALB 後方,ALB Target Group 健康檢查已控制流量路由,ECS 也會自動取消註冊不健康的任務。額外的 Dockerfile HEALTHCHECK 只會增加負擔與複雜度,並不提供新的訊號。只有非 HTTP 工作負載,或 Target Group 不在架構中時,才使用 Dockerfile HEALTHCHECK。 Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

Amazon ECR 容器部署深入解析

Amazon ECR 是 AWS 的容器 Registry,也是容器部署流程中的第二個站點。DVA-C02 對 ECR 的測驗相當深入,因為這是開發者筆電與 AWS 執行期之間的交接點。

使用 AWS CLI 向 ECR 認證

ECR 需要透過 aws ecr get-login-password 取得認證 token。標準推送流程如下:

# 1. 向 ECR 認證 Docker(12 小時有效 token)
aws ecr get-login-password --region us-east-1 \
  | docker login --username AWS --password-stdin \
  123456789012.dkr.ecr.us-east-1.amazonaws.com

# 2. 以完整 ECR URI 為本機映像檔加上 tag
docker tag myapp:latest \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1.2.3

# 3. 推送
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1.2.3

認證 token 有效期為 12 小時。在 CI/CD Pipeline 中,同樣的 get-login-password 指令也適用,因為它會從環境中讀取 IAM 憑證。

一個常見的開發者體驗升級是 Amazon ECR Docker Credential Helper。安裝後,在 ~/.docker/config.json 加入 {"credsStore": "ecr-login"}docker push 就能透明地使用你的 AWS 憑證,不再需要明確登入步驟。DVA-C02 關於 CI/CD 推送流程的問題常對比這兩種方式。

每個 ECR 私有 Repository 的 URI 格式為 <account-id>.dkr.ecr.<region>.amazonaws.com/<repository-name>:<tag>。Account ID 與 Region 隱含在 URI 中;在 tag 或 pull 時都必須完整帶入兩者。ECR Public Gallery 使用不同的主機名稱 public.ecr.aws/<alias>/<name>:<tag>,並以全球分散方式提供。 Reference: https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html

不可變 Tag 與 Digest 固定部署

ECR 對每個 Repository 支援兩種 tag 可變性模式:

  • MUTABLE(預設)— 相同 tag 可被新映像檔覆寫。用 latest tag 很方便,但對正式環境的可重現性有風險。
  • IMMUTABLE — 一旦分配 tag,不可覆寫或刪除。以相同 tag 重新推送會失敗。

正式環境的容器部署,應將 tag 可變性設為 IMMUTABLE,並依 digest(repo@sha256:...)或版本 tag(v1.2.3)部署。不可變 tag 搭配任務定義中固定 digest,是 DVA-C02「保證正式環境執行映像檔完全可驗證」的標準答案。

推送時掃描與增強掃描

ECR 提供兩種漏洞掃描模式:

  • 基本掃描 — 免費,在推送時對照 Clair CVE 資料庫掃描映像檔。一次性掃描,幾分鐘內出結果。
  • 增強掃描 — 由 Amazon Inspector 驅動,即使推送後也會持續重新掃描映像檔以偵測新 CVE,涵蓋作業系統與語言套件漏洞,按每個映像檔每月計費。

可針對個別 Repository 啟用推送時掃描。正式環境工作負載若有「持續掃描」或「針對新發現 CVE 發出警示」的需求,增強掃描是答案。

ECR 生命週期政策

ECR 生命週期政策會自動刪除未標記或過舊的映像檔,這對於 ECR 按 GB-month 計費的儲存成本控管至關重要。典型政策範例:

{
  "rules": [
    {
      "rulePriority": 1,
      "description": "保留最新 20 個已標記映像檔",
      "selection": {
        "tagStatus": "tagged",
        "tagPrefixList": ["v"],
        "countType": "imageCountMoreThan",
        "countNumber": 20
      },
      "action": { "type": "expire" }
    },
    {
      "rulePriority": 2,
      "description": "刪除超過 7 天的未標記映像檔",
      "selection": {
        "tagStatus": "untagged",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 7
      },
      "action": { "type": "expire" }
    }
  ]
}

生命週期規則以非同步方式套用——刪除通常在 24 小時內完成。DVA-C02 中「降低 ECR 儲存成本」的情境,答案幾乎都是生命週期政策。

跨帳號映像檔拉取

DVA-C02 常見的架構是在 AWS Organizations 下設有 dev、staging、prod 三個帳號。映像檔在 dev 帳號建置,再由 staging 與 prod 拉取。跨帳號存取透過 ECR Repository 政策(資源型政策)啟用,向其他帳號的 Principal 授予 ecr:BatchGetImageecr:GetDownloadUrlForLayer。拉取帳號的任務執行角色也需要針對自身帳號具備 ecr:GetAuthorizationToken

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "AllowPullFromProd",
    "Effect": "Allow",
    "Principal": { "AWS": "arn:aws:iam::444455556666:root" },
    "Action": [
      "ecr:BatchGetImage",
      "ecr:GetDownloadUrlForLayer"
    ]
  }]
}

Amazon ECR Public Gallery 在 public.ecr.aws/ 下托管公開存取的映像檔。AWS 在此發布基礎映像檔(Amazon Linux、Lambda 執行期、EKS distro),第三方也可發布。匿名拉取無需認證;透過 aws ecr-public get-login-password 認證後拉取則能提高速率上限。在容器部署中,Dockerfile 改從 public.ecr.aws 拉取公開基礎映像檔,可避免 Docker Hub 的速率限制(匿名使用者每 6 小時僅能拉取 100 次)。

先以 aws ecr get-login-password --region <r> | docker login --username AWS --password-stdin <account>.dkr.ecr.<r>.amazonaws.com 認證,再以 docker tag local:tag <account>.dkr.ecr.<r>.amazonaws.com/<repo>:<tag> 加 tag,最後以 docker push <account>.dkr.ecr.<r>.amazonaws.com/<repo>:<tag> 推送。認證 token 有效 12 小時。這三步驟序列是 DVA-C02 最常考的 ECR 實作流程。 Reference: https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry_auth.html

ECS 任務定義 — 執行期契約

ECS 任務定義是告訴 ECS 如何執行容器的 JSON(或透過 SAM / CloudFormation 的 YAML)藍圖。DVA-C02 期望你熟悉欄位細節——以下是必備知識。

任務層級欄位

  • family — 邏輯名稱;任務定義以 family:revision 方式版本化。
  • requiresCompatibilities["FARGATE"]["EC2"] 或兩者並列。
  • networkModeawsvpc(Fargate 必填)、bridgehost,或 none(僅限 EC2)。
  • cpumemory — 整個任務的總量。Fargate 有固定支援的組合(0.25 vCPU 搭配 0.5–2 GB,最高至 16 vCPU 搭配 30–120 GB)。EC2 則較彈性。
  • executionRoleArn — Fargate / ECS 代替你執行操作的 IAM 角色,用於拉取 ECR 映像檔、從 Secrets Manager 取得 Secrets 值、透過 awslogs 寫入 CloudWatch Logs。使用 ECR 私有 Registry、Secrets 或 awslogs 時為必填。
  • taskRoleArn — 容器內應用程式程式碼用於呼叫 AWS API 的 IAM 角色(讀取 S3、寫入 DynamoDB)。這是「應用程式」角色。
  • volumes — bind mount、Docker volume、EFS volume、FSx volume。

容器層級欄位

任務定義 containerDefinitions 陣列中的每個項目,代表任務中的一個容器:

  • name — 供 dependsOn 與服務負載平衡器使用的識別符。
  • image — 含 tag 或 digest 的完整 ECR URI。
  • essential — 若為 true(第一個容器的預設值),此容器停止時整個任務跟著停止;非 essential 容器失敗不會拖垮任務(常用於 Sidecar)。
  • cpumemorymemoryReservation — 容器層級的資源限制;必須符合任務層級的總量。
  • portMappingscontainerPortprotocol。在 Fargate(awsvpc 模式)下,hostPort 必須等於 containerPort。在 EC2 bridge 模式下,hostPort: 0 表示動態 port 映射(ALB Target Group 會登記實際的主機 port)。
  • environment — 純文字環境變數,格式為 {"name": "LOG_LEVEL", "value": "info"}
  • secrets — 透過 valueFrom 從 Secrets Manager 或 SSM Parameter Store 取得的環境變數,在容器啟動時解析,不會寫死進任務定義。
  • healthCheck — Docker 層級的健康檢查命令、間隔、逾時、重試次數、啟動緩衝期。
  • dependsOn — 宣告此容器的啟動或停止取決於另一個容器的狀態(例如:等待資料庫遷移 Sidecar 以 SUCCESS 退出後,應用程式容器才啟動)。
  • logConfiguration — Log Driver(awslogsawsfirelenssplunksyslog)及其專屬選項。

網路模式

ECS 支援四種 networkMode 值;選擇影響隔離性、效能與 port 行為。

  • awsvpc — 每個任務獲得自己的 ENI,帶有主要私有 IPv4 及可選 IPv6。Fargate 強制使用。支援在任務層級附加 VPC Security Group。同一主機上不同任務因各有 ENI 而無 port 衝突。大多數工作負載的建議選項。
  • bridge — 主機上的 Docker 預設虛擬網路。支援動態 port 映射。僅限 EC2 啟動類型。適合在單一主機上密集運行大量小型任務。
  • host — 容器共享主機的網路命名空間。無網路隔離;若兩個任務使用相同 port 會衝突。僅限 EC2。網路效能最高。
  • none — 無外部網路連線;很少使用。

Fargate 任務必須使用 awsvpc。對 EC2 啟動的任務,awsvpc 通常仍是正確選擇,因為它讓每個任務擁有專屬 Security Group、消除 port 衝突,並能使用 PrivateLink / VPC Endpoint。僅在 EC2 高密度、成本緊張的情境下才選 bridge。 Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html

透過 valueFrom 注入 Secrets

絕對不要將 Secrets 寫死進 Dockerfile 或任務定義 JSON 的環境變數中。使用 secrets 陣列,在容器啟動時從 AWS Secrets Manager 或 SSM Parameter Store 拉取值。

"secrets": [
  {
    "name": "DB_PASSWORD",
    "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/db-AbCdEf:password::"
  },
  {
    "name": "API_KEY",
    "valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/prod/api-key"
  }
]

任務執行角色需要 secretsmanager:GetSecretValuessm:GetParameters(若 Secret 以客戶自管 KMS 金鑰加密,還需要 kms:Decrypt)。Secret 以環境變數形式注入容器;從應用程式角度看,與一般 environment 項目完全相同。Secrets Manager 支援以 secret-arn:json-key:: 格式指定 JSON 金鑰,讓單一 Secret 為多個環境變數提供值。

健康檢查與相依順序

dependsOn 讓多容器任務擁有有序的生命週期。範例——資料庫遷移 Sidecar 必須完成後,主應用程式才啟動:

"containerDefinitions": [
  {
    "name": "migrate",
    "image": "...migrator:v1",
    "essential": false,
    "dependsOn": []
  },
  {
    "name": "app",
    "image": "...app:v1",
    "essential": true,
    "dependsOn": [
      { "containerName": "migrate", "condition": "SUCCESS" }
    ]
  }
]

支援的條件:STARTCOMPLETESUCCESSHEALTHYSUCCESS 表示被依賴的容器以 exit code 0 退出。HEALTHY 需要該容器的 Docker HEALTHCHECK 通過。

日誌設定 — awslogs 與 FireLens

awslogs Driver 是 ECS 容器日誌的預設選項。設定 Log Group、Stream 前綴與 Region:

"logConfiguration": {
  "logDriver": "awslogs",
  "options": {
    "awslogs-group": "/ecs/myapp",
    "awslogs-region": "us-east-1",
    "awslogs-stream-prefix": "app",
    "awslogs-create-group": "true"
  }
}

若需要更複雜的日誌路由——多目的地、過濾、解析——可使用 AWS FireLens,以 Fluent Bit(或 Fluentd)Sidecar 將日誌轉送至 CloudWatch Logs、Amazon OpenSearch Service、Amazon Kinesis Data Firehose、Amazon S3,或 Datadog、Splunk 等第三方服務。

{
  "name": "log_router",
  "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
  "essential": true,
  "firelensConfiguration": { "type": "fluentbit" }
}

接著應用程式容器的 logConfiguration 使用 awsfirelens 作為 Driver,FireLens 依 Fluent Bit 設定進行路由。

ECS 服務 — 維持任務運行並安全部署

ECS 服務是長駐控制器,維持期望數量的任務實例、整合負載平衡器、處理滾動或藍/綠部署,並驅動 Service Auto Scaling。DVA-C02 對服務設定與部署行為的測驗相當深入。

服務核心元件

  • desiredCount — 要執行的任務數量。
  • launchTypeFARGATEEC2,或 EXTERNAL(用於客戶自管主機的 ECS Anywhere)。
  • deploymentControllerECSCODE_DEPLOY,或 EXTERNAL
  • loadBalancers — Target Group ARN、容器名稱、容器 port。服務在擴縮與部署事件時自動在 Target Group 中登記或取消登記任務 ENI。
  • serviceRegistries — 用於以 DNS 進行服務探索的 AWS Cloud Map。
  • networkConfigurationawsvpc 任務的子網路與 Security Group。
  • deploymentConfiguration — 控制滾動行為(最小/最大健康百分比、斷路器)。

部署控制器

三種部署控制器類型決定新任務定義 revision 如何取代舊版。

  • ECS 控制器(滾動更新) — 預設。ECS 啟動新任務,等待健康狀態確認,再排空並停止舊任務。可透過 minimumHealthyPercent(預設 100)與 maximumPercent(預設 200)設定。最簡單也最常見。
  • CODE_DEPLOY 控制器(藍/綠) — AWS CodeDeploy 在第二個 Target Group 上啟動新任務集,執行 Hook,以全量切換或金絲雀 / 線性百分比方式調整 ALB 監聽規則從藍切換至綠,並可在 CloudWatch 警示觸發時回滾。需要明確驗證視窗的真正藍/綠部署使用此方式。
  • EXTERNAL 控制器 — 由你或第三方工具(如 Spinnaker)透過 ECS API 驅動任務集。較少見。

部署斷路器

ECS 部署斷路器會自動停止並選擇性回滾失敗的滾動部署。啟用後,ECS 追蹤失敗的任務啟動次數,若過多新任務無法達到健康狀態,便將部署標記為 FAILED,並選擇性地重新部署前一個任務定義 revision。

在服務的 deploymentConfiguration 中啟用斷路器:

"deploymentConfiguration": {
  "deploymentCircuitBreaker": {
    "enable": true,
    "rollback": true
  },
  "minimumHealthyPercent": 100,
  "maximumPercent": 200
}

沒有斷路器時,一個有問題的新任務定義可能讓 ECS 無止盡地嘗試啟動失敗任務,浪費費用並可能破壞流量分配。DVA-C02 中「安全滾動部署」的情境,答案幾乎都是啟用 rollback 的部署斷路器。

DVA-C02 有一個陷阱,在 CodeDeploy 藍/綠情境中提供「啟用部署斷路器」作為答案。斷路器只在 deploymentControllerECS 時有效。CodeDeploy 藍/綠的回滾,是透過部署群組中的 CloudWatch 警示與 CodeDeploy Hook 生命週期來控制的。 Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-type-ecs.html

Service Auto Scaling

ECS 服務透過 Application Auto Scaling 進行水平擴展。三種政策類型:

  • 目標追蹤 — 「維持 CPU 在 60 百分比」或「維持 ALBRequestCountPerTarget 在 500」。最簡單且建議優先使用。
  • Step Scaling — CloudWatch 警示閾值觸發步進式數量變化。
  • 排程擴展 — 基於 Cron 的最小/最大邊界設定。

目標追蹤 ALBRequestCountPerTarget 是 DVA-C02「依流量擴展服務」的標準答案。當 ALB 不在架構中時,目標追蹤 ECSServiceAverageCPUUtilization 是備用答案。Auto Scaling 在 minCapacitymaxCapacity 之間調整服務的 desiredCount

負載平衡器整合

服務在任務啟動時將每個任務的 ENI + containerPort 登記至 Target Group,停止時取消登記。對 awsvpc + Fargate,Target Group 的目標類型必須是 ip(不是 instance)。Target Group 的取消登記延遲(連線排空)決定負載平衡器向正在停止的任務繼續送出現有連線的時間——預設 30 秒,建議調高至應用程式最長請求時長。

AWS Fargate 啟動類型 — Serverless 容器執行期

AWS Fargate 是 ECS 與 EKS 的 Serverless 啟動類型。DVA-C02 將 Fargate 定位為「如何避免管理 EC2」——開發者進行新容器部署的預設選擇。

從開發者視角比較 Fargate 與 EC2 啟動類型

  • 無需修補、調整大小或 Auto Scale EC2 執行個體。沒有「容器執行個體」概念。
  • 按任務保留的 vCPU 與記憶體,以秒計費。
  • 任務層級的 Firecracker microVM 隔離。
  • 固定支援的 CPU / 記憶體組合。
  • 每個新任務的佈建時間為 20 至 60 秒。
  • 平台版本(見下方)控制功能支援。

在 DVA-C02 中,只要情境提到「最小化營運負擔」、「無需管理 EC2」或「開發者希望專注於程式碼」,答案就是 Fargate。

Fargate 平台版本

Fargate 平台版本是 Fargate 的執行期發行版(類似任務的作業系統核心)。各版本新增功能——更大的 /tmp、新 CPU 架構、新磁碟區類型。

  • LATEST — 目前建議版本。
  • 固定版本(例如 1.4.0)— 穩定,直到明確更新為止。

DVA-C02 的一個重要細節:某些功能(EFS 磁碟區掛載、預設 20 GB 暫時儲存空間、ARM Graviton 支援)需要特定平台版本。若任務定義引用了固定平台版本不支援的功能,任務啟動會失敗。正式環境務必明確固定版本,以避免意外升級。

Fargate 暫時儲存空間

每個 Fargate 任務都有用於可寫容器層與 /tmp 的暫時儲存空間。平台版本 1.4.0+ 的預設值為 20 GB,可透過 ephemeralStorage.sizeInGiB 設定,最高每個任務 200 GB。暫時儲存空間以 AWS 受管金鑰加密,任務停止時即銷毀。若需持久狀態,請使用 EFS 或 FSx 磁碟區。

Fargate 平台版本 1.4.0+ 提供 20 GB 預設暫時儲存空間(可設定至 200 GB)、支援 EFS 磁碟區掛載、可在 x86 或 Graviton ARM64 上執行、使用 Firecracker microVM 進行任務隔離,並在 20 至 60 秒內佈建新任務。Fargate Spot 為可中斷任務提供最高 70 百分比的折扣。 Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/platform_versions.html

有狀態 Fargate — EFS 與 FSx 掛載

Fargate 暫時儲存空間在任務停止時即銷毀,對無狀態 Web 應用程式完全沒問題。對有狀態工作負載——共享上傳檔案、Session 狀態、CMS 檔案儲存——則需掛載外部檔案系統。

Fargate 任務中的 EFS 磁碟區

Amazon EFS 提供 NFS 檔案系統,可讓多個 Fargate 任務同時掛載。前置需求:

  • 任務網路模式必須為 awsvpc(Fargate 上恆為真)。
  • 任務 Security Group 必須允許 NFS(TCP 2049)連至 EFS 掛載目標。
  • 任務執行角色需要 elasticfilesystem:ClientMountelasticfilesystem:ClientWrite(或使用帶 IAM 的 EFS Access Point)。
  • Fargate 平台版本 1.4.0 或更新版本。

在任務層級定義磁碟區,並在容器中掛載:

"volumes": [
  {
    "name": "shared-data",
    "efsVolumeConfiguration": {
      "fileSystemId": "fs-abc123",
      "rootDirectory": "/",
      "transitEncryption": "ENABLED",
      "authorizationConfig": {
        "accessPointId": "fsap-xyz",
        "iam": "ENABLED"
      }
    }
  }
],
"containerDefinitions": [
  {
    "name": "app",
    "mountPoints": [
      { "sourceVolume": "shared-data", "containerPath": "/data" }
    ]
  }
]

EFS Access Point 提供應用程式層級的 POSIX 使用者/群組與目錄隔離,是多租戶共享檔案系統的建議模式。

FSx for Windows 與 FSx for Lustre

Windows 容器工作負載可使用 FSx for Windows File Server 提供的 SMB 共享——ECS on EC2 Windows 支援此方式;Fargate Windows 支援較新,依平台版本而定。FSx for Lustre 是高效能平行檔案系統,適用於 HPC 與 ML 工作負載,可掛載於 ECS on EC2(EKS Fargate 支援有限)。DVA-C02 鮮少深入 FSx;記住 EFS 是 Fargate 上通用共享狀態的主要答案。

AWS App Runner — 全受管容器部署

AWS App Runner 是 AWS 上最簡單的容器部署路徑,也是無狀態 Web 應用程式的開發者友善選項。App Runner 從 ECR 取得容器映像檔,或從 GitHub 取得原始碼,並以自動擴縮與 TLS 的方式將其作為公開 HTTPS 端點執行。

App Runner 來源

  • ECR 映像檔 — App Runner 拉取指定的映像檔 URI。可選擇在相同 tag 有新映像檔推送時自動重新部署。
  • 原始碼 Repository — 連結 GitHub Repository;App Runner 使用受管 Buildpack(Python、Node.js、Java 等)或 Repository 中的 Dockerfile 建置映像檔,再進行部署。推送至主分支會觸發自動部署。

App Runner 功能

  • 自動 HTTPS,搭配 AWS Certificate Manager(為 <id>.<region>.awsapprunner.com 網域管理憑證)或自訂網域。
  • 並發自動擴縮——設定每個執行個體的最大並發請求數(預設 100)與最小/最大執行個體數;App Runner 在其間自動伸縮。
  • VPC Connector,用於存取 RDS、ElastiCache 或內部服務(否則 App Runner 在你的 VPC 之外執行)。
  • 按 vCPU 與記憶體以秒計費,另加小額的每請求費用。
  • 滾動部署,搭配可設定 HTTP 路徑的健康檢查。
  • 可觀測性外掛(AWS App Runner observability)無需額外監測設定,即可在 CloudWatch 與 X-Ray 中呈現請求與執行期指標。

DVA-C02 中 App Runner 勝過 ECS 的時機

  • 應用程式是無狀態的 HTTP API 或 Web 應用程式。
  • 團隊希望零基礎設施決策(無需設定 VPC、負載平衡器、Target Group)。
  • 從 Git Push 觸發部署是硬性需求。
  • 流量屬於中低量;縮減至近零實例可節省成本。

App Runner 不適合非 HTTP 工作負載、多容器 Sidecar 模式,或需要精細網路設定的工作負載。在 DVA-C02 中,若情境描述「開發者希望部署無狀態 API 且無需設定基礎設施」,App Runner 就是正確答案——若出現 Sidecar、自訂網路或長連線,則改選 ECS on Fargate。

在 ECR Repository 上啟用 App Runner 自動部署。每次 docker push 到追蹤的 tag,App Runner 就會拉取新映像檔並以健康檢查完成滾動部署。無需 CodePipeline、CodeDeploy 或 GitHub Actions 部署步驟。對 DVA-C02 問「從 commit 到正式環境最短路徑」的情境,這個組合難有對手。 Reference: https://docs.aws.amazon.com/apprunner/latest/dg/manage-automatic.html

AWS Copilot CLI — 容器部署 Stack 鷹架工具

AWS Copilot CLI 是開放原始碼的命令列工具,用於在 ECS、Fargate 與 App Runner 上搭建並部署容器化應用程式。Copilot 底層使用 CloudFormation;你與高層次概念互動(applicationenvironmentservicejobpipeline),而非直接撰寫任務定義。

Copilot 核心工作流程

# 每個應用程式執行一次
copilot app init my-store

# 每個環境(dev、staging、prod)
copilot env init --name prod --profile prod-account --default-config

# 每個服務
copilot svc init --name api --svc-type "Load Balanced Web Service" \
  --dockerfile ./api/Dockerfile

# 部署
copilot svc deploy --name api --env prod

Copilot 選取合理的預設值(Web 服務使用 ALB、ECS on Fargate、CloudWatch Logs、每環境隔離),在 copilot/ 目錄下產生你可提交至 Git 的 manifest YAML,並在 CloudFormation 中建立 VPC、叢集、任務定義、服務、負載平衡器與 IAM 角色。

Copilot 服務類型(每次 svc init 選擇一種):

  • Request-Driven Web Service — 由 App Runner 支援。
  • Load Balanced Web Service — ECS on Fargate,位於公開 ALB 後方。
  • Backend Service — ECS on Fargate,搭配內部服務探索(Cloud Map)。
  • Worker Service — ECS on Fargate,消費 SQS。
  • Static Site — S3 + CloudFront。

Copilot 也可搭建 Pipeline(copilot pipeline init),串聯 CodeCommit / GitHub → CodeBuild → 各環境 ECS 部署。

在 DVA-C02 中,若情境描述「開發者希望以最少手動設定啟動新容器化服務」或「無需手工撰寫範本即可生成 CloudFormation 支援的 ECS Stack」,Copilot 就是答案。

ECS Exec — 進入執行中任務的 Shell

ECS Exec 讓開發者無需 SSH、跳板機或主機存取,即可在執行中的 ECS 任務內執行互動式命令(包含 Shell)。ECS Exec 底層使用 AWS Systems Manager Session Manager。

前置需求

  • 任務角色必須包含 SSM 權限(ssmmessages:CreateControlChannelssmmessages:CreateDataChannelssmmessages:OpenControlChannelssmmessages:OpenDataChannel)。
  • 容器映像檔必須包含 SSM Agent——AWS 在任務啟動時透過 bind-mounted 二進位檔自動注入,因此映像檔通常無需自行打包。
  • 任務定義的服務必須設定 enableExecuteCommand: true(或在執行一次性任務時傳入 --enable-execute-command)。
  • Fargate 平台版本 1.4.0 或更新版本。

使用 ECS Exec

aws ecs execute-command \
  --cluster prod \
  --task <task-id> \
  --container app \
  --interactive \
  --command "/bin/sh"

Session 日誌可透過叢集的 executeCommandConfiguration 路由至 CloudWatch Logs 或 S3 以供稽核。DVA-C02 中「無需重建映像檔即可除錯執行中任務」的情境,答案都是 ECS Exec。常見的干擾選項「SSH 至 Fargate 主機」是不可能的,因為 Fargate 根本不提供主機存取。

常見的設定錯誤:開發者將 SSM 權限授予任務執行角色,導致 ECS Exec 失敗。SSM 權限必須設在任務角色,因為容器內的 SSM Agent 使用的是任務角色的憑證。此外,服務在建立(或更新)時必須加入 --enable-execute-command——在現有服務上啟用此功能需要進行新部署。 Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html

容器映像檔簽署與部署護欄

正式環境的容器部署需要供應鏈完整性保證。AWS 提供多種圍繞容器映像檔的護欄機制。

AWS Signer 容器映像檔簽署

AWS Signer 搭配 Notation(Notary Project 的開放原始碼簽署標準)對儲存於 ECR 中的容器映像檔進行簽署。簽章與映像檔一同存放於 ECR。在部署時,驗證政策——由 EKS 上的 Kyverno 或 ECS 的自訂 Lambda 評估——在允許映像檔執行前,對照受信任身份驗證簽章。

對 ECS 而言,簽章驗證在啟動時並不由原生機制強制執行(截至 DVA-C02 考試視窗);執行強制通常在呼叫 UpdateService 之前的 CI/CD 閘道,或透過 EKS 上的 Admission Controller 進行。記住這個細節:DVA-C02 可能考映像檔簽署的存在與目的,而非執行期的強制執行機制。

ECR 複寫與 Pull-Through Cache

  • ECR 複寫自動跨 Region 或跨帳號複製映像檔,降低多 Region 部署的拉取延遲。
  • ECR pull-through cache將上游 Registry(Docker Hub、Quay、Kubernetes registry、Microsoft Container Registry)的映像檔鏡像至你的 ECR,降低速率限制風險,同時獲得可掃描的映像檔。

部署護欄模式

  • 具回滾功能的部署斷路器(已於上方說明)——捕捉失敗的滾動部署。
  • CodeDeploy 藍/綠搭配 CloudWatch 警示——在指標閾值觸發時自動回滾。
  • 任務定義 revision——透過 UpdateService 將服務指向前一個 revision 以手動回滾。
  • 不可變映像檔 tag——確保服務的 image URI 不會被靜默竄改。
  • 推送時映像檔掃描 + 增強掃描——在 CI/CD 閘道阻擋含高風險 CVE 的映像檔部署。

DVA-C02 容器部署常見陷阱

陷阱一 — 混淆任務角色與執行角色

任務執行角色 = ECS Agent 的權限(拉取 ECR、取得 Secrets、寫入日誌)。任務角色 = 應用程式的權限(讀取 S3、寫入 DynamoDB)。DVA-C02 會混用這兩者,錯誤的角色幾乎都是干擾選項。

陷阱二 — 執行角色缺少 secretsmanager:GetSecretValue

當任務定義使用 secrets.valueFrom,容器卻以「ResourceInitializationError」啟動失敗時,修正方式是將 secretsmanager:GetSecretValue(若 Secret 以 CMK 加密則另需 kms:Decrypt)加入執行角色

陷阱三 — Dockerfile Shell 形式破壞 SIGTERM 處理

CMD node server.js 將行程包在 /bin/sh -c 中,吞掉 SIGTERM。滾動部署時任務觸及 stopTimeout 被 SIGKILL 強制終止。修正方式:改用 exec 形式 CMD ["node", "server.js"] 或以 tini 作為 init。

陷阱四 — EC2 主機上 awsvpc 任務缺少 ENI 容量

在 EC2 啟動類型上執行 awsvpc 任務時,每個任務需要自己的 ENI。EC2 執行個體有依類型而定的 ENI 上限。任務啟動失敗並顯示「InsufficientNetworkInterfaces」。可在支援的執行個體類型上啟用 ENI trunking 以提高上限,或改用 Fargate。

陷阱五 — Mutable Tag 破壞可重現性

latest tag 被重新推送後,「相同任務定義 = 相同程式碼」的心智模型就崩潰了。正式環境請將 ECR Repository 設為 IMMUTABLE,並以版本 tag 或 digest 固定部署。

陷阱六 — 未啟用部署斷路器

沒有斷路器時,壞的新版本部署會讓失敗任務無止盡地重複啟動。ECS 控制器服務務必啟用 rollback: true 的斷路器。

陷阱七 — App Runner 被誤選用於非 HTTP 工作負載

App Runner 僅支援 HTTP。DVA-C02 中涉及大量 WebSocket、gRPC Streaming 或 Long Polling 的工作負載,不應預設選 App Runner;正確答案是 ECS on Fargate 搭配 NLB。

開發者有時將應用程式狀態寫入 Fargate 上的 /tmp/var/lib/app,期望它在重啟後仍存在。Fargate 暫時儲存空間在任務停止時即銷毀。修正方式:共享狀態使用 EFS 磁碟區掛載,應用程式狀態使用 RDS / DynamoDB,Blob 儲存使用 S3。永遠不要假設任何 Serverless 容器執行期上的本機磁碟具有持久性。 Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-storage.html

容器部署必記數字

  • ECR 認證 token — 有效期 12 小時。
  • ECR 推送時映像檔掃描 — 每個映像檔的基本掃描免費;增強掃描按每個映像檔每月計費。
  • Fargate 平台版本 1.4.0+ — 預設 20 GB 暫時儲存空間(最高 200 GB)、支援 EFS 掛載。
  • Fargate CPU/記憶體組合 — 0.25 vCPU(0.5–2 GB)至 16 vCPU(30–120 GB)。
  • Fargate Spot 折扣 — 最高 70 百分比。
  • ECS 控制平面 — 免費。
  • 部署斷路器 — 預設閾值為 10 次失敗任務啟動或期望數量的 200 百分比,以較低者為準。
  • Target Group 取消登記延遲 — 預設 30 秒,最高 3600 秒。
  • awsvpc 網路模式 — Fargate 強制使用,每個任務一個 ENI。
  • ECS 任務 stopTimeout — 預設 30 秒,Linux 最高 120 秒。
  • ECS Exec — 需要 Fargate 平台版本 1.4.0+、任務角色的 SSM 權限、enableExecuteCommand: true

FAQ — AWS 容器部署

Q1. ECS 任務執行角色與 ECS 任務角色有何不同?各在何時適用?

ECS 任務執行角色由 ECS Agent(EC2 上)或 Fargate 基礎設施代表你承擔,用於在任務啟動前後執行操作:從私有 ECR 拉取容器映像檔、從 Secrets Manager 或 SSM Parameter Store 取得 Secrets 以注入為環境變數,以及透過 awslogs Driver 將容器 stdout/stderr 寫入 CloudWatch Logs。ECS 任務角色由容器內執行的應用程式程式碼承擔,授予程式碼在執行期呼叫的 AWS API 權限——讀取 S3 儲存貯體、寫入 DynamoDB、發布至 SNS。在 ECS 上,只要使用 ECR 私有 Registry、Secrets Manager 或 awslogs,就需要執行角色;只要應用程式程式碼呼叫 AWS API,就需要任務角色。混淆這兩者是 DVA-C02 容器部署情境中測驗最多的單一陷阱。

Q2. 如何從開發者筆電將容器映像檔推送至 Amazon ECR?

使用 AWS CLI 向 ECR 認證 Docker:aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com。回傳的 token 有效期為 12 小時。以完整 ECR URI 為本機映像檔加上 tag:docker tag myapp:latest <account-id>.dkr.ecr.<region>.amazonaws.com/myapp:v1.2.3。推送:docker push <account-id>.dkr.ecr.<region>.amazonaws.com/myapp:v1.2.3。若想提升開發體驗,可安裝 Amazon ECR Docker Credential Helper,讓 docker push 自動使用 AWS 憑證進行認證,省去明確登入步驟。

Q3. ECS 部署斷路器如何保護滾動部署?應在何時啟用回滾?

ECS 部署斷路器監控滾動部署中的失敗任務啟動次數。當失敗閾值達到(預設 10 次失敗或期望數量的 200 百分比,以較低者為準),ECS 將部署標記為 FAILED 並停止啟動新任務。若你在部署設定中設定 rollback: true,ECS 還會自動重新部署前一個任務定義 revision。對每一個使用預設 ECS 部署控制器的正式環境 ECS 服務,都應啟用具回滾功能的斷路器——它是免費的、沒有副作用,且能防止損壞的新 revision 演變成完全中斷。斷路器不適用於 CodeDeploy 藍/綠控制器;對 CodeDeploy,請在部署群組上設定 CloudWatch 警示以觸發自動回滾。

Q4. 如何將 AWS Secrets Manager 的 Secrets 注入 ECS 容器,而不將其寫死進映像檔?

在 AWS Secrets Manager 或 SSM Parameter Store 中定義一次 Secret。在 ECS 任務定義的容器定義中,使用 secrets 陣列,而非 environment 陣列:{"name": "DB_PASSWORD", "valueFrom": "arn:aws:secretsmanager:<region>:<account>:secret:<secret-name>-<suffix>:password::"}valueFrom 的 ARN 可指向整個 Secret,或特定 JSON 金鑰(在 ARN 後附加 :json-key::)。授予任務執行角色針對該 Secret ARN 的 secretsmanager:GetSecretValue(若 Secret 以客戶自管 KMS 金鑰加密,則另需 kms:Decrypt)。任務啟動時,ECS 解析每個 Secret 並以環境變數形式注入容器。應用程式視之為一般環境變數;Secret 值不會出現在任務定義 JSON 中。

Q5. 為 ECS 或 Fargate 產生正式環境就緒映像檔的核心 Dockerfile 最佳實踐是什麼?

AWS 容器部署的核心 Dockerfile 最佳實踐如下:使用多階段建置,確保編譯工具鏈與開發相依套件不進入正式環境;選擇最小化基礎映像檔(slim、Alpine 或 distroless,最好從 ECR Public Gallery 拉取以避免 Docker Hub 速率限制);從最少變動到最多變動排列層次,讓相依套件安裝層可以快取;先安裝相依套件,再複製原始碼;以非 root 使用者執行,建立專屬使用者或使用基礎映像檔內建的非 root 使用者;使用 exec 形式的 CMD(CMD ["node", "server.js"]),確保滾動部署時 SIGTERM 能到達行程;只有在 ALB Target Group 健康檢查不足時才加入 HEALTHCHECK;並明確設定 EXPOSE 與 WORKDIR。遵循這八個習慣,可產生小巧、快速拉取、訊號安全、善用快取且安全的映像檔——這直接換算為 DVA-C02 的考試分數。

Q6. 為新服務選擇 AWS App Runner 還是 ECS on Fargate,判斷依據是什麼?

選擇 AWS App Runner 的時機:工作負載是無狀態的 HTTP Web 應用程式或 API;團隊希望零基礎設施管理(無需設定 VPC、負載平衡器、Target Group 或 Auto Scaling 政策);從 Git Push 或 ECR Push 觸發自動部署是硬性需求;流量規模允許縮減至近零實例以節省成本。App Runner 負責處理負載平衡器、受管 TLS 憑證、依每個執行個體並發請求數的 Auto Scaling、帶健康檢查的滾動部署,以及用於存取私有資源的內建 VPC Connector。選擇 ECS on Fargate 的時機:需要多容器任務搭配 Sidecar(FireLens Log Router、Envoy Proxy、遷移 init 容器);非 HTTP 協定;WebSocket 或 gRPC Streaming 高流量;精細網路設定(多個 Security Group、多個子網路、PrivateLink Endpoint);或超出滾動部署的部署策略(CodeDeploy 藍/綠搭配金絲雀或線性)。對於全新的無狀態 API,App Runner 幾乎都是最佳首選;若複雜度要求升高,日後再遷移至 ECS。

Q7. 如何在沒有 SSH 或跳板機的情況下除錯正式環境 ECS 任務?

使用 ECS Exec,它透過 AWS Systems Manager Session Manager 在執行中任務內提供互動式 Shell。前置需求:任務角色包含四個 SSM 訊息權限(ssmmessages:CreateControlChannelCreateDataChannelOpenControlChannelOpenDataChannel);服務在建立或更新時加入 enableExecuteCommand: true;Fargate 平台版本為 1.4.0 或更新版本。接著執行 aws ecs execute-command --cluster <cluster> --task <task-id> --container <name> --interactive --command "/bin/sh"。Session 日誌可透過叢集的 executeCommandConfiguration 路由至 CloudWatch Logs 或 S3 以供稽核。ECS Exec 是 DVA-C02 任何「無需重建映像檔即可除錯執行中容器」情境的答案。常見設定錯誤是將 SSM 權限放在執行角色而非任務角色——容器內的 SSM Agent 使用的是任務角色的憑證。

摘要 — 容器部署一覽

  • AWS 上的容器部署是 Dockerfile → ECR → ECS 任務定義 → ECS 服務 → Fargate 執行期的開發者流程,App Runner 與 Copilot 是加速器,ECS Exec 是除錯工具。
  • Dockerfile 最佳實踐:多階段建置、最小化基礎映像檔、快取友善的層次排序、非 root 使用者、exec 形式 CMD、僅在必要時加入明確的 HEALTHCHECK。
  • Amazon ECR:透過 aws ecr get-login-password 取得 12 小時有效認證 token、正式環境使用不可變 tag、推送時掃描(基本免費,增強用於持續掃描)、生命週期政策控制儲存成本、透過 Repository 政策支援跨帳號拉取、ECR Public Gallery 提供免速率限制的基礎映像檔。
  • ECS 任務定義:Fargate 上的 awsvpc 網路模式、任務與容器層級的 CPU/記憶體、透過 valueFrom 在啟動時解析 Secrets、依 dependsOn 排序生命週期、awslogs 或 FireLens 記錄日誌、任務角色 vs 執行角色為標準陷阱。
  • ECS 服務:desiredCount、部署控制器(ECS 滾動、CodeDeploy 藍/綠、External)、具回滾的部署斷路器、透過 ALBRequestCountPerTarget 目標追蹤的 Service Auto Scaling。
  • Fargate:無需管理 EC2、平台版本(固定 1.4.0+ 以使用 EFS 與較大暫時儲存空間)、按秒計費、Fargate Spot 可中斷工作負載最高 70 百分比折扣。
  • 有狀態 Fargate:透過 efsVolumeConfiguration 掛載 EFS 磁碟區、Access Point 提供 POSIX 隔離、任務 Security Group 必須允許 NFS 2049;Windows / Lustre 特殊需求使用 FSx。
  • App Runner:僅限 HTTP、零基礎設施決策、從 ECR 或 GitHub 自動部署、VPC Connector 存取私有資源、CloudWatch 與 X-Ray 的可觀測性外掛。
  • AWS Copilot CLI:以 CloudFormation 為底層搭建 ECS on Fargate 或 App Runner 應用程式,服務類型涵蓋 Load Balanced Web Service、Backend Service、Worker Service、Request-Driven Web Service。
  • ECS Exec:透過 SSM Session Manager 進入執行中任務的互動式 Shell;SSM 權限設在任務角色而非執行角色;按服務啟用,且需 Fargate 平台版本 1.4.0+。
  • 透過 AWS Signer + Notation 進行映像檔簽署;部署護欄包括斷路器回滾、不可變 tag、推送時掃描閘道、CodeDeploy 警示。

以此深度掌握容器部署,DVA-C02 的任務陳述 3.1 與 3.2 就會成為模式辨識。同樣的開發者肌肉記憶——Dockerfile、ECR、任務定義、服務、Fargate、App Runner、Copilot、ECS Exec——在你通過考試後的第一個上班早上,就能直接帶進正式環境的工作中。

官方資料來源

更多 DVA-C02 主題