Fargate Spot 인스턴스 무중단 운영 기법






Fargate Spot은 온디맨드 Fargate 대비 최대 70% 저렴하지만, AWS에 여유 용량이 부족해지면 2분 전에 종료 경고(Interruption Notice)를 보낸 뒤 강제로 컨테이너를 회수합니다.

따라서 '무중단(Zero Downtime)'을 구현하려면 (1) 최소 필수 용량은 온디맨드로 방어하고, (2) Spot 컨테이너 회수 시 2분 내에 안전하게 트래픽을 차단하고 새 컨테이너로 교체하는 아키텍처를 설계해야 합니다.

프로덕션 무중산 세팅


  1. Capacity Provider: Base: 2 (FARGATE), Weight: 4 (SPOT) : 1 (FARGATE) 조합

  2. ALB Target Group: Deregistration Delay를 30초로 조정

  3. Task Definition: stopTimeout90초로 설정 + 경량화된 컨테이너 이미지 사용

  4. App Code: SIGTERM 시그널을 잡아 기존 요청 정상 처리 후 종료


◼️ 1. 코드로 실행하기

1. 용량 공급자(Capacity Provider) 전략으로 기본 방어선 구축

모든 컨테이너를 100% Spot으로 띄우면 AWS 리전 전체에 Spot 용량이 고갈되었을 때 서비스 전체가 다운될 수 있습니다. 온디맨드(FARGATE)와 Spot(FARGATE_SPOT)을 혼합 구성합니다.

  • Base(기본 보장 개수): 서비스가 절대 죽지 않도록 최소한의 트래픽을 처리할 태스크(예: 2개)는 무조건 온디맨드로 고정합니다.

  • Weight(가중치 비율): Base를 초과해 오토스케일링되는 추가 트래픽은 Spot과 온디맨드를 4:1 또는 3:1 비율로 할당합니다.

[
  {
    "capacityProvider": "FARGATE",
    "base": 2,
    "weight": 1
  },
  {
    "capacityProvider": "FARGATE_SPOT",
    "base": 0,
    "weight": 4
  }
]

결과: 총 10개의 태스크가 뜰 경우, 2개는 온디맨드 고정 + 나머지 8개 중 약 6~7개는 Spot, 1~2개는 온디맨드로 배정되어 비용을 약 50% 이상 절감하면서 안정성을 확보합니다.

2. 2분 조기 경고 감지 및 우아한 종료(Graceful Shutdown)

AWS는 Fargate Spot을 중단하기 120초 전에 EventBridge로 경고 이벤트를 보내며, 컨테이너 내부 프로세스에 SIGTERM 시그널을 전달합니다.

  • ALB 연결 드레인(Deregistration Delay) 단축

    • ALB 기본 연결 해제 지연 시간은 300초(5분)입니다. 이 값이 2분보다 길면 ALB가 끊어질 컨테이너로 요청을 계속 보내 502 Bad Gateway 에러가 발생합니다.

    • ALB 대상 그룹의 deregistration_delay.timeout_seconds를 30초 ~ 60초로 줄여서 새 요청을 즉시 차단해야 합니다.

  • 애플리케이션의 SIGTERM 핸들링

    • Node.js, Python(FastAPI/Flask) 등 앱 코드에서 SIGTERM을 수신하면:

      1. 신규 HTTP 요청 수신 중단

      2. 현재 처리 중인 요청/DB 트랜잭션 정상 완료 (최대 10~20초 내)

      3. 프로세스 정상 종료(exit 0)

  • ECS Task Definition의 stopTimeout 설정

    • Task Definition에서 컨테이너의 stopTimeout을 90초~110초 정도로 넉넉하게 설정하여, 프로세스가 강제 종료(SIGKILL)되기 전에 안전하게 작업을 마칠 수 있도록 보장합니다.

3. EventBridge 기반 조기 프로비저닝 (Proactive Replacement)

Spot 인스턴스가 꺼질 때까지 기다리지 않고, 경고를 받자마자 즉시 새로운 컨테이너를 띄우는 자동화입니다.

[AWS Spot 회수 결정]
       │
       ▼ (중단 2분 전)
[EventBridge 이벤트 발생] ──> [ECS 클러스터 감지]
                                     │
                                     ├─ 1. 즉시 대체 Task(신규 컨테이너) 기동 시작
                                     └─ 2. 중단 대상 Task는 ALB에서 제거(Drain) 시작

  • ECS는 기본적으로 Fargate Spot 중단 알림을 수신하면 기존 태스크가 완전히 꺼지기 전에 미리 새 태스크 프로비저닝을 시도합니다.

  • 컨테이너 이미지 크기를 경량화(예: Alpine, Distroless 기반 200MB 이하)해 두면 새 태스크가 30~45초 만에 헬스 체크를 통과하므로 2분의 유예 시간 안에 완벽히 교체됩니다.

◼️ 포탈에서 실행하기

AWS 콘솔(웹 포털)에서도 100% 설정 가능하다

Terraform이나 CLI 같은 코드 작업 없이 AWS 웹 콘솔 마우스 클릭만으로 구현하는 단계별 방법이다.

1단계: ECS 서비스 생성 시 Spot 혼합 설정 (Capacity Provider)

  1. ECS 콘솔 > 클러스터 선택 > 서비스 생성(또는 업데이트) 클릭

  2. 배포 구성(Deployment configuration) 섹션으로 이동

  3. 컴퓨팅 옵션에서 용량 공급자 전략(Capacity provider strategy) 선택

  4. 용량 공급자 2개 추가:

    • 첫 번째: FARGATE 선택 / 기본(Base): 2, 가중치(Weight): 1

    • 두 번째: FARGATE_SPOT 선택 / 기본(Base): 0, 가중치(Weight): 4

2단계: ALB 대상 그룹 연결 해제 지연 시간(Drain) 단축

  1. EC2 콘솔 > 좌측 메뉴 하단 대상 그룹(Target Groups) 선택

  2. 사용 중인 ECS 대상 그룹 클릭 > 속성(Attributes) 탭 클릭 > 편집(Edit)

  3. 연결 해제 지연(Deregistration delay) 항목을 기본 300초에서 30초로 변경 후 저장

3단계: 작업 정의(Task Definition)에서 중지 대기 시간 설정

  1. ECS 콘솔 > 작업 정의(Task definitions) > 수정할 작업 정의 선택 > 새 개정판 생성

  2. 컨테이너 편집 클릭 > 환경(Environment) 섹션 확장

  3. 중지 제한 시간(Stop timeout) 항목에 90 (초) 입력 후 저장 및 배포

4단계: 애플리케이션 코드(컨테이너 내부) 처리

  • 포털 설정과 별개로 컨테이너 내부 애플리케이션 코드(Python/Node.js 등)에서 SIGTERM 신호를 받았을 때 에러를 뿜지 않고 기존 처리를 마무리하도록 5~10줄 내외의 핸들러만 넣어두면 끝난다.






* 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.