본문으로 건너뛰기
김신건의 로그

[AWS] ECS + Fargate: 컨테이너 오케스트레이션

· 수정 · 📖 약 3분 · 964자/단어 #aws #ecs #fargate #container #cloud #orchestration
ECS, Amazon ECS, Fargate, Task Definition, ECS Service, ECS Cluster, ECS Anywhere, Fargate Spot

정의

ECS (Elastic Container Service) = AWS 의 컨테이너 오케스트레이션. K8s 보다 단순하고 AWS 네이티브.

Fargate = ECS (또는 EKS) 의 서버리스 실행 환경. EC2 인스턴스 관리 없이 Task 단위 vCPU/Memory 예약 + 과금.

ECS 계층 구조

flowchart TB
    Cluster["Cluster (논리 그룹)"]
    Cluster --> SvcA["Service A<br/>(Deployment 역할)"]
    Cluster --> SvcB["Service B"]
    SvcA --> T1["Task (실행 인스턴스)"]
    SvcA --> T2["Task"]
    SvcB --> T3["Task"]
    T1 --> C1["Container 1<br/>(nginx)"]
    T1 --> C2["Container 2<br/>(sidecar)"]
객체역할K8s 비교
Cluster논리 그룹 (EC2 / Fargate 혼합 가능)Cluster
Task Definition컨테이너 스펙 (버전 관리됨)Pod spec (manifiest)
Task실행 중인 Task Definition 인스턴스Pod
Servicedesired count 유지, LB 통합, 롤링 배포Deployment

Task Definition 상세

{
  "family": "web",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "arn:aws:iam::123:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::123:role/ecsTaskRole",
  "containerDefinitions": [
    {
      "name": "web",
      "image": "123.dkr.ecr.us-east-1.amazonaws.com/web:latest",
      "portMappings": [{ "containerPort": 8080, "protocol": "tcp" }],
      "environment": [
        { "name": "APP_ENV", "value": "production" }
      ],
      "secrets": [
        { "name": "DB_PASSWORD", "valueFrom": "arn:aws:secretsmanager:us-east-1:123:secret:prod/db" }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/web",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "healthCheck": {
        "command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
        "interval": 30,
        "timeout": 5,
        "retries": 3
      }
    }
  ]
}

IAM Role 두 가지 구분:

  • executionRoleArn: ECS agent 가 ECR 이미지 pull, CloudWatch 로그 쓰기에 사용
  • taskRoleArn: 컨테이너 내 앱이 AWS 서비스 (DynamoDB, S3 등) 접근에 사용

Fargate vs EC2 Launch Type

항목EC2 Launch TypeFargate
노드 관리사용자 직접 관리AWS 관리
운영 부담패치, 스케일링, AMI없음
가격 모델EC2 인스턴스 시간Task vCPU + Memory 시간
비용 (대규모)저렴 (밀도 최적화)일반적으로 비쌈
GPU 지원가능일부만
호스트 접근SSH 가능불가
시작 속도빠름 (사전 프로비전)약간 느림 (콜드 스타트)
Spot 사용가능Fargate Spot
적합비용 최적화, GPU, 밀도운영 단순화, 변동 워크로드

TIP

소규모 팀 / 운영 부담 최소화 = Fargate. 대규모 / 비용 최적화 = EC2 Launch Type (Bin packing).

Fargate 가격 구조

vCPU 시간: $0.04048/vCPU/시간
Memory:    $0.004445/GB/시간

예: 0.5 vCPU + 1 GB Memory, 720시간/월
  = (0.5 * $0.04048 * 720) + (1 * $0.004445 * 720)
  = $14.57 + $3.20 = ~$17.77/월

Fargate Spot: 70% 할인. 2분 사전 통지 후 중단 가능. Stateless/Batch 에 적합.

Service 설정 (Deployment)

