AWS Learning
Compute

Amazon ECS (Elastic Container Service)

Elastic Container Service, Task Definitions, Services, Fargate

Tổng quan

Amazon ECS (Elastic Container Service) là dịch vụ quản lý container được AWS quản lý hoàn toàn (fully managed). ECS giúp bạn chạy, dừng và quản lý Docker containers trên một cluster.

Container là gì?

┌────────────────────────────────────────────────────────────┐
│                    VIRTUAL MACHINE                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│  │   App A  │  │   App B  │  │   App C  │                  │
│  ├──────────┤  ├──────────┤  ├──────────┤                  │
│  │  Libs A  │  │  Libs B  │  │  Libs C  │                  │
│  ├──────────┤  ├──────────┤  ├──────────┤                  │
│  │ Guest OS │  │ Guest OS │  │ Guest OS │  ← Mỗi VM có OS  │
│  └──────────┘  └──────────┘  └──────────┘                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              Hypervisor (VMware, KVM)               │   │
│  ├─────────────────────────────────────────────────────┤   │
│  │                    Host OS                          │   │
│  └─────────────────────────────────────────────────────┘   │
└────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────┐
│                      CONTAINERS                            │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│  │   App A  │  │   App B  │  │   App C  │                  │
│  │ + Libs A │  │ + Libs B │  │ + Libs C │                  │
│  └──────────┘  └──────────┘  └──────────┘                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │           Container Runtime (Docker)                │   │
│  ├─────────────────────────────────────────────────────┤   │
│  │                Host OS (1 OS duy nhất!)             │   │
│  └─────────────────────────────────────────────────────┘   │
└────────────────────────────────────────────────────────────┘

Tại sao dùng Containers?

VM (Virtual Machine)Container
❌ Khởi động chậm (phút)✅ Khởi động nhanh (giây)
❌ Tốn nhiều resources✅ Nhẹ, chia sẻ OS kernel
❌ Mỗi VM cần Guest OS✅ Không cần Guest OS
❌ Image size lớn (GBs)✅ Image size nhỏ (MBs)
✅ Isolation hoàn toàn⚠️ Isolation ít hơn

Tại sao cần ECS?

Tự quản lý DockerAmazon ECS
Phải setup Docker Swarm/K8sAWS quản lý hoàn toàn
Tự scheduling containersECS tự động scheduling
Tự quản lý clusterCluster quản lý sẵn
Tự thiết lập load balancingTích hợp ALB/NLB
Tự cấu hình auto-scalingApplication Auto Scaling

Giải thích chi tiết từng điểm:


1. Phải setup Docker Swarm/K8s vs AWS quản lý hoàn toàn

┌─────────────────────────────────────────────────────────────────────┐
│                    TỰ QUẢN LÝ (Docker Swarm/K8s)                    │
│                                                                     │
│   Bạn phải:                                                         │
│   ├── Cài đặt Docker trên từng server                               │
│   ├── Setup Swarm cluster hoặc K8s master/worker nodes              │
│   ├── Cấu hình network overlay (Flannel, Calico, Weave)             │
│   ├── Setup etcd cluster để lưu state                               │
│   ├── Cấu hình TLS certificates                                     │
│   ├── Monitor cluster health                                        │
│   └── Upgrade/patch cluster components                              │
│                                                                     │
│   ⏰ Thời gian setup: 2-5 ngày                                      │
│   👨‍💻 Yêu cầu: DevOps engineer có kinh nghiệm                        │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                         AMAZON ECS                                  │
│                                                                     │
│   Bạn chỉ cần:                                                      │
│   └── aws ecs create-cluster --cluster-name my-cluster              │
│                                                                     │
│   ⏰ Thời gian setup: 5 phút                                        │
│   👨‍💻 Yêu cầu: Biết cơ bản về containers                             │
│                                                                     │
│   AWS lo phần còn lại:                                              │
│   ├── Control plane                                                 │
│   ├── State management                                              │
│   ├── API server                                                    │
│   └── Cluster coordination                                          │
└─────────────────────────────────────────────────────────────────────┘

2. Tự scheduling containers vs ECS tự động scheduling

Scheduling = Quyết định container nào chạy trên server nào.

┌─────────────────────────────────────────────────────────────────────┐
│                         TỰ SCHEDULING                               │
│                                                                     │
│  Bạn có 3 servers, mỗi server có resources khác nhau:               │
│                                                                     │
│  Server 1: 4 CPU, 8GB RAM (đang dùng 3 CPU, 6GB)                    │
│  Server 2: 2 CPU, 4GB RAM (đang dùng 0.5 CPU, 1GB)                  │
│  Server 3: 4 CPU, 16GB RAM (đang dùng 4 CPU, 14GB)                  │
│                                                                     │
│  → Bạn muốn deploy container cần 1 CPU, 2GB RAM                     │
│  → Bạn phải TỰ kiểm tra server nào có đủ resources                  │
│  → Nếu Server 3 đầy, bạn phải đổi sang Server 1/2                   │
│  → Phải viết logic để handle failures, retries                      │
│                                                                     │
│  ❌ Prone to human error                                            │
│  ❌ Khó scale khi có 50+ servers                                    │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                       ECS SCHEDULER                                 │
│                                                                     │
│  ECS tự động:                                                       │
│  ├── Track resources của tất cả instances                           │
│  ├── Tìm instance phù hợp nhất (bin packing)                        │
│  ├── Handle constraints (AZ, instance type, custom)                 │
│  ├── Retry nếu placement fail                                       │
│  └── Rebalance khi cần                                              │
│                                                                     │
│  Placement Strategies:                                              │
│                                                                     │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐               │
│  │   BINPACK    │  │   SPREAD     │  │   RANDOM     │               │
│  │              │  │              │  │              │               │
│  │ Tối ưu cost  │  │ Tối ưu HA    │  │ Đơn giản     │               │
│  │ Pack đầy 1   │  │ Spread đều   │  │ Chọn random  │               │
│  │ server trước │  │ các AZs      │  │              │               │
│  └──────────────┘  └──────────────┘  └──────────────┘               │
│                                                                     │
│  ✅ Tự động, không cần can thiệp                                    │
│  ✅ Scale tới hàng ngàn containers                                  │
└─────────────────────────────────────────────────────────────────────┘

Ví dụ Placement Strategy:

# Spread tasks across Availability Zones (HA)
aws ecs create-service \
  --placement-strategy type=spread,field=attribute:ecs.availability-zone
 
# Pack tasks to minimize EC2 instances (cost)
aws ecs create-service \
  --placement-strategy type=binpack,field=memory

3. Tự quản lý cluster vs Cluster quản lý sẵn

┌─────────────────────────────────────────────────────────────────────┐
│                    TỰ QUẢN LÝ CLUSTER                               │
│                                                                     │
│  Khi 1 server chết:                                                 │
│  ┌────────────────────────────────────────────────────────────┐     │
│  │  1. Monitor alert (bạn phải setup monitoring trước)        │     │
│  │  2. SSH vào server để debug (nếu còn access được)          │     │
│  │  3. Quyết định: repair hay replace?                        │     │
│  │  4. Nếu replace:                                           │     │
│  │     a. Provision server mới                                │     │
│  │     b. Cài Docker                                          │     │
│  │     c. Join vào cluster                                    │     │
│  │     d. Migrate containers                                  │     │
│  │  5. Remove server cũ khỏi cluster                          │     │
│  │  6. Update DNS/LB nếu cần                                  │     │
│  └────────────────────────────────────────────────────────────┘     │
│                                                                     │
│  ⏰ Thời gian: 30 phút - vài giờ                                    │
│  🚨 Có thể xảy ra lúc 3 giờ sáng!                                   │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                     ECS MANAGED CLUSTER                             │
│                                                                     │
│  Với Fargate:                                                       │
│  └── Không có server để quản lý! AWS lo tất cả.                     │
│                                                                     │
│  Với EC2 + ECS:                                                     │
│  ┌────────────────────────────────────────────────────────────┐     │
│  │  1. ECS detect container instance unhealthy                │     │
│  │  2. Tasks được reschedule sang instance khác TỰ ĐỘNG       │     │
│  │  3. Auto Scaling Group thay thế instance mới               │     │
│  │  4. Instance mới tự động join cluster (ECS Agent)          │     │
│  └────────────────────────────────────────────────────────────┘     │
│                                                                     │
│  ⏰ Thời gian: 1-5 phút (tự động)                                   │
│  😴 Bạn có thể tiếp tục ngủ!                                        │
└─────────────────────────────────────────────────────────────────────┘

4. Tự thiết lập load balancing vs Tích hợp ALB/NLB

