EC2 / ECS / EKS:你的容器該跑在哪?
你有一個容器化的 App,想丟到 AWS 上跑。打開 Console 發現 EC2、ECS、EKS 三個選項——它們到底差在哪?
先講結論
EC2 是你自己管機器,什麼都能控制,但 OS patch、scaling 都要自己來。ECS 是 AWS 自家的容器編排,學習成本低、跟 AWS 生態整合最好。EKS 是 AWS 託管的 K8s,適合已經有 K8s 經驗或需要多雲的團隊。如果你只是要跑幾個容器、團隊不超過 10 人,ECS + Fargate 是 2026 年的最佳起點。
三種選擇一覽
| EC2 | ECS (Fargate) | EKS | |
|---|---|---|---|
| 你管什麼 | OS、Runtime、App | App | K8s manifests、App |
| 學習曲線 | 低(就是 VM) | 中(Task Definition) | 高(K8s 全家桶) |
| Scaling | 自己設 ASG | 自動(Fargate) | HPA + Cluster Autoscaler |
| 成本 | 最低(可用 Spot) | 中(Fargate 溢價) | 最高(Control Plane $73/月) |
| 適合誰 | 非容器化 App、特殊 OS 需求 | 大多數容器化 App | 已有 K8s 團隊、多雲 |
EC2:老朋友,但要自己扛
EC2 就是虛擬機。幾個重點:
Instance Type 怎麼選?
# 查看可用的 Instance Type(東京 Region)
aws ec2 describe-instance-types \
--filters "Name=current-generation,Values=true" \
--query "InstanceTypes[?starts_with(InstanceType,'t3')].[InstanceType,VCpuInfo.DefaultVCpus,MemoryInfo.SizeInMiB]" \
--output table| 場景 | Instance Type | 說明 |
|---|---|---|
| 測試/開發 | t3.micro | 免費方案,2 vCPU / 1 GB |
| Web App | t3.medium | 2 vCPU / 4 GB,夠跑大多數服務 |
| 計算密集 | c6i.xlarge | 4 vCPU / 8 GB,CPU 優化 |
| 記憶體密集 | r6i.xlarge | 4 vCPU / 32 GB,DB/Cache 用 |
PEM 檔案管理
# 建立 Key Pair
aws ec2 create-key-pair --key-name prod-key \
--query 'KeyMaterial' --output text > prod-key.pem
chmod 400 prod-key.pem
# SSH 進去
ssh -i prod-key.pem ec2-user@<PUBLIC_IP>PEM 弄丟了就只能重建 instance,沒有第二次機會。建議存到密碼管理器(1Password / Bitwarden),別放在桌面。
User Data:開機自動設定
# 啟動 EC2 時自動安裝 Docker
aws ec2 run-instances --image-id ami-xxxxx \
--instance-type t3.medium \
--key-name prod-key \
--subnet-id subnet-private-1a \
--security-group-ids sg-app \
--user-data file://init.sh
# init.sh 內容
#!/bin/bash
yum update -y
yum install docker -y
systemctl start docker
systemctl enable docker
usermod -aG docker ec2-userECS + Fargate:容器化 App 的最佳起點
ECS 是 AWS 自家的容器編排服務。搭配 Fargate,你連 EC2 都不用管——丟 container image 進去就跑。
核心概念
- Cluster:邏輯群組,裡面跑 Service 和 Task
- Task Definition:描述你的容器怎麼跑(image、CPU、Memory、port、env)
- Service:保持 N 個 Task 一直在跑(類似 K8s Deployment)
- Task:一次性任務(類似 K8s Job)
建立 ECS 服務
# 1. 建立 Cluster
aws ecs create-cluster --cluster-name prod-cluster
# 2. 建立 Task Definition
cat > task-def.json << 'EOF'
{
"family": "web-app",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "app",
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/web-app:1.0.0",
"portMappings": [
{ "containerPort": 8080, "protocol": "tcp" }
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/web-app",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
},
"environment": [
{ "name": "NODE_ENV", "value": "production" }
]
}
]
}
EOF
aws ecs register-task-definition --cli-input-json file://task-def.json
# 3. 建立 Service
aws ecs create-service --cluster prod-cluster \
--service-name web-app \
--task-definition web-app:1 \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-private-1a,subnet-private-1c],securityGroups=[sg-app],assignPublicIp=DISABLED}" \
--load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=app,containerPort=8080"ECS Auto Scaling
# 註冊 Scalable Target
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--resource-id service/prod-cluster/web-app \
--scalable-dimension ecs:service:DesiredCount \
--min-capacity 2 --max-capacity 10
# Target Tracking:CPU 70% 就擴
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--resource-id service/prod-cluster/web-app \
--scalable-dimension ecs:service:DesiredCount \
--policy-name cpu-tracking \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration \
"TargetValue=70.0,PredefinedMetricSpecification={PredefinedMetricType=ECSServiceAverageCPUUtilization}"EKS:如果你真的需要 K8s
EKS 適合兩種人:已經有 K8s 經驗的團隊,和需要多雲可攜性的架構。
EKS 的成本
別忽略 Control Plane 費用:73/月**,這還沒算 Worker Node。
# 建立 EKS Cluster(用 eksctl 比較不痛苦)
eksctl create cluster \
--name prod-cluster \
--region ap-northeast-1 \
--version 1.31 \
--vpc-private-subnets subnet-private-1a,subnet-private-1c \
--vpc-public-subnets subnet-public-1a,subnet-public-1c \
--nodegroup-name workers \
--node-type t3.medium \
--nodes 3 \
--nodes-min 2 \
--nodes-max 5 \
--managedEKS vs 自架 K8s
| 面向 | 自架 K8s | EKS |
|---|---|---|
| Control Plane | 自己維護 etcd/API Server | AWS 託管 |
| 升版 | 手動、怕爆 | eksctl upgrade cluster |
| IAM 整合 | 沒有 | IRSA(Pod 層級 IAM) |
| Networking | CNI 自己選 | VPC CNI(Pod 拿 VPC IP) |
| 成本 | 機器費用 | 機器 + $73/月 Control Plane |
決策框架
你的 App 容器化了嗎?
├─ 否 → EC2(先容器化再說)
├─ 是 → 團隊有 K8s 經驗嗎?
│ ├─ 否 → ECS + Fargate
│ └─ 是 → 需要多雲嗎?
│ ├─ 否 → ECS(省錢省事)
│ └─ 是 → EKS
我的真心建議:除非你有很強的理由選 EKS(多雲、團隊已熟 K8s),否則 ECS + Fargate 是最省心的選擇。EKS 的 overhead 不只是 $73/月,還有學習成本和維運複雜度。
自架 vs AWS
| 面向 | 自架(Docker Compose) | ECS Fargate | EKS |
|---|---|---|---|
| 部署方式 | docker-compose up | Task Definition | kubectl apply |
| Scaling | 手動 / 腳本 | Application Auto Scaling | HPA |
| 服務發現 | Docker network | CloudMap / ALB | K8s Service |
| Log | Docker log driver | CloudWatch Logs | Fluentd/Loki |
| 成本 | 機器費用 | 按 vCPU/Memory 秒計 | 機器 + CP 費 |
如果你在 Infra 系列讀過 Container Runtime,ECS Task Definition 就是 Docker Compose 的 AWS 版。而 Compose vs K8s 的決策,在 AWS 上變成了 ECS vs EKS。
K8s 映射
| ECS 概念 | K8s 對應 |
|---|---|
| Cluster | Cluster |
| Task Definition | Pod spec / Deployment |
| Service | Deployment + Service |
| Task | Job |
| Fargate | Virtual Kubelet / Fargate on EKS |
| Application Auto Scaling | HPA (Horizontal Pod Autoscaler) |
如果你選了 EKS,那就是完整的 K8s——直接看 K8s Workloads 吧。
系列導覽
選 Compute 方案就像選車——不是最貴的最好,是最適合你的路況的最好。