service:
  cluster: prod
  taskDefinition: "web:42"
  desiredCount: 3
  launchType: FARGATE
  networkConfiguration:
    awsvpcConfiguration:
      subnets: [subnet-private-a, subnet-private-b]
      securityGroups: [sg-app]
      assignPublicIp: DISABLED
  loadBalancers:
    - targetGroupArn: "arn:aws:elasticloadbalancing:..."
      containerName: web
      containerPort: 8080
  deploymentConfiguration:
    minimumHealthyPercent: 100    # 롤링 중 최소 가용 비율
    maximumPercent: 200           # 롤링 중 최대 Task 수
  deploymentController:
    type: ECS                     # 기본 (CODE_DEPLOY 로 Blue/Green 가능)

ALB 통합 아키텍처

flowchart LR
    Internet["인터넷"] --> ALB["ALB<br/>(443/80)"]
    ALB -->|"Target Group"| Task1["Task (AZ-a)"]
    ALB -->|"Target Group"| Task2["Task (AZ-b)"]
    ALB -->|"Target Group"| Task3["Task (AZ-a)"]
    Task1 --> RDS["RDS Aurora"]
    Task2 --> RDS
    Task3 --> RDS
    Task1 -.-> SM["Secrets Manager"]
    Task2 -.-> SM
  • ALB 가 Task IP 를 직접 Target 으로 등록 (awsvpc network mode)
  • Service 가 새 Task 등록 / 구 Task 드레이닝 자동 처리
  • Draining 기간: 기본 300초 (graceful shutdown)

Service Auto Scaling

# Target Tracking (권장)
aws application-autoscaling register-scalable-target \
  --service-namespace ecs \
  --resource-id "service/prod/web" \
  --scalable-dimension ecs:service:DesiredCount \
  --min-capacity 2 \
  --max-capacity 20

aws application-autoscaling put-scaling-policy \
  --policy-name "cpu-tracking" \
  --service-namespace ecs \
  --resource-id "service/prod/web" \
  --scalable-dimension ecs:service:DesiredCount \
  --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration '{
    "TargetValue": 70.0,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
    },
    "ScaleInCooldown": 300,
    "ScaleOutCooldown": 30
  }'
스케일링 타입특성사용 케이스
Target Tracking목표값 유지 자동기본 선택 (CPU 70% 유지)
Step Scaling지표 임계값별 단계정밀 제어 필요 시
Scheduled시간표 기반예측 가능한 트래픽 패턴

ECR 연동

# ECR 로그인
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin 123.dkr.ecr.us-east-1.amazonaws.com

# 이미지 빌드 + 푸시
docker build -t web:latest .
docker tag web:latest 123.dkr.ecr.us-east-1.amazonaws.com/web:latest
docker push 123.dkr.ecr.us-east-1.amazonaws.com/web:latest

# 새 Task Definition revision 으로 서비스 업데이트
aws ecs update-service \
  --cluster prod \
  --service web \
  --task-definition web:43 \
  --force-new-deployment

Blue/Green 배포 (CodeDeploy)

sequenceDiagram
    participant CD as CodeDeploy
    participant ALB
    participant Blue as "Blue (구 버전)"
    participant Green as "Green (신 버전)"

    CD->>Green: "새 Task 시작"
    CD->>ALB: "Test listener (8080) -> Green"
    Note over CD: "스모크 테스트"
    CD->>ALB: "Production listener (443) -> Green"
    CD->>Blue: "드레이닝 후 종료"

deploymentController: type: CODE_DEPLOY 로 ALB 두 Target Group 사용. 롤백 1초.

ECS Anywhere

온프레미스 서버나 Edge 머신을 ECS 클러스터에 등록해 관리.

# ECS Anywhere 에이전트 설치 스크립트 생성
aws ecs create-cluster --cluster-name hybrid-cluster
aws ssm create-activation \
  --default-instance-name "on-prem-node" \
  --iam-role ECSAnywhereInstanceRole \
  --registration-limit 5