┌─────────────────────────────────────────────────────────────────────┐
│                    TỰ SETUP LOAD BALANCING                          │
│                                                                     │
│  Bạn phải:                                                          │
│  ├── Setup HAProxy/Nginx làm load balancer                          │
│  ├── Cấu hình health checks                                         │
│  ├── Update config mỗi khi container start/stop                     │
│  ├── Handle SSL termination                                         │
│  └── Setup HA cho chính load balancer                               │
│                                                                     │
│  Vấn đề với Dynamic Ports:                                          │
│  ┌──────────────────────────────────────────────────┐               │
│  │  Container 1: host:32768 → container:80          │               │
│  │  Container 2: host:32769 → container:80          │               │
│  │  Container 3: host:32770 → container:80          │               │
│  │                                                  │               │
│  │  → Port thay đổi mỗi lần deploy!                 │               │
│  │  → Phải update LB config liên tục                │               │
│  │  → Thường dùng Service Discovery (Consul, etc)   │               │
│  └──────────────────────────────────────────────────┘               │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                    ECS + ALB INTEGRATION                            │
│                                                                     │
│         ┌─────────────────────────────────────┐                     │
│         │     Application Load Balancer       │                     │
│         │     (AWS managed, HA by default)    │                     │
│         └───────────────┬─────────────────────┘                     │
│                        │                                            │
│         ┌───────────────┼───────────────┐                           │
│         ▼               ▼               ▼                           │
│    ┌─────────┐    ┌─────────┐    ┌─────────┐                        │
│    │ Task 1  │    │ Task 2  │    │ Task 3  │                        │
│    │ :32768  │    │ :32769  │    │ :32770  │                        │
│    └─────────┘    └─────────┘    └─────────┘                        │
│                                                                     │
│  ECS tự động:                                                       │
│  ├── Register task vào Target Group khi start                       │
│  ├── Deregister khi task stop                                       │
│  ├── Handle dynamic ports (ECS biết port mapping)                   │
│  ├── Connection draining trước khi remove                           │
│  └── Health check integration                                       │
│                                                                     │
│  ✅ Zero manual intervention!                                       │
└─────────────────────────────────────────────────────────────────────┘

Ví dụ cấu hình:

// Service Definition với Load Balancer
{
  "serviceName": "my-service",
  "loadBalancers": [
    {
      "targetGroupArn": "arn:aws:elasticloadbalancing:...:targetgroup/my-tg/xxx",
      "containerName": "my-app",
      "containerPort": 80
    }
  ],
  "healthCheckGracePeriodSeconds": 60
}

5. Tự cấu hình auto-scaling vs Application Auto Scaling

┌─────────────────────────────────────────────────────────────────────┐
│                    TỰ SETUP AUTO SCALING                            │
│                                                                     │
│  Bạn phải viết custom solution:                                     │
│                                                                     │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │  1. Collect metrics (Prometheus, custom scripts)             │   │
│  │  2. Viết scaling logic:                                      │   │
│  │     if cpu > 70%:                                            │   │
│  │         spawn_more_containers()                              │   │
│  │     if cpu < 30%:                                            │   │
│  │         terminate_containers()                               │   │
│  │  3. Handle cooldown periods                                  │   │
│  │  4. Prevent thrashing (scale up/down liên tục)               │   │
│  │  5. Implement min/max limits                                 │   │
│  │  6. Scale servers (nếu hết capacity)                         │   │
│  └──────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  ❌ Phức tạp, dễ bugs                                               │
│  ❌ Không scale đủ nhanh                                            │
│  ❌ Có thể scale sai (over/under provision)                         │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                 ECS + APPLICATION AUTO SCALING                      │
│                                                                     │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │                    CloudWatch                                │   │
│  │        ┌─────────────────────────────────────┐               │   │
│  │        │  ECSServiceAverageCPUUtilization    │               │   │
│  │        │         Current: 75%                │               │   │
│  │        │         Target: 70%                 │               │   │
│  │        └─────────────────┬───────────────────┘               │   │
│  │                          │                                   │   │
│  │                          ▼                                   │   │
│  │        ┌─────────────────────────────────────┐               │   │
│  │        │    Application Auto Scaling          │              │   │
│  │        │    Action: Scale Out                 │              │   │
│  │        └─────────────────┬───────────────────┘               │   │
│  │                          │                                   │   │
│  │                          ▼                                   │   │
│  │        ┌─────────────────────────────────────┐               │   │
│  │        │    ECS Service                       │              │   │
│  │        │    Desired: 3 → 4 tasks             │               │   │
│  │        └─────────────────────────────────────┘               │   │
│  └──────────────────────────────────────────────────────────────┘   │
│                                                                     │
│  Các loại scaling policies:                                         │
│                                                                     │
│  1. Target Tracking (set-and-forget):                               │
│     "Giữ CPU ở mức 70%"                                             │
│                                                                     │
│  2. Step Scaling (chi tiết hơn):                                    │
│     CPU 70-80%: +1 task                                             │
│     CPU 80-90%: +2 tasks                                            │
│     CPU > 90%: +4 tasks                                             │
│                                                                     │
│  3. Scheduled Scaling:                                              │
│     9 AM: Scale to 10 tasks (giờ cao điểm)                          │
│     6 PM: Scale to 3 tasks (giờ thấp điểm)                          │
│                                                                     │
│  ✅ AWS đã test và tối ưu                                           │
│  ✅ Integrate seamlessly với ECS                                    │
│  ✅ Predictive scaling (ML-based)                                   │
└─────────────────────────────────────────────────────────────────────┘

Ví dụ cấu hình Target Tracking:

# Đăng ký scalable target
aws application-autoscaling register-scalable-target \
  --service-namespace ecs \
  --resource-id service/my-cluster/my-service \
  --scalable-dimension ecs:service:DesiredCount \
  --min-capacity 2 \
  --max-capacity 10
 
# Tạo scaling policy (Target Tracking)
aws application-autoscaling put-scaling-policy \
  --service-namespace ecs \
  --resource-id service/my-cluster/my-service \
  --scalable-dimension ecs:service:DesiredCount \
  --policy-name cpu70-target-tracking \
  --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration '{
    "TargetValue": 70.0,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
    },
    "ScaleOutCooldown": 60,
    "ScaleInCooldown": 300
  }'

Tóm tắt: Tự quản lý vs ECS

Công việcTự quản lýECS
Setup cluster2-5 ngày5 phút
SchedulingCode customBuilt-in
Server failureManual responseAuto heal
Load balancingDIY + maintain1 config
Auto scalingCustom scriptsPolicy config
Total DevOps effortCaoThấp

💡 Kết luận: ECS cho phép bạn tập trung vào application code thay vì infrastructure management. Đặc biệt với Fargate, bạn không cần quan tâm đến servers nữa!


Kiến trúc ECS

Các thành phần chính

┌─────────────────────────────────────────────────────────────┐
│                        ECS CLUSTER                          │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                    ECS SERVICE                      │    │
│  │                                                     │    │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐           │    │
│  │  │  TASK    │  │  TASK    │  │  TASK    │           │    │
│  │  │┌────────┐│  │┌────────┐│  │┌────────┐│           │    │
│  │  ││Container││  ││Container││  ││Container││        │    │
│  │  │└────────┘│  │└────────┘│  │└────────┘│           │    │
│  │  └──────────┘  └──────────┘  └──────────┘           │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  ┌───────────────────────┐  ┌───────────────────────┐       │
│  │ Container Instance 1  │  │ Container Instance 2  │       │
│  │ (EC2 hoặc Fargate)    │  │ (EC2 hoặc Fargate)    │       │
│  └───────────────────────┘  └───────────────────────┘       │
└─────────────────────────────────────────────────────────────┘

1. Cluster (Cụm)

┌─────────────────────────────────────────────────────────────────────┐
│                           ECS CLUSTER                               │
│                                                                     │
│   = Một "nhóm logic" để quản lý tất cả resources ECS                │
│                                                                     │
│   Ví von: Cluster giống như 1 CÔNG TY                               │
│   - Công ty có nhiều phòng ban (Services)                           │
│   - Mỗi phòng ban có nhiều nhân viên (Tasks)                        │
│   - Công ty thuê văn phòng (EC2) hoặc coworking space (Fargate)     │
│                                                                     │
│   Trong 1 cluster có:                                               │
│   ├── Nhiều Services                                                │
│   ├── Nhiều Tasks                                                   │
│   ├── Compute resources (EC2 hoặc Fargate)                          │
│   └── Configs, settings chung                                       │
└─────────────────────────────────────────────────────────────────────┘

Khi nào tạo nhiều clusters?

  • Môi trường khác nhau: dev-cluster, staging-cluster, prod-cluster
  • Projects tách biệt hoàn toàn
  • Regions khác nhau

2. Task Definition (Bản thiết kế)

┌─────────────────────────────────────────────────────────────────────┐
│                        TASK DEFINITION                              │
│                                                                     │
│   = BẢN THIẾT KẾ / BLUEPRINT để tạo container                       │
│   = Giống như "công thức nấu ăn"                                    │
│                                                                     │
│   Task Definition KHÔNG PHẢI là container đang chạy!                │
│   Nó chỉ MÔ TẢ cách tạo container.                                  │
│                                                                     │
│   Một Task Definition bao gồm:                                      │
│   ├── Image nào? (nginx:latest, my-app:v1.2.3)                      │
│   ├── Cần bao nhiêu CPU, Memory?                                    │
│   ├── Port mapping? (host:80 → container:80)                        │
│   ├── Environment variables?                                        │
│   ├── Secrets? (password từ Secrets Manager)                        │
│   ├── Logging config? (CloudWatch)                                  │
│   ├── Volume mounts?                                                │
│   └── IAM roles?                                                    │
│                                                                     │
│   Versioned: my-app:1, my-app:2, my-app:3 (revisions)               │
└─────────────────────────────────────────────────────────────────────┘

Ví dụ Task Definition JSON:

{
  "family": "my-web-app",
  "cpu": "256",
  "memory": "512",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "nginx:1.21",
      "portMappings": [
        { "containerPort": 80 }
      ],
      "environment": [
        { "name": "ENV", "value": "production" }
      ],
      "secrets": [
        { "name": "DB_PASSWORD", "valueFrom": "arn:aws:secretsmanager:..." }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/my-web-app"
        }
      }
    }
  ]
}

3. Task (Công việc đang chạy)

┌─────────────────────────────────────────────────────────────────────┐
│                             TASK                                    │
│                                                                     │
│   = INSTANCE của Task Definition đang chạy                          │
│   = Container(s) thực sự đang chạy                                  │
│                                                                     │
│   Ví von:                                                           │
│   - Task Definition = Công thức pizza                               │
│   - Task = Chiếc pizza thật đang được làm/ăn                        │
└─────────────────────────────────────────────────────────────────────┘

