EC2 스팟 인스턴스 중단으로 인한 배포 실패 패턴과 대응 가이드
문제 정의 — 스팟 인스턴스 중단이 배포에 미치는 영향
스팟 인스턴스의 갑작스러운 중단은 배포 과정에 여러 문제를 유발합니다. 전형적인 영향은 롤아웃 중단, 서비스 가용성 저하, 상태 일관성 붕괴로 정리할 수 있습니다. 이 글은 특히 EC2 스팟 인스턴스 중단으로 인한 배포 실패 패턴을 중심으로 문제를 정리합니다. 실무 체크리스트 예: 레디니스·라이브니스 프로브와 재시작 정책 점검, 세션·캐시의 외부화, 로컬 볼륨 백업·복구 절차 확인.
- 롤아웃 중단: 노드 손실로 Deployment·DaemonSet·StatefulSet이 목표 복제 수를 유지하지 못하면 캔리·블루그린 배포가 일부만 적용되거나 배포가 중단되고 자동 롤백이 발생할 수 있다.
- 가용성 저하: 노드 감소는 처리 용량을 낮춰 응답 지연과 5xx 오류, 타임아웃 증가로 이어진다. 동시에 서비스 디스커버리 플랩과 오토스케일링의 과도한 반응을 촉발할 수 있다.
- 상태 일관성 문제: 리더 선출·세션·캐시·로컬 볼륨에 저장된 임시 상태가 손실되면 중복 처리나 데이터 불일치, 트랜잭션 실패가 발생한다. 쿠버네티스가 이를 보정하려 재스케줄링을 반복하면서 컨트롤플레인의 조정이 잦아진다.
스팟 인스턴스 동작 특성 — 중단 신호와 시간적 제약
스팟 인스턴스는 비용 효율적이지만 운영상 몇 가지 중요한 제약을 가집니다. 가장 대표적인 것은 중단 통지입니다. AWS는 일반적으로 인스턴스 종료 약 2분 전에 IMDS의 instance-action 엔드포인트로 알림을 전송합니다. 이 짧은 시간 창은 파드 드레인이나 재스케줄링, 롤링 업데이트 완료, 긴 이미지 풀링 같은 작업을 마치기에 부족할 수 있습니다. 따라서 EC2 스팟 인스턴스 중단으로 인한 배포 실패 패턴을 고려해 대비책을 마련해야 합니다.
- 용량 변동성: 가용성은 AZ, 인스턴스 유형, 시간대에 따라 크게 달라집니다. 특정 스팟 풀에서 중단이 잦아질 수 있습니다.
- 리밸런싱 패턴: AWS는 용량 최적화를 위해 동일 계층 내 인스턴스를 재배치하거나 일부를 선제 종료합니다. 이 경우에도 통지 시간은 대체로 2분에 불과합니다.
- 리클레임(회수) 시나리오: 수요 급증 시 특정 스팟 풀이 즉시 회수될 수 있으므로 상태 유지와 데이터 보존 관점의 설계가 필수입니다. 실무 체크리스트 예: 중요 데이터 정기 백업, 애플리케이션의 무상태(stateless) 설계, 재시작·롤백 자동화 마련.
배포 실패 패턴 유형과 원인 분석
EC2 스팟 인스턴스 중단으로 인한 배포 실패 패턴은 배포 과정에서 여러 반복적 장애를 만들어 냅니다. 다음은 대표적인 사례와 그 원인과 대응 방법입니다.
- 부분 롤아웃 실패 — 스팟 노드만 교체되며 트래픽 분산이 불균형해 새 버전이 일부만 적용되는 현상입니다. 주된 원인은 롤링 전략이 스팟과 온디맨드를 구분하지 못하는 것입니다. 대응으로는 배포 그룹별 태그 적용, 단계적 트래픽 셰이핑, 그리고 헬스체크를 강화하는 방법을 권장합니다.
- 리더 손실로 인한 장애 — 분산 시스템에서 리더가 스팟인 경우 중단 시 리더 재선출이 지연되어 장애가 확대됩니다. 원인은 리더 의존도가 높거나 세션 타임아웃이 과도하게 긴 경우입니다. 해결책은 리더를 온디맨드로 고정하거나, 타임아웃을 짧게 하고 빠른 재선출 정책을 적용하는 것입니다.
- 상태 유지 서비스의 데이터 불일치 — 캐시나 로컬 디스크에 의존하면 스팟 종료로 비정상 종료가 발생해 동기화가 깨질 수 있습니다. 원인은 레플리카 부족과 영속화 전략의 부재입니다. 권장 대응은 외부 영속 스토리지 사용, 동기적 쓰기 적용, 그리고 레플리카 수 보강입니다.
- 오토스케일 스래시 — 스팟 변동으로 빈번한 스케일 인/아웃이 발생하며 배포가 연쇄적으로 실패할 수 있습니다. 원인은 스케일 정책이 너무 민감하게 설정된 탓입니다. 대응으로는 스케일 버퍼 유지, 안정화 기간 설정, 혼합 인스턴스·용량 전략 적용 등이 효과적입니다. 실무 체크리스트: 최소 용량(buffer) 확보, 안정화 타임아웃 설정, 핵심 역할(예: 리더)은 온디맨드로 고정하는 지침을 우선 수립하세요.
관찰성으로 빠르게 감지하는 법
스팟 인스턴스가 중단될 때는 여러 신호를 조합해 초기에 포착해야 합니다. 아래 항목을 기준으로 알림을 설계하면 빠르게 대응할 수 있습니다.
- CloudWatch / EventBridge : EventBridge 룰로 "EC2 Spot Instance Interruption Warning" (instance-action) 이벤트를 캡처해 SNS/Lambda/PagerDuty로 전달하세요.
- ASG / EC2 상태 : Auto Scaling의 정상 인스턴스 수와 EC2 Status Check 실패를 CloudWatch Alarm으로 모니터링해 이상 징후를 조기에 감지합니다.
- 노드 종료 공지 : 인스턴스 메타데이터의 termination-time을 폴링하거나 IMDS 알림을 사용하고, ASG Lifecycle Hook으로 종료 전 처리를 트리거하세요.
- 배포 로그·트레이스 : 배포 시스템(CodeDeploy/ArgoCD/CI)의 실패율·타임아웃과 분산 트레이스의 에러 급증을 연동해 관련 인스턴스 ID로 상관관계를 분석합니다.
권장 설정: EventBridge → SNS/SQS → 자동 롤백/재시도 흐름을 구성하고, Prometheus/Grafana의 kube_node_status_condition 및 배포 실패 알람을 병행해 교차 검증하세요. 이런 구성은 EC2 스팟 인스턴스 중단으로 인한 배포 실패 패턴을 빠르게 식별하는 데 도움이 됩니다. 실무 체크리스트 예: 1) EventBridge 룰 등록 여부 확인, 2) SNS/SQS로 알림 전달 테스트, 3) ASG 헬스 및 termination-time 모니터링 점검, 4) 배포 로그에서 인스턴스 ID 연동 검증.
즉각적인 완화책과 인프라 설계 패턴
온디맨드 폴백: 스팟 종료 알림(예: 2분 인터럽트)을 수신하면 즉시 온디맨드 인스턴스를 기동하거나 ASG의 온디맨드 비중을 자동으로 높여 임시 용량을 확보합니다. 특히 EC2 스팟 인스턴스 중단으로 인한 배포 실패 패턴을 염두에 두고 설계하면 영향 범위를 줄일 수 있습니다. mixed/spot fleet: 다양한 인스턴스 타입과 가용 영역(AZ)에 걸쳐 용량을 분산하고 capacity‑optimized 정책을 적용해 재기동 시간을 최소화합니다.
- 용량 버퍼: 평상시 목표 용량의 10~30%를 여유로 확보하거나 Warm Pool을 활용해 빠르게 대체할 수 있도록 합니다.
- lifecycle hook·drain 자동화: ASG lifecycle hook, Lambda/SSM, k8s node‑termination‑handler를 연계해 종료 시 ELB 등록 해제 → 그레이스풀 드레인 → 상태 보고 후 안전하게 종료되도록 파이프라인화합니다.
- 운영보완: 인터럽트 지표로 자동 트리거를 설정하고, 배포 동시성을 제한하며 헬스 체크 기반 롤백으로 실패 전파를 차단합니다. 실무 체크리스트 예: 인터럽트 알림 확인 → 자동 스케일 정책 검증 → 최대 동시 배포 수 설정 → 헬스 체크 기준 테스트.
배포 파이프라인·애플리케이션 측면의 근본적 개선
스팟 인스턴스 중단을 가정해 파이프라인과 애플리케이션을 설계하면 배포 실패를 근본적으로 줄일 수 있다. 특히 EC2 스팟 인스턴스 중단으로 인한 배포 실패 패턴을 완화하는 데 효과적이다. 주요 개선 항목과 실무 체크리스트 예: 멱등성 키 적용 여부, 재시도 정책, 상태 외부화, 자동 드레인·백업 구성 확인.
- 멱등성·재시도 설계 — 모든 배포·업데이트 작업에 멱등성 키를 적용하고, 중복 처리 방지 로직을 둔다. 지수 백오프 기반 재시도와 데드레터 큐도 함께 구성한다.
- 점진적 배포(카나리/블루그린) — 트래픽 분할과 헬스 기반 게이트를 설정해 소규모로 롤아웃하고, 문제가 생기면 자동으로 롤백한다. 인스턴스 그룹은 배치 단위로 교체한다.
- 상태 분리·외부화 — 세션, 캐시, 파일, 설정 등을 Redis, DynamoDB, S3, Parameter Store로 외부화한다. 로컬 상태를 제거해 인스턴스 교체 시 안전성을 확보한다.
- 런북 자동화 — Runbook as Code(SSM Automation, Rundeck 등)를 도입해 종료 통지 수신 후 드레인, 백업, 알림을 자동으로 수행하고 필요한 경우 인시던트를 자동으로 트리거한다.
경험에서 배운 점
현장에서 흔히 보이는 실패 패턴은 대체로 비슷합니다. 예컨대 배포 중 Spot 인스턴스가 중단 통보(통상 2분)를 받고, 대체 인스턴스가 제때 확보되지 않으면 롤링 업데이트가 멈추거나 파이프라인이 타임아웃됩니다. 이런 유형은 EC2 스팟 인스턴스 중단으로 인한 배포 실패 패턴에서 자주 관찰됩니다.
특정 AZ나 인스턴스 타입에 과도하게 의존하면 ASG가 필요한 용량을 채우지 못해 서비스 가용성이 떨어집니다. 상태 저장(stateful) 구성에서는 쿼럼이나 세션 손실이 장애로 전이되는 경우가 잦습니다. 또한 배포 스크립트나 애플리케이션이 중단 신호(SIGTERM 등)를 제대로 처리하지 못해 작업이 중간에 끊기고 불완전한 배포 상태가 남는 실수도 흔합니다.
- 인스턴스/구매옵션 혼합: ASG나 Spot Fleet에서 여러 인스턴스 타입과 여러 AZ를 조합하고, 온디맨드 비중을 최소 확보해 위험을 분산합니다.
- 할당 전략: Capacity‑optimized, lowest‑price 등 환경에 맞는 할당 정책을 선택합니다.
- 중단 통지 처리: EC2 인스턴스 메타데이터의 Spot interruption notice를 활용해 graceful drain을 구현하고, 워커 종료 전 현재 작업을 취소하거나 재스케줄합니다.
- 배포 전략: 블루/그린 또는 카나리와 최소 헬시 비율(rolling update minHealthy)을 도입해 부분 실패가 전체로 확산되지 않도록 설계합니다.
- 무상태 원칙 준수: 로컬 상태와 세션 의존을 최소화하고 RDB, Redis, S3 같은 외부 저장소를 사용합니다.
- 이미지·시작시간 단축: 사전 빌드 AMI나 컨테이너 이미지 사용, init 스크립트 단순화, Warm Pool/사전 준비 인스턴스 활용으로 시작 시간을 줄입니다.
- 배포 작업 idempotent화 및 짧은 실행 시간: 중간 상태에 의존하지 않도록 설계해 재시도 시에도 안전하게 동작하도록 합니다.
- 타임아웃·재시도 정책: 파이프라인과 헬스체크의 타임아웃을 명시하고, 실패 시 대체 로직을 정의합니다.
- 모니터링·알림: Spot 중단률, ASG 실패율, 대체 지연 같은 지표를 수집하고 자동 경보와 대응 플레이북을 준비합니다.
- 테스트·훈련: 정기적으로 Spot 종료를 시뮬레이션(스케줄 종료 또는 카오스 실험)하고 런북을 검증합니다. 체크리스트: 시뮬레이션 주기, 복구 목표 시간(RTO), 알림 수신자·경로 점검.
- 비상 대체 경로: SLA에 맞춰 온디맨드로 자동 전환하거나 트래픽을 다른 리전·풀로 우회하는 계획을 마련합니다.
댓글
댓글 쓰기