Amazon SAA-C03: 容器與編排 — 學習指南
屬於 AWS SAA-C03 — 完整學習指南. 使用經過驗證的解答練習: Amazon 考試中心, 或參加限時模擬考試: ExamRoll.io.
在 ECS 與 EKS、以及 EC2 與 Fargate 之間做選擇
對於 AWS 上的任何容器工作負載,第一個架構決策就是選擇編排器 (orchestrator) 和運算模式。Amazon ECS 是 AWS 自家的編排器,與 IAM、ALB/NLB、CloudWatch、Service Discovery 和 VPC 網路緊密整合。它沒有控制平面 (control-plane) 費用,對於不需要 Kubernetes 特定工具的團隊來說,是投入生產最快的路徑。任務 (Task) 是一個或多個共享生命週期的容器單位;服務 (Service) 則是由排程器 (scheduler) 在前端管理的長時間執行的任務集合。Amazon EKS 執行符合上游標準的 Kubernetes,每個叢集固定收費每小時 0.10 美元。當工作負載必須保持可攜性、使用 Kubernetes API 或利用 CNCF 生態系 (如 Helm、CRDs、Operators) 時,它是正確的選擇。控制平面——包含 API server、etcd、controller manager、scheduler——由 AWS 負責修補、備份,並在三個可用區 (AZ) 之間實現高可用性。
兩種編排器都接受兩種運算模式。AWS Fargate 在隔離的 Firecracker 微型虛擬機 (microVM) 上執行每個任務 (task) 或 pod;沒有需要修補的 AMI、沒有需要調整的 Auto Scaling Group 容量供應商、沒有裝箱 (bin-packing) 決策、也沒有可以透過 SSH 存取的主機。您只需為任務使用的 vCPU-秒和 GB-秒付費。EC2 啟動類型 / 受管節點群組 意味著您擁有執行個體,這也代表著您同時獲得了靈活性和其所帶來的維運負擔。
只要情境強調「無伺服器 (serverless)」、「最少維運開銷」或「無需管理基礎設施」,Fargate 就是正確的預設選擇,前提是工作負載符合其限制:每個任務最多 16 vCPU / 120 GB 記憶體、無 GPU、無特權容器 (privileged containers)、無 DaemonSets、無 HostPort/HostNetwork、無 Windows 主機層級的客製化。當您需要 GPU、需要主機存取權限的 DaemonSets、自訂 AMI、使用 GMSA 的 Windows Server 容器、亞秒級的裝箱效率,或積極的基於 Spot 的成本優化時,請選擇受管節點群組或 EC2 啟動類型。
| 需求 | 正確的選擇 |
|---|---|
| Kubernetes API + 上游工具 | EKS |
| 最簡單的 AWS 原生編排器 | ECS |
| 無需管理基礎設施 | Fargate (適用於任一編排器) |
| GPU、DaemonSets、自訂核心模組 | 受管節點群組 / EC2 |
| 使用 GMSA 的 Windows 容器 | EC2 啟動類型 |
| 大規模基於 Spot 的成本優化 | 使用 Spot 的受管節點群組 |
| EKS 上由 EBS 支援的持久性磁碟區 | 受管節點群組 |
| 突發性、不可預測的 pod | Fargate |
一個典型的陷阱是,因為 EC2 節點「感覺上」比較便宜而選擇它們。對於流量尖峰或低使用率的工作負載,一旦您將閒置容量、加上修補 AMI、節點清空 (node draining) 和叢集自動擴展器 (cluster autoscaler) 設定所需的工程時間都考慮進去後,Fargate 通常更便宜——而所有這些工作 Fargate 都幫您省去了。
任務定義、放置與容量供應商
一個典型的 ECS Fargate 任務定義 (task definition) 包含了幾個要點——CPU/記憶體大小、用於拉取映像檔和寫入日誌的執行角色 (execution role)、awsvpc 網路模式,以及與 CloudWatch Logs 的串接:
family: checkout-service
requiresCompatibilities: [FARGATE]
networkMode: awsvpc
cpu: "1024"
memory: "2048"
executionRoleArn: arn:aws:iam::111122223333:role/ecsTaskExecutionRole
containerDefinitions:
- name: checkout
image: 111122223333.dkr.ecr.us-east-1.amazonaws.com/checkout:1.4.2
portMappings: [{ containerPort: 8080 }]
logConfiguration:
logDriver: awslogs
options:
awslogs-group: /ecs/checkout
awslogs-region: us-east-1
在使用 EC2 的 ECS 上,任務放置策略 (task placement strategies) 決定了任務如何在執行個體之間分佈。它們按順序組合:
| 策略 | 行為 | 典型用途 |
|---|---|---|
spread | 在一個欄位上均勻分佈 (例如 attribute:ecs.availability-zone) | 跨 AZ 的高可用性 (HA) |
binpack | 根據 CPU 或記憶體,將任務打包到最少的執行個體上 | 成本優化 |
random | 隨機放置 | 很少適用 |
放置約束 (Placement constraints),例如使用叢集查詢語言的 distinctInstance 或 memberOf,會進一步限制候選的執行個體。
容量供應商 (Capacity providers) 將服務與底層的 Auto Scaling Group 解耦。FARGATE 和 FARGATE_SPOT 是受管的供應商;自訂供應商則包裝一個 ASG 並啟用受管擴展 (managed scaling),讓 ECS 能夠根據已佈建的任務數量來調整 ASG 的期望數量 (desired count)。容量供應商策略 (capacity provider strategy) 根據權重 (weight) 和基礎數量 (base) 來分配任務——例如,保證兩個 on-demand Fargate 任務,並將其餘的以 1:4 的比例分配給 Fargate Spot,以處理可容忍中斷的工作負載:
capacityProviderStrategy:
- capacityProvider: FARGATE
base: 2
weight: 1
- capacityProvider: FARGATE_SPOT
weight: 4
自動擴展:Pod、任務與節點
Fargate 省去了節點管理,但它不會自動擴展任務或 pod 的數量。這個區別是關於 Fargate 最常被誤解的一點:無伺服器 (serverless) 僅適用於主機層,絕不適用於您服務的期望數量 (desired count)。您仍然需要負責服務層級的自動擴展。
對於 ECS,請使用 Application Auto Scaling。目標追蹤 (Target tracking) 是慣用的預設方式,因為它會自動建立擴展 (scale-out) 和縮減 (scale-in) 的 CloudWatch 警報,並遵循冷卻時間 (cooldowns)。合理的指標包括 ECSServiceAverageCPUUtilization、ECSServiceAverageMemoryUtilization 和 ALBRequestCountPerTarget:
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--resource-id service/prod-cluster/checkout \
--scalable-dimension ecs:service:DesiredCount \
--min-capacity 2 --max-capacity 30
aws application-autoscaling put-scaling-policy \
--policy-name cpu-target-50 \
--service-namespace ecs \
--resource-id service/prod-cluster/checkout \
--scalable-dimension ecs:service:DesiredCount \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration \
'{"TargetValue":50.0,"PredefinedMetricSpecification":{"PredefinedMetricType":"ECSServiceAverageCPUUtilization"}}'
對於非線性的響應曲線或已知的流量時段,步階擴展 (Step scaling) 和排程擴展 (Scheduled scaling) 仍然可用。
對於在 EC2 節點上的 EKS,pod 維度的擴展由 Horizontal Pod Autoscaler (HPA) 處理,它會根據 CPU、記憶體或自訂指標來調整複本 (replica) 數量。單獨的 HPA 無法新增節點——它會很樂意地將複本數增加到超過叢集容量,此時新的 pod 會進入 Pending 狀態,並出現 FailedScheduling 事件。這就是為什麼在 EC2 上的 HPA 必須總是與 Kubernetes Cluster Autoscaler 或 Karpenter 搭配使用。忘記這種搭配是一個常見的設計錯誤:HPA 回報「已擴展到 20 個複本」,但其中一半卻卡在 pending 狀態。一個最小化的 Cluster Autoscaler 設定會透過 ASG 標籤來發現節點群組:
- --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/prod-eks
- --balance-similar-node-groups
- --skip-nodes-with-system-pods=false
在 Fargate profiles 上,這個問題就消失了——每個 pod 都成為自己的微型虛擬機,因此節點擴展的維度被完全消除了。這也正是為什麼對於具有突發性且 pod 數量不可預測的工作負載,Fargate 是正確的選擇。
Fargate Profile 及其功能限制
EKS 中的 Fargate profile 是一個選擇器——由 namespace 加上可選的 pod 標籤組成——它指示 EKS 將匹配的 pod 調度到 Fargate 上,而不是節點上:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata: { name: microservices, region: us-east-1 }
fargateProfiles:
- name: fp-app
selectors:
- namespace: app
labels: { compute: fargate }
關鍵的注意事項是,EKS on Fargate 並不支援完整的 Kubernetes 功能集:
- DaemonSet 無法運行。 由於沒有節點可以執行 daemon,像
fluentd這類的日誌傳送器 DaemonSet 必須被替換為 sidecar 或內建的 Fluent Bit 日誌路由器。 - 特權容器 (Privileged containers)、HostPort 和 HostNetwork 無法使用。
- 持久性儲存僅限於 EFS,需透過 CSI 驅動程式。不支援 EBS,因為 EBS 磁碟區需要掛載到特定的 EC2 執行個體。
- 不支援 GPU 工作負載。
NodePort服務以及依賴特權 init 容器的服務網格 (service mesh) 無法運作。
若假設功能完全對等,會導致需要 EBS 的 StatefulSet、使用 hostPort 的 ingress controller 或 GPU 推理工作負載的遷移失敗。
Ingress:透過 AWS Load Balancer Controller 使用 ALB vs NLB
AWS Load Balancer Controller 是一個 Kubernetes 控制器,它會將 Ingress 和 Service 物件轉換為實際的 ALB 和 NLB。對於需要基於路徑或主機路由的 HTTP/HTTPS 微服務,請建立一個 class 為 alb 的單一 Ingress。一個 ALB 服務多個後端服務(透過 alb.ingress.kubernetes.io/group.name)比每個服務一個 ALB 要便宜得多,是標準的成本效益模式:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shop
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/group.name: shop
spec:
rules:
- http:
paths:
- path: /customers
pathType: Prefix
backend: { service: { name: customers, port: { number: 80 }}}
- path: /orders
pathType: Prefix
backend: { service: { name: orders, port: { number: 80 }}}
對於 TCP、UDP、TLS pass-through、靜態 IP 需求或極高的 Layer 4 吞吐量,請使用 NLB(類型為 LoadBalancer 的 Service,並設定 service.beta.kubernetes.io/aws-load-balancer-type: external 和目標類型為 nlb-ip)。將 gRPC-over-HTTP/2 或純 TCP 的資料庫代理放在 ALB 後面,僅對 gRPC 來說是可行的(ALB 支援 HTTP/2 和 gRPC);ALB 無法終止任意的 TCP 或任何 UDP 連線。試圖透過 ALB 來服務 UDP 遊戲流量是一種協定不匹配,必須在設計階段就發現這個問題。
使用 IRSA 實現 Pod 層級的 IAM
IAM Roles for Service Accounts (IRSA) 是授予個別 pod AWS API 權限的正確機制。將節點的 instance profile 附加到節點上以賦予 pod S3 存取權限是錯誤的,因為節點上的每個 pod 都會繼承這些權限,這違反了最小權限原則。IRSA 的運作方式是將叢集的 OIDC provider 與 IAM 進行聯邦:只需建立一次 OIDC provider,然後建立一個 IAM role,其信任策略信任該 provider 為特定的 namespace:serviceaccount 主體。
eksctl utils associate-iam-oidc-provider --cluster prod --approve
eksctl create iamserviceaccount \
--cluster prod --namespace payments --name orders-sa \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess \
--approve
service account 會被加上 eks.amazonaws.com/role-arn: arn:aws:iam::...:role/orders-role 的註解,而掛載它的 pod 會透過一個 projected token 接收到短期的 STS 憑證。跳過 OIDC provider 的關聯或省略註解會靜默地退回到使用節點的角色——這是一個在審查中很容易錯過的細微安全倒退。
VPC CNI plugin 透過為每個 pod 分配一個在 VPC 子網路中可路由的 ENI/IP 位址來補充這一點。Pod 接著就可以使用安全群組直接與 RDS、ElastiCache 或 VPC 端點通訊,而 CloudTrail 也能看到 pod 的實際 IP 以便於稽核。
持久性與臨時性儲存
儲存的選擇取決於存取模式、耐用性和啟動類型。
EBS(在 EKS 上透過 EBS CSI 驅動程式,或在 ECS 上透過 task-attached EBS)為單一 pod 的有狀態工作負載(例如 Postgres 主資料庫)提供 ReadWriteOnce 的區塊儲存磁碟區。EFS 提供 ReadWriteMany 的 NFS 儲存,它是區域性、多可用區的,並且可以同時被多個 pod 掛載——當需求提到「高可用、容錯、多容器共享」或共享機器學習產物時,這就是正確的選擇。FSx for Lustre 處理高吞吐量的 HPC;FSx for NetApp ONTAP 和 FSx for Windows File Server 處理企業級的 NFS/SMB。
Fargate task 預設會獲得 20 GB 的臨時儲存空間,在平台 1.4.0+ 版本上可透過 ephemeralStorage.sizeInGiB 設定最高達 200 GB。假設 Fargate 總是有「足夠的暫存空間」是一個陷阱:一個會寫入 50 GB 中間檔案的供應商容器可能適用於擴展後的臨時儲存,但如果需求是 50 GB 的共享或持久儲存,需要在 task 重啟或跨 task 之間保持,那麼臨時儲存就是錯誤的選擇,因為它在 task 停止時會被銷毀,且從不共享。Fargate 不支援 EBS。 如果 Fargate 工作負載需要持久性或共享儲存,EFS 基本上是唯一支援的選項。
對於 ECS,直接在 task definition 中掛載 EFS;存取點會為每個 task 強制執行 POSIX UID/GID 和根目錄,在單一檔案系統上提供安全的多租戶環境,並且 IAM 授權範圍為 elasticfilesystem:ClientMount:
"volumes": [{
"name": "scratch",
"efsVolumeConfiguration": {
"fileSystemId": "fs-0abc123",
"transitEncryption": "ENABLED",
"authorizationConfig": {
"accessPointId": "fsap-0def456",
"iam": "ENABLED"
}
}
}],
"containerDefinitions": [{
"name": "app",
"mountPoints": [{
"sourceVolume": "scratch",
"containerPath": "/data"
}]
}]
對於 EKS,透過 StorageClass 來連接 EFS:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata: { name: efs-sc }
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: fs-0123456789abcdef0
directoryPerms: "700"
一個常見的陷阱:為有狀態的工作負載選擇 Fargate,卻忘記安裝 EFS CSI 驅動程式和 StorageClass——pod 會啟動,但 PersistentVolumeClaims 會永遠處於 Pending 狀態。反過來說,當需求是共享的多寫入器儲存時,僅為了掛載 EBS 而選擇 EC2 節點也是錯誤的;掛載到單一節點的 EBS io2 無法跨可用區共享。
ECR 映像檔掃描與生命週期
Amazon ECR 提供兩種掃描模式。基本掃描使用開源的 Clair 資料庫,在推送時(或依需求)執行,不收取費用。增強型掃描整合了 Amazon Inspector,持續監控作業系統和語言套件的 CVE,並將發現的結果報告到 Security Hub。對於「掃描 CVE、在新映像檔建立時掃描、對工作負載變更最少」的需求,正確的做法是在儲存庫層級啟用推送時掃描 (scan on push)——不需要更改 pipeline,因為推送事件會觸發掃描:
aws ecr put-image-scanning-configuration \
--repository-name payments-api \
--image-scanning-configuration scanOnPush=true
然後 CI/CD 會呼叫 describe-image-scan-findings,並在 CRITICAL 或 HIGH 計數不為零時讓建置失敗。跳過掃描意味著未修補的 Log4j、OpenSSL 或 glibc CVE 會在生產環境中運行;不掃描的緩解成本遠大於啟用掃描的近乎零成本。
生命週期策略可以限制儲存成本並強制執行標籤的整潔:
{
"rules": [{
"rulePriority": 1,
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 14
},
"action": { "type": "expire" }
}]
}
遷移 Kubernetes + MongoDB 工作負載
在「不變更應用程式碼」和「最低維運負擔」的限制下,將自行託管的 Kubernetes + MongoDB 技術堆疊平移搬遷至 AWS 時,有兩個決策方向是一致的。首先,運算層應移至 EKS,因為 Kubernetes API 的相容性意味著 manifests 和 Helm charts 可以原封不動地移植;對於無狀態服務,使用 Fargate profiles 來免去節點管理的責任。
其次,MongoDB 本身不應重新託管到自行管理的 EC2 或 StatefulSets 上——那會重新帶來備份、分片、容錯轉移和修補等維運負擔。應使用 Amazon DocumentDB (with MongoDB compatibility),它支援 MongoDB 3.6/4.0/5.0 的線路協定,因此現有的驅動程式和連線字串只需極少變更即可運作。
相容性的注意事項很重要。DocumentDB 模擬 MongoDB 的 API 介面,但它並非 MongoDB。某些彙總運算子、特定的索引類型、變更串流語意,以及較新 MongoDB 版本中引入的功能可能會失敗。正確的遷移前步驟是,對應用程式執行 DocumentDB 相容性工具 (compat.py),以確認每個操作都有支援。若選擇 DynamoDB,則會強制重寫資料模型;若選擇 RDS,則會完全破壞文件模型。這兩者都違反了「不變更程式碼」的限制。
混合雲選項:ECS Anywhere 與 EKS Anywhere
ECS Anywhere 將地端伺服器(或其他雲端的 VM)註冊為 ECS 叢集中的外部執行個體。控制平面保留在 AWS 中;外部執行個體上的 SSM Agent 和 ECS Agent 會向外連線。一個部署管道、一個任務定義、一組 IAM 角色,就能同時涵蓋雲端和地端的工作負載。
EKS Anywhere 在您的硬體(通常是 vSphere 或裸機)上安裝一個符合規範的 Kubernetes 發行版,並可選用 EKS Connector 來整合到 AWS 主控台的可視性。當您需要一個輕量、基於任務定義的混合雲方案時,請選擇 ECS Anywhere;當法規或延遲限制要求在本地端運行 Kubernetes,並使用與雲端 EKS 相同的工具鏈時,請選擇 EKS Anywhere。兩者都能保持協作流程的一致性——其根本價值在於,團隊可以避免維護兩套 CI/CD 系統或兩種思維模型。
使用 EKS Connector 實現多叢集可視性
企業經常會混合運營 EKS 叢集、在 EC2 上自行管理的 Kubernetes,以及地端叢集。Amazon EKS Connector 能將任何符合規範的 Kubernetes 叢集註冊到 EKS 主控台中,為節點、工作負載和叢集元數據提供一個單一管理平台。它本質上是一個輕量級代理程式加上一個 SSM 通道——是實現「集中檢視所有叢集」的低負擔解決方案。若要用自行託管的 Rancher、Anthos 或客製化的 Prometheus/Grafana 聯邦來建立同等的可視性,雖然可行,但維運成本要高得多,且無法與 IAM 或基於主控台的存取整合。
EKS Connector 嚴格來說只是一個可視性層;它不會管理或升級遠端叢集,這也正符合「以最低負擔集中檢視」的意義。
整合各種模式
對於一個電子商務工作負載,包含負載平衡的前端、容器化的中介層和關聯式儲存,若以「盡可能減少手動介入」為標準,其標準的技術堆疊是 ALB → ECS on Fargate → Aurora Serverless v2。每一層都消除了執行個體層級的管理責任:ALB 是全託管的,Fargate 移除了主機,而 Aurora Serverless v2 則以 ACU 為單位擴展,無需調整執行個體大小。
對於一個微服務平台,若團隊「無法管理額外的基礎設施」,正確的組合是 ECS 或 EKS 搭配 Fargate,再加上一個全託管的資料服務。選擇 EC2 啟動類型或自行管理的節點群組,就與此限制相矛盾,儘管技術上工作負載仍然可以運行。
對於 Kubernetes + MongoDB 的平移搬遷,答案會收斂到 EKS + DocumentDB:Kubernetes API 保留了部署方式,DocumentDB 保留了驅動程式的相容性,而 Fargate profiles 則維持了最低的維運需求——前提是該工作負載所使用的 Kubernetes 功能和 MongoDB 指令介面,都落在上述支援的範圍內。
← 運算、Auto Scaling 與執行個體管理 · 所有領域 · 無伺服器與事件驅動架構 →
練習這些題目 → · 在 ExamRoll.io 上限時練習 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
通過考試 →