1 Task có thể chứa NHIỀU Containers!

TRƯỜNG HỢP 1: 1 Task = 1 Container (phổ biến nhất - 90%)
┌─────────────────────────────────────────────┐
│                  TASK                       │
│   ┌─────────────────────────────────────┐   │
│   │         Container: user-api         │   │
│   │         (Node.js app)               │   │
│   └─────────────────────────────────────┘   │
└─────────────────────────────────────────────┘

TRƯỜNG HỢP 2: 1 Task = NHIỀU Containers (sidecar pattern)
┌─────────────────────────────────────────────┐
│                  TASK                       │
│   ┌─────────────────┐  ┌─────────────────┐  │
│   │  Container 1:   │  │  Container 2:   │  │
│   │  nginx          │  │  app            │  │
│   │  (reverse proxy)│  │  (Python Flask) │  │
│   └─────────────────┘  └─────────────────┘  │
│                                             │
│   Cả 2 chia sẻ:                             │
│   - Network (gọi nhau qua localhost)        │
│   - Storage volumes                         │
│   - Lifecycle (sống chết cùng nhau)         │
└─────────────────────────────────────────────┘

Khi nào dùng nhiều containers trong 1 Task?

PatternVí dụ
SidecarApp + Log collector
Reverse ProxyNginx + Python app
Service MeshEnvoy + Your app

⚠️ Lưu ý: Containers trong cùng Task KHÔNG THỂ scale riêng - cả nhóm scale cùng nhau!


4. Service (Dịch vụ)

┌─────────────────────────────────────────────────────────────────────┐
│                           SERVICE                                   │
│                                                                     │
│   = Đảm bảo số lượng Tasks mong muốn LUÔN CHẠY                      │
│   = "Supervisor" giám sát Tasks                                     │
│                                                                     │
│   Service nói: "Tôi muốn luôn có 3 tasks chạy"                      │
│   ┌──────────┐  ┌──────────┐  ┌──────────┐                          │
│   │  Task 1  │  │  Task 2  │  │  Task 3  │                          │
│   │ RUNNING  │  │ RUNNING  │  │ RUNNING  │                          │
│   └──────────┘  └──────────┘  └──────────┘                          │
│                                                                     │
│   Nếu Task 2 chết:                                                  │
│   ┌──────────┐  ┌──────────┐  ┌──────────┐                          │
│   │  Task 1  │  │  Task 2  │  │  Task 4  │ ← Service tự tạo mới!    │
│   │ RUNNING  │  │  DEAD ❌ │  │ RUNNING  │                          │
│   └──────────┘  └──────────┘  └──────────┘                          │
│                                                                     │
│   Service làm gì?                                                   │
│   ├── Duy trì số lượng tasks (desired count)                        │
│   ├── Tự động restart tasks bị crash                                │
│   ├── Kết nối với Load Balancer                                     │
│   ├── Rolling deployments (cập nhật từ từ)                          │
│   ├── Health checks                                                 │
│   └── Auto scaling                                                  │
└─────────────────────────────────────────────────────────────────────┘

Task vs Service:

TaskService
Chạy 1 lần rồi kết thúcChạy liên tục, tự restart
Batch jobs, cron jobsWeb servers, APIs
Manually start/stopTự động maintain

5. Container Instance (Chỉ với EC2 Launch Type)

┌──────────────────────────────────────────────────────────────────────┐
│                      CONTAINER INSTANCE                              │
│                                                                      │
│   = EC2 instance đã đăng ký với ECS cluster                          │
│   = Máy chủ thật chạy containers                                     │
│                                                                      │
│   ┌─────────────────────────────────────────────────────────────┐    │
│   │                   EC2 Instance                              │    │
│   │  ┌──────────────────────────────────────────────────────┐    │   │
│   │  │  ECS Agent (chạy sẵn trong ECS-optimized AMI)        │    │   │
│   │  │  - Giao tiếp với ECS control plane                   │    │   │
│   │  │  - Nhận lệnh start/stop containers                   │    │   │
│   │  │  - Báo cáo resource usage                            │    │   │
│   │  └──────────────────────────────────────────────────────┘    │   │
│   │                                                             │    │
│   │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐             │   │
│   │  │ Container 1 │ │ Container 2 │ │ Container 3 │             │   │
│   │  └─────────────┘ └─────────────┘ └─────────────┘             │   │
│   │                                                             │    │
│   │  Docker daemon, OS, etc.                                    │    │
│   └─────────────────────────────────────────────────────────────┘    │
│                                                                      │
│   ⚠️ Fargate KHÔNG có Container Instance - AWS quản lý hết!          │
└──────────────────────────────────────────────────────────────────────┘

Tổng kết quan hệ các thành phần

┌─────────────────────────────────────────────────────────────────────┐
│                           CLUSTER                                   │
│    = Công ty / Tổ chức                                              │
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │                        SERVICE A                              │  │
│  │    = Phòng ban (luôn duy trì X nhân viên)                     │  │
│  │                                                               │  │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐                        │  │
│  │  │ Task 1  │  │ Task 2  │  │ Task 3  │   = Nhân viên          │  │
│  │  └─────────┘  └─────────┘  └─────────┘                        │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │                        SERVICE B                              │  │
│  │  ┌─────────┐  ┌─────────┐                                     │  │
│  │  │ Task 1  │  │ Task 2  │                                     │  │
│  │  └─────────┘  └─────────┘                                     │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  TASK DEFINITION = Hướng dẫn tạo Task (blueprint)                   │
│  CONTAINER INSTANCE = Văn phòng (EC2) - nơi làm việc                │
└─────────────────────────────────────────────────────────────────────┘
Thành phầnVí vonMô tả
ClusterCông tyNhóm logic quản lý mọi thứ
Task DefinitionBản mô tả công việcBlueprint để tạo container
TaskNhân viên đang làm việcContainer(s) đang chạy
ServicePhòng banĐảm bảo luôn có đủ Tasks
Container InstanceVăn phòngEC2 chạy containers

Launch Types: EC2 vs Fargate

Tại sao ECS cần EC2 hoặc Fargate? Mỗi cái làm gì?

Điểm quan trọng cần hiểu:

  • ECS là bộ não điều khiển (không có CPU/RAM)
  • EC2/Fargate là cơ bắp thực thi (có CPU/RAM thật)
  • Container = chương trình → cần MÁY THẬT để chạy!
  • Không có EC2/Fargate = ECS không thể chạy container nào cả!
┌─────────────────────────────────────────────────────────────────────┐
│                          ECS (Orchestrator)                         │
│                       🧠 "BỘ NÃO ĐIỀU KHIỂN"                        │
│                                                                     │
│   ECS LÀM:                                                          │
│   ├── Quyết định container chạy ở đâu (scheduling)                  │
│   ├── Ra lệnh khởi động/dừng containers                             │
│   ├── Theo dõi health của containers                                │
│   ├── Tự động restart container nếu chết                            │
│   ├── Scale số lượng containers lên/xuống                           │
│   └── Kết nối containers với Load Balancer                          │
│                                                                     │
│   ECS KHÔNG LÀM:                                                    │
│   ├── ❌ Cung cấp CPU/RAM để chạy containers                        │
│   └── ❌ Thực sự "chạy" container processes                         │
└─────────────────────────────────────────────────────────────────────┘

                                │ ECS ra lệnh: "Chạy container này!"

┌─────────────────────────────────────────────────────────────────────┐
│                     EC2 (Compute Resources)                         │
│                        💪 "CƠ BẮP THỰC THI"                         │
│                                                                     │
│   EC2 LÀM:                                                          │
│   ├── Cung cấp CPU, RAM, Disk vật lý                                │
│   ├── Chạy Docker daemon (container runtime)                        │
│   ├── Thực sự execute container processes                           │
│   └── Cung cấp network interface cho containers                     │
│                                                                     │
│   EC2 KHÔNG LÀM:                                                    │
│   ├── ❌ Biết nên chạy container nào (chờ lệnh từ ECS)              │
│   ├── ❌ Tự động scale containers                                   │
│   └── ❌ Quyết định logic deployment                                │
└─────────────────────────────────────────────────────────────────────┘

🍕 Ví dụ: Tiệm Pizza

Vai tròTrong tiệm PizzaTrong AWS
ManagerNhận order, phân công thợ làm pizza nàoECS (Orchestrator)
Thợ làm bánhThực sự nhào bột, nướng bánhEC2 (Compute)
PizzaSản phẩm được tạo raContainer (App)
Công thứcHướng dẫn làm pizzaTask Definition

Nếu chỉ có Manager (ECS), không có Thợ (EC2):

Manager: "Làm 5 pizza Margherita!"
...
...
Không ai làm 😅 → Cần có thợ (EC2/Fargate) để thực hiện!

Nếu chỉ có Thợ (EC2), không có Manager (ECS):

Thợ: "Tôi có tay, có lò nướng... nhưng làm pizza nào?"
Thợ: "Ai order? Bao nhiêu cái? Loại gì?"
→ Cần có manager (ECS) để điều phối!

Vậy 2 Launch Types là gì?

Launch Type = Cách bạn cung cấp "thợ làm bánh" cho ECS