ECS vs EKS 선택 기준

항목ECSEKS
학습 곡선낮음높음
AWS 종속성높음낮음
K8s 이식성없음높음
운영 복잡도낮음높음 (Control plane 관리)
Cluster 비용무료$0.10/시간
Ecosystem제한적방대 (Helm, Operator 등)
적합AWS 네이티브, 빠른 시작멀티 클라우드, 표준화, 큰 규모

함정

WARNING

Fargate Spot 중단 대응 미흡: 2분 전 SIGTERM 보내고 중단. 컨테이너가 SIGTERM 처리 안 하면 데이터 손실. Graceful shutdown 구현 필수.

CAUTION

awsvpc 네트워크 모드 ENI 한도: EC2 launch type 시 인스턴스 타입별 ENI 수 제한. c5.large 는 ENI 3개 = Task 3개 상한. 인스턴스 타입 선택 시 ENI 한도 확인.

WARNING

CloudWatch Logs 비용: 모든 컨테이너 로그가 CloudWatch Logs 로. 고트래픽 서비스에서 로그 비용이 컴퓨팅 비용 초과 가능. fluent-bit sidecar + S3/OpenSearch 로 라우팅 권장.

CAUTION

Task Definition secrets 키 오타: secrets 필드에 Secrets Manager ARN 오타 시 Task 시작 실패 (ECS_EXEC 로 디버깅). executionRolesecretsmanager:GetSecretValue 권한 필요.

WARNING

Service 업데이트 후 롤링 지연: minimumHealthyPercent=100 + maximumPercent=200 시 기존 Task 유지 + 새 Task 추가 후 헬스체크 통과하면 구 Task 종료. 헬스체크가 길면 배포 느림.

IMPORTANT

Fargate Task 시작 지연: 첫 Task 시작에 10-30초 소요 (이미지 풀 포함). Auto Scaling 반응 시간 고려, 사전에 여유 Task 유지.

관련 위키

이 글의 용어 (8개)
[AWS] ALB vs NLB: L7 vs L4 로드 밸런서cloud
정의 | | ALB | NLB | (Classic ELB) | |---|---|---|---| | Layer | L7 (HTTP) | L4 (TCP/UDP) | L4 + L7 (…
[AWS] Auto Scaling: EC2 ASG, target tracking, predictivecloud
정의 Auto Scaling Group (ASG) = EC2 instance 자동 증감. desired / min / max + scaling policy. 구조 Scaling …
[AWS] CloudWatch: 메트릭, 로그, 알람cloud
정의 CloudWatch = AWS 의 모니터링 + 로그 + 알람 통합 서비스. 메트릭 수집, 로그 집계, 대시보드, 알람, 이상 감지를 하나의 서비스에서 제공. 사용 상황 | …
[AWS] ECR (Elastic Container Registry)cloud
정의 Amazon Elastic Container Registry (ECR) 는 AWS 가 관리하는 OCI 컨테이너 이미지 및 Helm chart 레지스트리 입니다. Docker…
[AWS] EKS: managed Kubernetescloud
정의 EKS (Elastic Kubernetes Service) = AWS 의 managed K8s control plane. worker node 는 사용자 (또는 Fargat…
[AWS] IAM: User, Role, Policy, STScloud
정의 IAM (Identity and Access Management) = AWS 의 권한 관리 전부. User, Group, Role, Policy 로 구성. "누가 어떤 리소…
[AWS] Secrets Manager + Parameter Storecloud
정의 AWS Secrets Manager = 회전이 필요한 비밀 (DB 패스워드, API key) 을 안전하게 저장/관리하는 서비스. Lambda 기반 자동 회전과 암호화 내장.…
[K8s] Deployment: ReplicaSet, rolling update, rollbackkubernetes
정의 Deployment = stateless 워크로드를 위한 컨트롤러. 내부적으로 ReplicaSet 관리 + rolling update / rollback. 사용 시나리오 |…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기