Bạn có Docker image, muốn chạy trên AWS. EC2 thì phải quản lý node pool, auto-scaling group, AMI update. ECS Fargate: bạn chỉ cần task definition, AWS lo phần còn lại. Không EC2, không node pool, không cluster management.
flowchart TB
ECR["ECR image"] --> TaskDef["Task Definition<br/>cpu/memory/image/secrets/logging"]
TaskDef --> Service["ECS Service<br/>desired=3 · deployment rolling"]
Service --> T1["Task (ENI)"]
Service --> T2["Task (ENI)"]
Service --> T3["Task (ENI)"]
ALB["ALB"] --> Service
CW["CloudWatch: CPU > 60%"] -->|"scale-out"| Service
Execution role (ECS agent pull image, stream log, get secrets) ≠ Task role (code trong container gọi AWS API). Tách biệt để app compromised không có quyền infrastructure.
{
"family": "myapp-api",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"containerDefinitions": [
{
"name": "api",
"image": "123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/myapp-api:v1",
"portMappings": [{ "containerPort": 3000 }],
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:...:secret:/prod/db:password::"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/myapp-api",
"awslogs-region": "ap-southeast-1",
"awslogs-stream-prefix": "api"
}
}
}
]
}
Execution role khác task role. Execution role cho ECS agent pull image và log; task role cho code trong container gọi AWS API. App compromised không có quyền infrastructure.
Auto-scaling: CPU > 60% scale-out, CDK 3 dòng code
aws application-autoscaling register-scalable-target --service-namespace ecs \
--resource-id service/myapp-cluster/api-service --min-capacity 2 --max-capacity 20
aws application-autoscaling put-scaling-policy --policy-name cpu60 \
--policy-type TargetTrackingScaling --target-tracking-scaling-policy-configuration '{
"PredefinedMetricSpecification": {"PredefinedMetricType": "ECSServiceAverageCPUUtilization"},
"TargetValue": 60
}'
const service = new ecsPatterns.ApplicationLoadBalancedFargateService(
this,
"Api",
{
cluster,
cpu: 512,
memoryLimitMiB: 1024,
desiredCount: 3,
taskImageOptions: {
image: ecs.ContainerImage.fromEcrRepository(ecrRepo),
containerPort: 3000,
secrets: { DB_PASSWORD: ecs.Secret.fromSecretsManager(dbSecret) },
},
}
);
service.service
.autoScaleTaskCount({ minCapacity: 2, maxCapacity: 20 })
.scaleOnCpuUtilization("CpuScaling", { targetUtilizationPercent: 60 });
Bài sau: Phần 22: IaC với CDK TypeScript