┌──────────────────────────────────────────────────────────────────────┐
│                         ECS CLUSTER                                  │
│                     (Manager/Orchestrator)                           │
│                                                                      │
│                              │                                       │
│          ┌───────────────────┴───────────────────┐                   │
│          ▼                                       ▼                   │
│  ┌───────────────────┐                ┌────────────────────┐         │
│  │  EC2 LAUNCH TYPE  │                │ FARGATE LAUNCH TYPE│         │
│  │                   │                │                    │         │
│  │  Bạn thuê EC2     │                │  AWS cung cấp      │         │
│  │  instances và     │                │  compute ẩn danh   │         │
│  │  đăng ký với ECS  │                │  tự động           │         │
│  │                   │                │                    │         │
│  │  🏠 Thuê nhà      │                │  🏨 Ở khách sạn    │         │
│  │  (tự lo mọi thứ)  │                │  (họ lo tất cả)    │         │
│  └───────────────────┘                └────────────────────┘         │
└──────────────────────────────────────────────────────────────────────┘
EC2 Launch TypeFargate Launch Type
Ai cung cấp máy?Bạn tạo EC2 instancesAWS tự động cung cấp
Bạn thấy servers?✅ Có, SSH được❌ Không thấy, serverless
Ví vonThuê nhà, tự quản lýỞ khách sạn, họ lo hết

So sánh tổng quan

┌──────────────────────────────────────┐  ┌──────────────────────────────────────┐
│           EC2 LAUNCH TYPE             │  │         FARGATE LAUNCH TYPE           │
│         "Thuê nhà riêng"              │  │          "Ở khách sạn"                │
│                                        │  │                                        │
│  ┌────────────────────────────────┐   │  │  ┌────────────────────────────────┐   │
│  │      BẠN QUẢN LÝ                │   │  │      AWS QUẢN LÝ                  │   │
│  │  ┌──────────────────────────┐  │   │  │  ┌──────────────────────────┐    │   │
│  │  │ EC2 Instances            │  │   │  │  │ Compute Resources        │    │   │
│  │  │ - Provisioning           │  │   │  │  │ (Serverless containers)  │    │   │
│  │  │ - Scaling                │  │   │  │  └──────────────────────────┘    │   │
│  │  │ - Patching               │  │   │  └────────────────────────────────┘   │
│  │  │ - AMI updates            │  │   │                                        │
│  │  └──────────────────────────┘  │   │  ┌────────────────────────────────┐   │
│  └────────────────────────────────┘   │  │      BẠN QUẢN LÝ                │   │
│                                        │  │  - Task Definitions              │   │
│  Bạn: Trả tiền EC2 + quản lý servers  │  │  - Container images              │   │
│                                        │  │  - Application code              │   │
│                                        │  └────────────────────────────────┘   │
└──────────────────────────────────────┘  └──────────────────────────────────────┘

So sánh chi tiết

Tiêu chíEC2 Launch TypeFargate Launch Type
Quản lý serverBạn quản lý EC2AWS quản lý
PricingTrả tiền EC2 instancesTrả theo vCPU + Memory sử dụng
ScalingPhải scale EC2 + TasksChỉ scale Tasks
ControlFull control (SSH, AMI)Ít control hơn
PatchingBạn patch OSAWS lo
GPU support✅ Có❌ Không
Persistent storage✅ EBS volumes⚠️ Ephemeral (có EFS)
Startup timeNhanh hơn (EC2 sẵn)Chậm hơn 1-2 phút
Use caseWorkloads ổn định, GPUVariable workloads, dev/test

Khi nào dùng EC2 vs Fargate?

Sử dụng EC2 khiSử dụng Fargate khi
Cần GPU/special hardwareKhông muốn quản lý servers
Workload ổn định, dự đoán đượcWorkload biến động
Cần SSH debugStartup, MVP, nhanh chóng
Có Reserved InstancesKhông muốn lo capacity
Cần tận dụng Spot InstancesDevelopment, testing

Khi hết resources thì sao?

Với EC2 Launch Type:

Bạn có 2 EC2, mỗi cái 4 CPU, 8GB RAM
Đang chạy 8 containers (mỗi cái 1 CPU, 2GB)
→ HẾT CHỖ!

ECS: "Tôi cần chạy Container #9"
     → Không có EC2 nào còn resources
     → Container #9 bị PENDING... mãi mãi ❌

Giải pháp: Setup Capacity Provider + Auto Scaling Group
→ Tự động tạo thêm EC2 khi cần
→ Tự động xóa EC2 khi không cần
Trạng tháiKhông có Auto ScalingCó Auto Scaling (Capacity Provider)
Hết resourcesTask PENDING mãiTự động tạo EC2 mới → Task chạy
Dư resourcesVẫn trả tiền EC2Tự động terminate EC2 thừa

Với Fargate Launch Type:

Bạn đang chạy 8 containers
ECS: "Tôi cần chạy Container #9"
AWS Fargate: "OK! Tôi tự tìm compute và chạy ngay!" ✅

→ Container #9 chạy trong 1-2 phút
→ KHÔNG CẦN lo capacity
→ AWS có "vô hạn" resources (từ góc nhìn của bạn)
So sánhEC2 (không Auto Scaling)EC2 (có Auto Scaling)Fargate
Hết resources❌ Task PENDING⏳ Chờ EC2 mới (3-5 phút)✅ Chạy ngay (1-2 phút)
Cấu hìnhKhông cầnPhải setup ASG + Capacity ProviderKhông cần
Độ phức tạpThấpCaoThấp

Network Modes

4 Network Modes trong ECS

┌─────────────────────────────────────────────────────────────┐
│                    1. awsvpc MODE                           │
│         (Recommended cho Fargate và EC2)                    │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                    VPC                              │    │
│  │  ┌────────────┐  ┌────────────┐  ┌────────────┐     │    │
│  │  │   Task 1   │  │   Task 2   │  │   Task 3   │     │    │
│  │  │ ENI: 10.0.1.5│ │ ENI: 10.0.1.6│ │ ENI: 10.0.1.7│ │    │
│  │  └────────────┘  └────────────┘  └────────────┘     │    │
│  │       ▲              ▲              ▲               │    │
│  │       └──────────────┴──────────────┘               │    │
│  │              Mỗi task có ENI riêng                  │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  ✅ Mỗi task có Private IP riêng                            │
│  ✅ Security Groups ở task level                            │
│  ✅ REQUIRED cho Fargate                                    │
└─────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────┐
│                    2. bridge MODE                            │
│              (Default cho EC2 Linux)                         │
│                                                              │
│  ┌─────────────────────────────────────────────────────┐     │
│  │              EC2 Instance (docker0 bridge)          │     │
│  │  ┌────────────┐  ┌────────────┐  ┌────────────┐      │    │
│  │  │ Container 1│  │ Container 2│  │ Container 3│      │    │
│  │  │  Port 8080 │  │  Port 8081 │  │  Port 8082 │      │    │
│  │  └─────┬──────┘  └─────┬──────┘  └─────┬──────┘      │    │
│  │        └───────────────┼───────────────┘             │    │
│  │                   Docker Bridge                     │     │
│  │                        │                             │    │
│  │              EC2 ENI: 10.0.1.5                      │     │
│  └─────────────────────────────────────────────────────┘     │
│                                                              │
│  ⚠️ Containers chia sẻ ENI của EC2                           │
│  ⚠️ Dynamic port mapping                                     │
└──────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────┐
│                    3. host MODE                              │
│                 (EC2 Linux only)                             │
│                                                              │
│  Container dùng trực tiếp network stack của EC2              │
│  Không có port mapping, container port = host port           │
│                                                              │
│  ⚠️ Chỉ 1 task/port/instance                                 │
│  ⚠️ Không có network isolation                               │
│  ✅ Performance tốt nhất                                     │
└──────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                    4. none MODE                             │
│                                                             │
│  Container không có external network connectivity           │
│  Chỉ có loopback interface                                  │
└─────────────────────────────────────────────────────────────┘

Chọn Network Mode nào?

ModeUse Case
awsvpcMặc định cho Fargate, recommended cho EC2 mới
bridgeLegacy EC2, khi cần dynamic port mapping
hostMaximum performance, single task per port
noneBatch jobs không cần network

Network Mode vs Security Group

┌─────────────────────────────────────────────────────────────────────┐
│                                                                     │
│   NETWORK MODE = LÀM SAO để container CÓ ĐƯỢC địa chỉ mạng?         │
│   (Giống như: Máy tính được cắm dây mạng kiểu gì?)                  │
│                                                                     │
│   SECURITY GROUP = AI ĐƯỢC PHÉP gửi/nhận request?                   │
│   (Giống như: Bảo vệ cho ai vào, ai không cho vào)                  │
│                                                                     │
│   → Cả 2 làm việc CÙNG NHAU, không thay thế nhau!                   │
└─────────────────────────────────────────────────────────────────────┘

🔌 awsvpc chi tiết: EC2 có NHIỀU ENIs

┌─────────────────────────────────────────────────────────────────────┐
│                         EC2 INSTANCE                                │
│                                                                     │
│   EC2 có IP chính: 10.0.1.100 (Primary ENI - eth0)                  │
│                                                                     │
│   Với awsvpc, mỗi Task được gắn thêm ENI riêng!                     │
│                                                                     │
│   ┌───────────────────────────────────────────────────────────┐     │
│   │  Primary ENI (eth0)     │  10.0.1.100  │ EC2 management   │     │
│   ├───────────────────────────────────────────────────────────┤     │
│   │  Task 1 ENI (eth1)      │  10.0.1.5    │ ← Task 1 dùng    │     │
│   ├───────────────────────────────────────────────────────────┤     │
│   │  Task 2 ENI (eth2)      │  10.0.1.8    │ ← Task 2 dùng    │     │
│   ├───────────────────────────────────────────────────────────┤     │
│   │  Task 3 ENI (eth3)      │  10.0.1.12   │ ← Task 3 dùng    │     │
│   └───────────────────────────────────────────────────────────┘     │
│                                                                     │
│   → Mỗi Task có "card mạng" riêng, IP riêng!                        │
│   → Traffic ĐI THẲNG đến Task, KHÔNG qua IP chính của EC2!          │
└─────────────────────────────────────────────────────────────────────┘

Traffic đi như thế nào với awsvpc?

     ALB

      │ Request đến 10.0.1.5:3000


┌─────────────────────────────────────────────────────────────────────┐
│   EC2 Instance (10.0.1.100) ← KHÔNG đi qua IP này!                  │
│                                                                     │
│   ┌──────────────────┐                                              │
│   │ Task 1           │ ← Traffic đi THẲNG vào ENI của Task 1        │
│   │ ENI: 10.0.1.5    │                                              │
│   │ Port: 3000       │                                              │
│   └──────────────────┘                                              │
│                                                                     │
│   ┌──────────────────┐                                              │
│   │ Task 2           │                                              │
│   │ ENI: 10.0.1.8    │                                              │
│   └──────────────────┘                                              │
└─────────────────────────────────────────────────────────────────────┘

Task gọi Task trên cùng EC2

Task 1 (10.0.1.5) gọi Task 2 (10.0.1.8) trên CÙNG EC2:

┌─────────────────────────────────────────────────────────────────────┐
│   EC2 Instance                                                      │
│                                                                     │
│   Task 1 (10.0.1.5)  ────────────────────►  Task 2 (10.0.1.8)       │
│                                                                     │
│   → Traffic đi qua VPC network layer                                │
│   → KHÔNG cần đi qua EC2's primary IP (10.0.1.100)                  │
│   → Giống như 2 máy tính riêng biệt trong cùng mạng LAN             │
└─────────────────────────────────────────────────────────────────────┘

Tại sao awsvpc + Security Group quan trọng?

VỚI BRIDGE MODE:
┌─────────────────────────────────────────────────────────────────────┐
│   EC2 có 1 Security Group chung cho TẤT CẢ containers               │
│   ├── Container A (web) - cần port 80                               │
│   ├── Container B (admin) - chỉ internal                            │
│   └── → Không thể kiểm soát riêng từng container ❌                 │
└─────────────────────────────────────────────────────────────────────┘

VỚI AWSVPC MODE:
┌─────────────────────────────────────────────────────────────────────┐
│   Mỗi Task có ENI riêng → có Security Group riêng!                  │
│   ├── Task A (web): SG cho phép port 80 từ ALB                      │
│   ├── Task B (admin): SG chỉ cho phép từ VPN                        │
│   └── → Kiểm soát riêng từng task ✅                                │
└─────────────────────────────────────────────────────────────────────┘

Giới hạn: Số ENI trên mỗi EC2

Instance TypeMax ENIsMax Tasks (awsvpc)
t3.micro21 task
t3.small32 tasks
t3.medium32 tasks
m5.large32 tasks
m5.xlarge43 tasks

💡 Fargate không có vấn đề này - AWS quản lý compute, không giới hạn ENI!


ECS Service

Service là gì?

Service đảm bảo số lượng tasks mong muốn luôn chạy:

┌─────────────────────────────────────────────────────────────┐
│                      ECS SERVICE                            │
│                                                             │
│  Desired Count: 3                                           │
│  Running Count: 3 ✅                                        │
│                                                             │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                   │
│  │  Task 1  │  │  Task 2  │  │  Task 3  │                   │
│  │ RUNNING  │  │ RUNNING  │  │ RUNNING  │                   │
│  └──────────┘  └──────────┘  └──────────┘                   │
│                                                             │
│  Nếu Task 2 chết:                                           │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                   │
│  │  Task 1  │  │  Task 2  │  │  Task 4  │ ← Service tự tạo  │
│  │ RUNNING  │  │  DEAD ❌ │  │ RUNNING  │   task mới!       │
│  └──────────┘  └──────────┘  └──────────┘                   │
└─────────────────────────────────────────────────────────────┘

Service Scheduler Types

TypeMô tả
REPLICADuy trì số lượng tasks cố định
DAEMONMột task trên mỗi container instance (EC2 only)

Service Load Balancing

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│                   Application Load Balancer                 │
│                         │                                   │
│              ┌───────────┼───────────┐                      │
│              ▼           ▼           ▼                      │
│        ┌──────────┐┌──────────┐┌──────────┐                 │
│        │  Task 1  ││  Task 2  ││  Task 3  │                 │
│        │ Port 80  ││ Port 80  ││ Port 80  │                 │
│        └──────────┘└──────────┘└──────────┘                 │
│                                                             │
│  ✅ Health checks tự động                                   │
│  ✅ Deregister unhealthy tasks                              │
│  ✅ Session stickiness (nếu cần)                            │
└─────────────────────────────────────────────────────────────┘

ECS tự động quản lý Load Balancer:

┌─────────────────────────────────────────────────────────────────────┐
│                    ALB + ECS INTEGRATION                            │
│                                                                     │
│   ALB                    Target Group: user-service-tg              │
│   ┌─────────────┐       ┌─────────────────────────────────────────┐ │
│   │             │       │  Targets (ECS tự động cập nhật):        │ │
│   │  Listener   │──────►│  ├── 10.0.1.5:3000 (Task 1) ✅ healthy  │ │
│   │  :80        │       │  ├── 10.0.2.8:3000 (Task 2) ✅ healthy  │ │
│   │             │       │  └── 10.0.1.12:3000 (Task 3) ✅ healthy │ │
│   └─────────────┘       └─────────────────────────────────────────┘ │
│                                                                     │
│   🔄 Khi scale up (thêm Task 4):                                    │
│   - ECS tự động đăng ký Task 4 vào Target Group                     │
│   - ALB bắt đầu gửi traffic đến Task 4                              │
│                                                                     │
│   🔄 Khi Task 2 chết:                                               │
│   - Health check fail → ALB ngừng gửi traffic                       │
│   - ECS hủy đăng ký Task 2 khỏi Target Group                        │
│   - ECS tạo Task mới thay thế                                       │
└─────────────────────────────────────────────────────────────────────┘

Cấu hình Service với Load Balancer:

{
  "serviceName": "user-service",
  "taskDefinition": "user-service:15",
  "desiredCount": 3,
  "loadBalancers": [
    {
      "targetGroupArn": "arn:aws:elasticloadbalancing:...:targetgroup/user-tg/xxx",
      "containerName": "user-api",
      "containerPort": 3000
    }
  ],
  "healthCheckGracePeriodSeconds": 60
}

Lưu ý: healthCheckGracePeriodSeconds cho phép task thời gian khởi động trước khi health check bắt đầu.

Deployment Strategies

StrategyMô tảUse case
Rolling UpdateThay thế tasks dần dầnDefault, zero-downtime
Blue/GreenChuyển traffic giữa 2 environmentsProduction, rollback nhanh

Rolling Update Parameters

minimumHealthyPercent: 50   ← Ít nhất 50% tasks phải healthy
maximumPercent: 200         ← Có thể chạy tối đa 200% tasks
Desired: 4 tasks, min: 50%, max: 200%

Step 1: Đang chạy 4 tasks (v1)
Step 2: Tạo thêm 4 tasks (v2) → 8 tasks (200%)
Step 3: Stop 4 tasks v1
Step 4: Còn 4 tasks v2 ✅

🏢 High Availability & Multi-AZ

ECS hỗ trợ High Availability bằng cách spread tasks qua nhiều AZs và EC2 instances:

┌─────────────────────────────────────────────────────────────────────┐
│                              VPC                                    │
│                                                                     │
│  ┌─────────────────────────────┐   ┌─────────────────────────────┐  │
│  │     Availability Zone A     │   │     Availability Zone B     │  │
│  │                             │   │                             │  │
│  │   ┌──────────────────────┐  │   │   ┌──────────────────────┐  │  │
│  │   │   EC2 Instance #1    │  │   │   │   EC2 Instance #2    │  │  │
│  │   │                      │  │   │   │                      │  │  │
│  │   │   ┌──────┐ ┌──────┐  │  │   │   │   ┌──────┐ ┌──────┐  │  │  │
│  │   │   │Task 1│ │Task 2│  │  │   │   │   │Task 3│ │Task 4│  │  │  │
│  │   │   └──────┘ └──────┘  │  │   │   │   └──────┘ └──────┘  │  │  │
│  │   └──────────────────────┘  │   │   └──────────────────────┘  │  │
│  │                             │   │                             │  │
│  │   ┌──────────────────────┐  │   │   ┌──────────────────────┐  │  │
│  │   │   EC2 Instance #3    │  │   │   │   EC2 Instance #4    │  │  │
│  │   │   ┌──────┐           │  │   │   │   ┌──────┐ ┌──────┐  │  │  │
│  │   │   │Task 5│           │  │   │   │   │Task 6│ │Task 7│  │  │  │
│  │   │   └──────┘           │  │   │   │   └──────┘ └──────┘  │  │  │
│  │   └──────────────────────┘  │   │   └──────────────────────┘  │  │
│  └─────────────────────────────┘   └─────────────────────────────┘  │
│                                                                     │
│   SERVICE: user-service (desired count: 7)                          │
│   → ECS tự động SPREAD tasks across AZs và EC2 instances            │
│                                                                     │
│   Nếu AZ-A chết toàn bộ:                                            │
│   → Tasks 1, 2, 5 bị mất                                            │
│   → Tasks 3, 4, 6, 7 vẫn chạy ✅ (HA)                               │
│   → ECS tự động tạo tasks mới ở AZ-B                                │
└─────────────────────────────────────────────────────────────────────┘

Placement Strategies (Chiến lược đặt Tasks)

ECS có các strategies để quyết định đặt task ở đâu:

StrategyMô tảUse case
SPREADPhân bổ đều theo AZ hoặc instanceHA (khuyến nghị)
BINPACKNhồi đầy 1 instance trướcTiết kiệm chi phí
RANDOMRandomTesting
// Service definition với SPREAD strategy
{
  "serviceName": "user-service",
  "placementStrategy": [
    {
      "type": "spread",
      "field": "attribute:ecs.availability-zone"
    },
    {
      "type": "spread",
      "field": "instanceId"
    }
  ]
}

Cấu hình Multi-AZ với Fargate:

// Fargate Service - chỉ cần chỉ định subnets ở nhiều AZs
{
  "networkConfiguration": {
    "awsvpcConfiguration": {
      "subnets": [
        "subnet-aza-1",   // Private subnet AZ-A
        "subnet-azb-1"    // Private subnet AZ-B
      ],
      "securityGroups": ["sg-xxx"],
      "assignPublicIp": "DISABLED"
    }
  }
}

→ Fargate tự động spread tasks giữa các AZs!


Container Images & ECR

Amazon ECR (Elastic Container Registry)

┌─────────────────────────────────────────────────────────────┐
│                    Amazon ECR                               │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  Repository: my-app                                 │    │
│  │                                                     │    │
│  │  Images:                                            │    │
│  │  ├── my-app:latest     (123 MB)                     │    │
│  │  ├── my-app:v1.2.3     (123 MB)                     │    │
│  │  ├── my-app:v1.2.2     (120 MB)                     │    │
│  │  └── my-app:dev        (125 MB)                     │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  Features:                                                  │
│  ✅ Private registry                                        │
│  ✅ Image scanning (vulnerabilities)                        │
│  ✅ Image lifecycle policies                                │
│  ✅ Cross-region replication                                │
│  ✅ IAM integration                                         │
└─────────────────────────────────────────────────────────────┘

Push Image to ECR

# 1. Authenticate Docker to ECR
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin \
  123456789012.dkr.ecr.us-east-1.amazonaws.com
 
# 2. Build image
docker build -t my-app .
 
# 3. Tag image
docker tag my-app:latest \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
 
# 4. Push to ECR
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest

IAM Roles trong ECS

2 loại IAM Roles quan trọng

┌─────────────────────────────────────────────────────────────┐
│                    ECS IAM ROLES                            │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │ 1. Task Execution Role                              │    │
│  │    (ecsTaskExecutionRole)                           │    │
│  │                                                     │    │
│  │    ECS Agent dùng để:                               │    │
│  │    - Pull images từ ECR                             │    │
│  │    - Push logs to CloudWatch                        │    │
│  │    - Get secrets từ Secrets Manager                 │    │
│  │                                                     │    │
│  │    Policy: AmazonECSTaskExecutionRolePolicy         │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │ 2. Task Role                                        │    │
│  │    (Application permissions)                        │    │
│  │                                                     │    │
│  │    Container app dùng để:                           │    │
│  │    - Access S3 buckets                              │    │
│  │    - Query DynamoDB                                 │    │
│  │    - Send messages to SQS                           │    │
│  │    - Bất kỳ AWS service nào app cần                 │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

Ví dụ Task Role Policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-bucket/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:PutItem"
      ],
      "Resource": "arn:aws:dynamodb:*:*:table/my-table"
    }
  ]
}

Auto Scaling

ECS Service Auto Scaling

┌─────────────────────────────────────────────────────────────┐
│                  ECS SERVICE AUTO SCALING                   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │         CloudWatch Alarm: CPU > 70%                 │    │
│  │                    │                                │    │
│  │                    ▼                                │    │
│  │         Application Auto Scaling                    │    │
│  │                    │                                │    │
│  │                    ▼                                │    │
│  │         Scale Out: 3 tasks → 6 tasks                │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  Scaling Policies:                                          │
│  ├── Target Tracking: Maintain CPU at 70%                   │
│  ├── Step Scaling: Add 2 tasks if CPU > 80%                 │
│  └── Scheduled Scaling: Scale up at 9 AM                    │
└─────────────────────────────────────────────────────────────┘

Scaling Metrics phổ biến

MetricMô tả
ECSServiceAverageCPUUtilizationCPU trung bình của service
ECSServiceAverageMemoryUtilizationMemory trung bình
ALBRequestCountPerTargetRequests per target từ ALB
Custom metricsSQS queue depth, etc.

EC2 Auto Scaling (cho EC2 Launch Type)

Fargate: Chỉ cần scale Service (tasks)

EC2 Launch Type: Phải scale CẢ HAI:
  1. EC2 Auto Scaling Group (instances)
  2. ECS Service Auto Scaling (tasks)

ECS Cluster Capacity Providers giúp tự động hoá!

Secrets & Configuration

Cách truyền secrets vào containers

┌─────────────────────────────────────────────────────────────┐
│                    SECRETS MANAGEMENT                       │
│                                                             │
│  ┌─────────────────┐     ┌─────────────────────────────┐    │
│  │ AWS Secrets     │     │ AWS Systems Manager         │    │
│  │ Manager         │     │ Parameter Store             │    │
│  │                 │     │                             │    │
│  │ DB passwords    │     │ API_ENDPOINT                │    │
│  │ API keys        │     │ FEATURE_FLAG                │    │
│  │ Certificates    │     │ CONFIG_VALUES               │    │
│  └────────┬────────┘     └───────────┬─────────────────┘    │
│           │                          │                      │
│           └────────────┬─────────────┘                      │
│                        ▼                                    │
│           ┌─────────────────────────────┐                   │
│           │     ECS Task Definition     │                   │
│           │    (secrets reference)      │                   │
│           └─────────────────────────────┘                   │
│                        │                                    │
│                        ▼                                    │
│           ┌─────────────────────────────┐                   │
│           │        Container            │                   │
│           │   env: DB_PASSWORD=***      │                   │
│           └─────────────────────────────┘                   │
└─────────────────────────────────────────────────────────────┘

Task Definition với Secrets

{
  "containerDefinitions": [
    {
      "name": "my-app",
      "image": "my-app:latest",
      "secrets": [
        {
          "name": "DB_PASSWORD",
          "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:my-db-password"
        },
        {
          "name": "API_KEY",
          "valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/my-api-key"
        }
      ],
      "environment": [
        {
          "name": "APP_ENV",
          "value": "production"
        }
      ]
    }
  ]
}

Logging

Container Logging với CloudWatch

┌─────────────────────────────────────────────────────────────┐
│                    ECS LOGGING                              │
│                                                             │
│  ┌────────────────┐          ┌────────────────────────┐     │
│  │   Container    │  stdout  │   CloudWatch Logs      │     │
│  │   (app logs)   │─────────▶│   /ecs/my-service      │     │
│  │                │  stderr  │   └── task-id/...      │     │
│  └────────────────┘          └────────────────────────┘     │
│                                                             │
│  Log Driver: awslogs                                        │
│                                                             │
│  Task Definition:                                           │
│  {                                                          │
│    "logConfiguration": {                                    │
│      "logDriver": "awslogs",                                │
│      "options": {                                           │
│        "awslogs-group": "/ecs/my-service",                  │
│        "awslogs-region": "us-east-1",                       │
│        "awslogs-stream-prefix": "ecs"                       │
│      }                                                      │
│    }                                                        │
│  }                                                          │
└─────────────────────────────────────────────────────────────┘

Các Log Drivers khác

DriverDestination
awslogsCloudWatch Logs
splunkSplunk
fluentdFluentd
awsfirelensKinesis, S3, Elasticsearch (via Fluent Bit)

Pricing: EC2 vs Fargate chi tiết

Điểm khác biệt cốt lõi

EC2 Launch TypeFargate Launch Type
Trả tiền choEC2 instances (dù container chạy hay không)Từng container (vCPU + Memory)
Không chạy gìVẫn trả tiền EC2!$0
Ví vonThuê nhà tháng (trả cả tháng)Thuê phòng theo giờ

EC2 Launch Type - Cách tính

Bạn thuê 2 x t3.medium ($0.0416/giờ mỗi cái)
Chi phí cố định: $0.0832/giờ × 24 × 30 = ~$60/tháng

┌───────────────────────────────────────────────────────────────┐
│  EC2 #1                    EC2 #2                             │
│  ┌────────────────┐        ┌────────────────┐                 │
│  │ Container A    │        │ [TRỐNG]        │ ← Vẫn trả tiền! │
│  │ [TRỐNG]        │        │ [TRỐNG]        │                 │
│  └────────────────┘        └────────────────┘                 │
│                                                               │
│  Dù chỉ chạy 1 container hay 0 container → vẫn ~$60/tháng     │
└───────────────────────────────────────────────────────────────┘

Fargate Launch Type - Cách tính

Giá (US East - tham khảo):
- vCPU: $0.04048 / vCPU / giờ
- Memory: $0.004445 / GB / giờ

Ví dụ 1 container (0.5 vCPU, 1GB RAM):
- vCPU:   0.5 × $0.04048 = $0.02024/giờ
- Memory: 1 × $0.004445 = $0.00445/giờ
- Tổng:   $0.0247/giờ

Chạy 24/7 trong 1 tháng: $0.0247 × 24 × 30 = ~$17.8/container

✅ Không chạy = $0!

So sánh thực tế: 3 containers (0.5 vCPU, 1GB mỗi cái)

Thời gian chạyEC2 (2 x t3.medium)FargateAi rẻ hơn?
24/7 cả tháng~$60~$53Fargate ✅
12h/ngày~$60~$26Fargate ✅
8h/ngày (giờ làm việc)~$60~$18Fargate ✅
4h/ngày~$60~$9Fargate ✅
Tắt hết~$60$0Fargate ✅

⚠️ Lưu ý: Ví dụ trên EC2 chưa tối ưu. Với Reserved Instances hoặc Spot, EC2 sẽ rẻ hơn nhiều!

Khi nào EC2 rẻ hơn?

┌───────────────────────────────────────────────────────────────────┐
│                    ĐIỂM HÒA VỐN (~65% utilization)                │
│                                                                   │
│   Cost│                                                           │
│    ▲   │          Fargate                                         │
│        │         /                                                │
│        │        /        EC2 (On-Demand)                          │
│        │       /        ─────────────────────                     │
│        │      /                                                   │
│        │     /     EC2 (Reserved)                                 │
│        │    /     ────────────────                                │
│        │   /                                                      │
│        │  /                                                       │
│        │ /                                                        │
│        └───────────────────────────────────────────► Utilization  │
│          0%        50%       65%       80%      100%              │
│                              ▲                                    │
│                    Điểm hòa vốn                                   │
│                                                                   │
│   Utilization < 65%: Fargate rẻ hơn                               │
│   Utilization > 65%: EC2 rẻ hơn                                   │
│   Có Reserved/Spot: EC2 rẻ hơn sớm hơn                            │
└───────────────────────────────────────────────────────────────────┘

Các cách tiết kiệm

Phương phápEC2FargateTiết kiệm
On-Demand0% (baseline)
Reserved Instances30-60%
Spot Instances✅ (Fargate Spot)50-70%
Savings Plans30-50%

🎟️ Reserved Instances (RI) là gì?

┌──────────────────────────────────────────────────────────────────────┐
│                    RESERVED INSTANCES                                │
│                                                                      │
│   Bạn: "Tôi cam kết dùng t3.medium 1 năm"                            │
│   AWS: "OK! Giảm 40% giá!"                                           │
│                                                                      │
│   Ví dụ:                                                             │
│   On-Demand: $0.0416/giờ × 8760 giờ = $364/năm                       │
│   Reserved:  $0.025/giờ  × 8760 giờ = $219/năm ← TIẾT KIỆM $145!     │
│                                                                      │
│   Các option:                                                        │
│   ├── 1 năm: Giảm ~30-40%                                            │
│   ├── 3 năm: Giảm ~50-60%                                            │
│   ├── Trả trước toàn bộ: Giảm thêm                                   │
│   └── Trả hàng tháng: Ít giảm hơn                                    │
│                                                                      │
│   ⚠️ Rủi ro: Cam kết rồi không dùng → vẫn phải trả!                  │
└──────────────────────────────────────────────────────────────────────┘
Ví vonReserved Instances
🚕 On-DemandĐi taxi, bật đồng hồ
🚗 ReservedThuê xe tháng/năm - cam kết, rẻ hơn

Spot Instances là gì?

┌──────────────────────────────────────────────────────────────────────┐
│                      SPOT INSTANCES                                  │
│                                                                      │
│   AWS có 1000 máy EC2, đang dùng 700 máy                             │
│   → 300 máy đang rảnh (idle)                                         │
│   → AWS bán rẻ những máy này! (giảm 50-90%)                          │
│                                                                      │
│   On-Demand: $0.10/giờ                                               │
│   Spot:      $0.03/giờ  ← GIẢM 70%!                                  │
│                                                                      │
│   ⚠️ NHƯNG: Khi AWS cần máy, bạn bị "đuổi" với 2 phút cảnh báo!      │
└──────────────────────────────────────────────────────────────────────┘
Ví vonSpot Instances
✈️ Vé máy bay giờ chótRẻ nhưng có thể bị hủy

🚨 Khi AWS lấy lại Spot Instance thì sao?

┌─────────────────────────────────────────────────────────────────────┐
│                    SPOT INTERRUPTION FLOW                           │
│                                                                     │
│   AWS: "Tôi cần lấy lại máy này trong 2 phút!"                      │
│         │                                                           │
│          ▼ (2 phút warning)                                         │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │  1. ECS nhận được thông báo                                 │   │
│   │  2. ECS đánh dấu instance DRAINING (không nhận task mới)    │   │
│   │  3. ALB ngừng gửi traffic đến tasks trên instance này       │   │
│   │  4. Tasks được graceful shutdown (SIGTERM)                  │   │
│   │  5. Instance bị terminate                                   │   │
│   └─────────────────────────────────────────────────────────────┘   │
│         │                                                           │
│          ▼                                                          │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │  6. ECS thấy: "Desired = 3, Running = 2" → thiếu 1 task!    │   │
│   │  7. ECS tự động khởi động Task mới ở instance khác!         │   │
│   │  8. Running = 3 lại như cũ ✅                               │   │
│   └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│   → User KHÔNG BỊ ẢNH HƯỞNG (nếu setup đúng)                        │
└─────────────────────────────────────────────────────────────────────┘

Best Practices với Spot:

PracticeTại sao?
Chạy nhiều tasks (ít nhất 2)Nếu 1 bị đuổi, còn task khác phục vụ
Spread across AZsSpot bị đuổi theo AZ, spread ra giảm risk
Mix 70% Spot + 30% On-DemandLuôn có On-Demand backup
Handle SIGTERM gracefullyApp xử lý shutdown để không mất data

Khi nào KHÔNG nên dùng Spot?

❌ Không dùng SpotLý do
Database (RDS, self-hosted)Data có thể mất/corrupt
Single instance appBị đuổi = downtime
Long-running jobs không checkpointMất hết progress

Tóm tắt: Chọn loại nào?

Tình huốngRecommendation
Dev/Test, chạy vài giờ/ngàyFargate (trả theo giờ)
Startup, MVPFargate (đơn giản, không lo capacity)
Production 24/7, workload ổn địnhEC2 + Reserved (rẻ hơn 40-60%)
Workload biến động (peak hours)Fargate (scale linh hoạt)
Cần Spot để tiết kiệmEC2 Spot hoặc Fargate Spot

ECS vs EKS vs Fargate

So sánh các Container Services

┌────────────────────────────────────────────────────────────────┐
│                   AWS CONTAINER SERVICES                       │
│                                                                │
│  ┌────────────┐  ┌────────────┐  ┌────────────────────────┐    │
│  │    ECS     │  │    EKS     │  │       FARGATE          │    │
│  │            │  │            │  │   (Serverless Compute) │    │
│  │  AWS-native│  │ Kubernetes │  │                        │    │
│  │ orchestrator│  │  managed   │  │  Works with ECS or EKS│    │
│  └────────────┘  └────────────┘  └────────────────────────┘    │
│                                                                │
│  Fargate = Launch Type, không phải orchestrator                │
│  Có thể dùng Fargate với cả ECS và EKS                         │
└────────────────────────────────────────────────────────────────┘
Tiêu chíECSEKS
Learning curveDễ hơnKhó hơn
AWS integrationNative, deepQua add-ons
PortabilityAWS onlyMulti-cloud
EcosystemNhỏ hơnLớn (Kubernetes)
PricingFree control plane~$0.10/hour/cluster
Use caseAWS-focusedMulti-cloud, existing K8s

Hands-on Labs

Lab 1: Tạo ECS Cluster với Fargate

# Tạo cluster
aws ecs create-cluster --cluster-name my-cluster
 
# Verify
aws ecs list-clusters

Lab 2: Register Task Definition

// task-definition.json
{
  "family": "my-web-app",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "nginx:latest",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/my-web-app",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}
# Register task definition
aws ecs register-task-definition --cli-input-json file://task-definition.json
 
# List task definitions
aws ecs list-task-definitions

Lab 3: Tạo ECS Service

# Tạo service
aws ecs create-service \
  --cluster my-cluster \
  --service-name my-web-service \
  --task-definition my-web-app:1 \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx,subnet-yyy],securityGroups=[sg-zzz],assignPublicIp=ENABLED}"
 
# List services
aws ecs list-services --cluster my-cluster
 
# Describe service
aws ecs describe-services --cluster my-cluster --services my-web-service

Lab 4: Scale Service

# Scale up
aws ecs update-service \
  --cluster my-cluster \
  --service my-web-service \
  --desired-count 4
 
# Scale down
aws ecs update-service \
  --cluster my-cluster \
  --service my-web-service \
  --desired-count 1

Lab 5: Deploy mới (Rolling Update)

# Update task definition với image mới
# Sau đó force new deployment
aws ecs update-service \
  --cluster my-cluster \
  --service my-web-service \
  --task-definition my-web-app:2 \
  --force-new-deployment

Best Practices

1. Container Best Practices

PracticeMô tả
One process per containerMỗi container chạy 1 process chính
Small imagesDùng alpine/distroless base images
Tag imagesKhông dùng :latest cho production
Health checksĐịnh nghĩa health check trong task def
LoggingLog ra stdout/stderr

2. Security Best Practices

PracticeMô tả
Least privilegeTask roles chỉ có permissions cần thiết
Secrets ManagerKhông hardcode secrets
Private ECRKhông dùng public images cho production
VPC endpointsTruy cập AWS services qua VPC endpoints
Read-only rootReadonly filesystem khi có thể

3. Reliability Best Practices

PracticeMô tả
Multi-AZDistribute tasks across AZs
Health checksALB + Container health checks
Auto ScalingScale based on metrics
Circuit breakerEnable deployment circuit breaker
Graceful shutdownHandle SIGTERM signals

4. Cost Optimization

PracticeMô tả
Right-sizingChọn đúng CPU/Memory
Fargate SpotDùng cho fault-tolerant workloads
Reserved capacityCompute Savings Plans
Turn off dev/testScheduled scaling về 0

Troubleshooting

Common Issues

IssueNguyên nhânGiải pháp
Task stuck in PENDINGKhông đủ resourcesCheck cluster capacity
Task fails to startImage pull failedCheck ECR permissions
Service unstableHealth check failsCheck health check config
Container keeps restartingApp crashCheck container logs
Cannot connectSecurity group/networkCheck SG rules, VPC config

Debug Commands

# Check task status
aws ecs describe-tasks \
  --cluster my-cluster \
  --tasks arn:aws:ecs:...:task/...
 
# View stopped task reason
aws ecs describe-tasks \
  --cluster my-cluster \
  --tasks arn:aws:ecs:...:task/... \
  --query 'tasks[0].stoppedReason'
 
# View container logs
aws logs get-log-events \
  --log-group-name /ecs/my-service \
  --log-stream-name ecs/container-name/task-id
 
# List services with details
aws ecs describe-services \
  --cluster my-cluster \
  --services my-service
 
# Check events
aws ecs describe-services \
  --cluster my-cluster \
  --services my-service \
  --query 'services[0].events[:10]'

🛒 Ví dụ: Thiết kế Microservices E-commerce

Các Microservices

┌──────────────────────────────────────────────────────────────────────┐
│                     E-COMMERCE PLATFORM                              │
│                                                                      │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐                │
│  │   Frontend   │  │   User API   │  │  Product API │                │
│  │   (React)    │  │   (Node.js)  │  │   (Python)   │                │
│  └──────────────┘  └──────────────┘  └──────────────┘                │
│                                                                      │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐                │
│  │   Cart API   │  │  Order API   │  │ Payment API  │                │
│  │   (Node.js)  │  │    (Java)    │  │    (Go)      │                │
│  └──────────────┘  └──────────────┘  └──────────────┘                │
│                                                                      │
│  ┌──────────────┐  ┌──────────────┐                                  │
│  │ Notification │  │   Search     │                                  │
│  │   (Python)   │  │(Elasticsearch)│                                 │
│  └──────────────┘  └──────────────┘                                  │
└──────────────────────────────────────────────────────────────────────┘

Thiết kế trên ECS

┌─────────────────────────────────────────────────────────────────────┐
│                        ECS CLUSTER: prod-cluster                    │
│                                                                     │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                     ALB (Application Load Balancer)            │ │
│  │    api.myshop.com                                              │ │
│  │    /users/*  → User Service                                    │ │
│  │    /products/* → Product Service                               │ │
│  │    /orders/* → Order Service                                   │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                             │                                       │
│          ┌───────────────────┼───────────────────┐                  │
│          ▼                   ▼                   ▼                  │
│  ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐     │
│  │ SERVICE: user    │ │SERVICE: product  │ │ SERVICE: order    │    │
│  │ Desired: 2 tasks │ │ Desired: 3 tasks │ │ Desired: 2 tasks  │    │
│  │                  │ │                  │ │                   │    │
│  │ ┌────┐ ┌────┐   │ │ ┌────┐┌────┐┌────┐│ │ ┌────┐ ┌────┐     │    │
│  │ │Task│ │Task│   │ │ │Task││Task││Task││ │ │Task│ │Task│     │    │
│  │ └────┘ └────┘   │ │ └────┘└────┘└────┘│ │ └────┘ └────┘     │    │
│  └──────────────────┘ └──────────────────┘ └──────────────────┘     │
│                                                                     │
│            ↓                    ↓                 ↓                 │
│          ┌───────────────────────────────────────┐                  │
│          │                    DATABASES          │                  │
│  │  ┌─────────┐    ┌─────────┐    ┌─────────┐                   │   │
│  │  │ RDS     │    │ RDS     │    │ RDS     │                   │   │
│  │  │ (users) │    │(products)│   │ (orders)│                   │   │
│  │  └─────────┘    └─────────┘    └─────────┘                   │   │
│          └───────────────────────────────────────┘                  │
└─────────────────────────────────────────────────────────────────────┘

Chi tiết từng Service

ServiceTasksCPURAMLaunch TypeAuto Scale
user-service20.5 vCPU1 GBFargate2-10
product-service31 vCPU2 GBFargate3-15
order-api21 vCPU2 GBFargate2-8
order-worker10.5 vCPU1 GBFargate1-5
cart-service20.5 vCPU1 GBFargate2-10
payment-service20.5 vCPU1 GBFargate2-6
notification10.25 vCPU512 MBFargate1-3

Networking

┌─────────────────────────────────────────────────────────────────────┐
│                              VPC                                    │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │                    PUBLIC SUBNETS                           │    │
│  │   ┌─────────────┐                                           │    │
│  │   │     ALB     │  ← Internet facing                        │    │
│  │   └─────────────┘                                           │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                              ▼                                      │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │                   PRIVATE SUBNETS                           │    │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐            │    │
│  │  │ User    │ │ Product │ │ Order   │ │ Payment │            │    │
│  │  │ Tasks   │ │ Tasks   │ │ Tasks   │ │ Tasks   │            │    │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────┘            │    │
│  │  (Each task has its own ENI - awsvpc mode)                  │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                              ▼                                      │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │                   DATABASE SUBNETS                          │    │
│  │   ┌─────────┐ ┌─────────┐ ┌───────────┐                     │    │
│  │   │   RDS   │ │   RDS   │ │ElastiCache│                     │    │
│  │   └─────────┘ └─────────┘ └───────────┘                     │    │
│  └─────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────┘

CI/CD Deployment Flow

Developer push code


┌───────────────┐
│   GitHub      │
│   Actions     │
└───────┬───────┘
        │ Build & Push image

┌───────────────┐
│     ECR       │
│  (Container   │
│   Registry)   │
└───────┬───────┘
        │ Update Task Definition

┌───────────────┐
│     ECS       │──► Rolling deployment
│   Service     │    (từ từ replace tasks)
└───────────────┘

Tóm tắt

Khi nào dùng ECS?

Use CaseRecommendation
Mới bắt đầu với containers✅ ECS + Fargate
Team quen AWS✅ ECS
Đã có Kubernetes experience→ EKS
Multi-cloud strategy→ EKS
Serverless containers✅ ECS + Fargate
GPU workloadsECS + EC2

Quick Reference

ECS = Container Orchestrator (AWS native)
Fargate = Serverless compute for containers
ECR = Container image registry

Cluster → Service → Task → Container

Launch Types:
  EC2 = You manage servers
  Fargate = AWS manages servers

Task Definition = Blueprint for containers
Service = Ensures desired tasks running

On this page

Tổng quanContainer là gì?Tại sao dùng Containers?Tại sao cần ECS?Giải thích chi tiết từng điểm:Tóm tắt: Tự quản lý vs ECSKiến trúc ECSCác thành phần chính1. Cluster (Cụm)2. Task Definition (Bản thiết kế)3. Task (Công việc đang chạy)1 Task có thể chứa NHIỀU Containers!4. Service (Dịch vụ)5. Container Instance (Chỉ với EC2 Launch Type)Tổng kết quan hệ các thành phầnLaunch Types: EC2 vs FargateTại sao ECS cần EC2 hoặc Fargate? Mỗi cái làm gì?🍕 Ví dụ: Tiệm PizzaVậy 2 Launch Types là gì?So sánh tổng quanSo sánh chi tiếtKhi nào dùng EC2 vs Fargate?Khi hết resources thì sao?Với EC2 Launch Type:Với Fargate Launch Type:Network Modes4 Network Modes trong ECSChọn Network Mode nào?Network Mode vs Security Group🔌 awsvpc chi tiết: EC2 có NHIỀU ENIsTraffic đi như thế nào với awsvpc?Task gọi Task trên cùng EC2Tại sao awsvpc + Security Group quan trọng?Giới hạn: Số ENI trên mỗi EC2ECS ServiceService là gì?Service Scheduler TypesService Load BalancingECS tự động quản lý Load Balancer:Cấu hình Service với Load Balancer:Deployment StrategiesRolling Update Parameters🏢 High Availability & Multi-AZPlacement Strategies (Chiến lược đặt Tasks)Cấu hình Multi-AZ với Fargate:Container Images & ECRAmazon ECR (Elastic Container Registry)Push Image to ECRIAM Roles trong ECS2 loại IAM Roles quan trọngVí dụ Task Role PolicyAuto ScalingECS Service Auto ScalingScaling Metrics phổ biếnEC2 Auto Scaling (cho EC2 Launch Type)Secrets & ConfigurationCách truyền secrets vào containersTask Definition với SecretsLoggingContainer Logging với CloudWatchCác Log Drivers khácPricing: EC2 vs Fargate chi tiếtĐiểm khác biệt cốt lõiEC2 Launch Type - Cách tínhFargate Launch Type - Cách tínhSo sánh thực tế: 3 containers (0.5 vCPU, 1GB mỗi cái)Khi nào EC2 rẻ hơn?Các cách tiết kiệm🎟️ Reserved Instances (RI) là gì?Spot Instances là gì?🚨 Khi AWS lấy lại Spot Instance thì sao?Tóm tắt: Chọn loại nào?ECS vs EKS vs FargateSo sánh các Container ServicesHands-on LabsLab 1: Tạo ECS Cluster với FargateLab 2: Register Task DefinitionLab 3: Tạo ECS ServiceLab 4: Scale ServiceLab 5: Deploy mới (Rolling Update)Best Practices1. Container Best Practices2. Security Best Practices3. Reliability Best Practices4. Cost OptimizationTroubleshootingCommon IssuesDebug Commands🛒 Ví dụ: Thiết kế Microservices E-commerceCác MicroservicesThiết kế trên ECSChi tiết từng ServiceNetworkingCI/CD Deployment FlowTóm tắtKhi nào dùng ECS?Quick Reference