[태그:] Spot Instance

  • 스팟 인스턴스(Spot Instance) 100% 활용법: 비정상 종료에도 끄떡없는 구성

    스팟 인스턴스의 양면성과 활용 전략

    AWS 스팟 인스턴스(Spot Instance)는 온디맨드(On-Demand) 가격 대비 최대 90%까지 저렴하게 EC2 컴퓨팅 파워를 활용할 수 있는 강력한 비용 최적화 수단입니다. 그러나 스팟 인스턴스는 AWS의 미사용 자원을 경매 방식으로 할당받기 때문에, 수요가 증가하거나 가격이 상승하면 AWS로부터 2분 경고 후 강제 회수(Preemption)될 수 있다는 근본적인 위험을 안고 있습니다.

    이러한 비정상 종료(Preemption) 위험에도 불구하고 스팟 인스턴스를 활용한다는 것은, 서비스의 내결함성(Fault Tolerance)을 높여 저렴한 자원의 불안정성을 흡수하는 아키텍처를 구축해야 함을 의미합니다. 본 글에서는 스팟 인스턴스를 안정적으로 100% 활용하여 강제 회수에도 끄떡없는 구성을 만드는 실질적인 방법과 Preemption 대응 스크립트 예시를 제시합니다.


    비정상 종료에 대비하는 아키텍처 및 설정 전략

    스팟 인스턴스 활용의 핵심은 ‘작업의 일시적인 중단 및 재시작 가능성’을 전제로 아키텍처를 설계하는 것입니다.

    1. 작업 분산 및 무상태(Stateless) 설계

    스팟 인스턴스에 할당되는 작업은 인스턴스 자체가 다운되어도 다른 인스턴스에서 이어서 처리할 수 있도록 설계되어야 합니다.

    • 작업 분산: 대규모 배치 작업(Batch Job)이나 데이터 처리 작업은 하나의 긴 작업으로 구성하지 않고, 여러 개의 작은 작업 단위로 나누어 병렬 처리합니다. 각 작업은 Amazon SQS(Simple Queue Service)와 같은 메시지 큐에 넣어 관리합니다.
    • 무상태(Stateless) 아키텍처: 애플리케이션 서버 자체에 세션 정보나 데이터를 저장하지 않고, 모든 상태 정보는 Amazon ElastiCache(Redis) 또는 Amazon DynamoDB와 같은 외부의 영구 스토리지에 저장해야 합니다. 인스턴스가 회수되어도 다른 인스턴스가 외부 스토리지에서 상태를 읽어 작업을 재개할 수 있습니다.

    2. 스팟 플릿(Spot Fleet) 및 Auto Scaling Group 활용

    개별 인스턴스 구매 대신 여러 인스턴스 유형을 조합하여 구매함으로써 회수 위험을 최소화해야 합니다.

    • 스팟 플릿(Spot Fleet) 전략: AWS 스팟 플릿 또는 Auto Scaling Group의 ‘혼합 인스턴스 정책’을 사용하여 여러 인스턴스 패밀리(예: C5, M5, R5)와 여러 가용 영역(AZ)을 동시에 지정합니다. 특정 인스턴스 타입의 재고가 부족해 회수되더라도, 플릿이 자동으로 다른 저렴하고 가용성 높은 타입으로 대체하여 할당받을 수 있게 됩니다.
    • 용량 최적화 할당 전략: 스팟 플릿 구매 시 용량 최적화(Capacity Optimized) 할당 전략을 선택합니다. 이는 AWS가 회수 가능성이 가장 낮은 풀에서 인스턴스를 선택하도록 하여 Preemption 위험을 낮춥니다.

    3. 작업 검문소(Checkpointing) 및 영구 스토리지 활용

    회수 전에 작업을 저장하여 데이터 손실을 방지해야 합니다.

    • 작업 검문소(Checkpointing): 장시간 걸리는 배치 작업의 경우, 일정 시간 간격 또는 특정 처리 단위마다 중간 결과를 S3와 같은 영구 스토리지에 저장(Checkpointing)합니다. 인스턴스가 회수된 후, 새로운 인스턴스가 작업을 재개할 때 마지막 검문소부터 시작하여 작업 시간을 최소화할 수 있습니다.
    • EBS 분리 방지: 스팟 인스턴스가 회수될 때 EBS 볼륨이 자동으로 삭제되지 않도록 설정을 비활성화합니다. 데이터는 보존되므로, 새 스팟 인스턴스에서 해당 볼륨을 재연결하여 복구 시간을 단축할 수 있습니다.

    4. Preemption 대응 스크립트: 2분 회수 경고 활용

    AWS는 스팟 인스턴스를 회수하기 2분 전에 인스턴스 메타데이터를 통해 경고를 보냅니다. 이 2분 동안 스크립트를 실행하여 작업을 안전하게 마무리하는 것이 핵심입니다.

    대응 메커니즘: 인스턴스 메타데이터 서비스(IMDS) 활용

    인스턴스 내부에서 실행되는 데몬이나 스크립트는 주기적으로 인스턴스의 메타데이터 엔드포인트를 호출하여 스팟 인스턴스 회수 통지(Termination Notice)가 있는지 확인해야 합니다.

    정보 유형메타데이터 엔드포인트반환 값
    회수 통지http://169.254.169.254/latest/meta-data/spot/instance-actionJSON 객체(종료 시간 포함) 또는 404 Not Found

    Preemption 대응 스크립트 예제 (Bash / Python)

    다음은 Bash 스크립트를 사용하여 5초마다 회수 통지를 확인하고, 통지 수신 시 안전 종료(Graceful Shutdown) 절차를 시작하는 간소화된 예시입니다.

    Bash

    #!/bin/bash
    # AWS 스팟 인스턴스 회수 대응 스크립트 예시
    
    # 회수 통지 메타데이터 엔드포인트
    SPOT_URL="http://169.254.169.254/latest/meta-data/spot/instance-action"
    
    # 5초 간격으로 회수 통지 확인 루프
    while true; do
        # curl을 사용하여 메타데이터 서비스에 접속
        HTTP_CODE=$(curl -s -w "%{http_code}" $SPOT_URL -o /tmp/spot_response)
    
        if [ "$HTTP_CODE" -eq 200 ]; then
            echo "경고: 스팟 인스턴스 회수 통지 수신!"
            ACTION=$(cat /tmp/spot_response | jq -r '.action')
            TIME=$(cat /tmp/spot_response | jq -r '.time')
            echo "예정된 작업: $ACTION, 예정 시간: $TIME"
            
            # --- [1단계: 핵심 작업 저장 (Graceful Shutdown)] ---
            echo "현재 진행 중인 작업 저장 및 큐에 재등록 시작..."
            # 예: 현재 처리 중인 메시지 SQS로 다시 보내기
            # /usr/local/bin/save_current_task.sh
            
            # --- [2단계: 트래픽 차단] ---
            # 로드 밸런서에서 인스턴스를 제거 (Target Group에서 De-register)
            # aws elbv2 deregister-targets --target-group-arn arn:aws:elasticloadbalancing:... --targets Id=i-xxxxxx
            
            # --- [3단계: 최종 정리 및 종료 대기] ---
            echo "안전 종료(Shutdown) 완료. 2분 대기 후 시스템 종료."
            sleep 120 
            exit 0 # 스크립트 종료, 인스턴스는 AWS에 의해 종료됨
            
        else
            # 404 응답 (회수 통지 없음)
            # echo "정상 작동 중. 5초 후 재확인."
            sleep 5
        fi
    done
    

    스크립트의 역할:

    1. 통지 확인: 5초마다 메타데이터 서비스에 접근하여 200 OK 응답이 오는지 확인합니다.
    2. 작업 저장: 200 OK 수신 즉시, 인스턴스 내에서 실행 중이던 배치 작업의 상태를 저장하고, 처리 중이던 메시지는 SQS 큐 등으로 되돌려 놓아 다른 스팟 인스턴스가 작업을 이어서 처리할 수 있도록 합니다.
    3. 트래픽 차단: 로드 밸런서 타겟 그룹에서 인스턴스를 수동으로 제거하여 신규 트래픽 유입을 막습니다.
    4. 안전 종료: 남은 2분 동안 정리 작업을 마무리하고, 인스턴스 종료를 AWS에 맡깁니다.

    결론: 스팟 인스턴스 활용의 성공 공식 — “불안정성을 설계로 정복하라”

    스팟 인스턴스(Spot Instances)최대 90% 비용 절감이라는 강력한 무기를 제공하지만, “언제든 회수된다” 는 불확실성 때문에 “위험한 도박” 으로 오해받습니다. 성공의 핵심은 “회수를 두려워하는 것”이 아니라, “회수를 예측하고 설계에 녹이는 것” 입니다.


    스팟 인스턴스 100% 활용 공식: 4단계 아키텍처 내재화

    단계핵심 원칙구현 예시
    1. 불안정성 인정“모든 스팟은 2분 내 종료된다” 를 기본 전제로 설계Termination Notice API 폴링 필수
    2. 무상태 설계인스턴스 내부에 상태 저장 금지세션 → ElastiCache, 파일 → S3
    3. 외부 상태 관리작업 큐 + 체크포인팅SQS → 작업 재시도, DynamoDB → 진행률 저장
    4. 다중 인스턴스 타입Spot Fleet / EKS Node Group 으로 회수 리스크 분산c5.large, m5.large, r5.large 혼합

    결정적 승부처: 2분 경고 → Graceful Shutdown

    bash

    # /opt/spot-termination-handler.sh
    #!/bin/bash
    while true; do
      if curl -s http://169.254.169.254/latest/meta-data/spot/instance-action | grep -q "terminate"; then
        echo "스팟 종료 2분 전 감지!"
        
        # 1. 현재 작업 완료 또는 SQS로 재전송
        ./checkpoint.sh
        
        # 2. ALB에서 드레인 (60초 대기)
        aws elbv2 deregister-targets --target-group-arn $TG_ARN --targets Id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
        
        # 3. CloudWatch 이벤트 기록
        aws cloudwatch put-metric-data --namespace Spot --metric-name GracefulShutdown --value 1
        
        exit 0
      fi
      sleep 5
    done

    “갑작스러운 종료” → “계획된 종료” 서비스 중단 0초, 비용 절감 85%


    스팟 인스턴스 성공 방정식

    text

    성공 = (무상태 + 외부 큐 + 다중 타입) × Graceful Shutdown
    실패 패턴성공 패턴
    상태를 로컬 디스크에 저장상태 → S3 / DynamoDB
    단일 인스턴스 타입Spot Fleet (10+ 타입)
    종료 시 무시2분 경고 → 드레인 + 체크포인트
    수동 대응Lambda + EventBridge 자동화

    최종 메시지

    스팟 인스턴스는 “위험”이 아니라 “기회”입니다. 불안정성은 회피하는 것이 아니라, 설계로 정복하는 것.

    **Graceful Shutdown 한 줄이, 월간 수천만 원을 지키고, 아키텍처 한 번의 재설계가, 영구적인 비용 혁신을 가져옵니다.


    오늘의 스팟 설계는 내일의 수익입니다. “회수된다”는 사실을 받아들이는 순간, 진정한 비용 최적화가 시작됩니다.

    스팟 인스턴스는 도박이 아닙니다. 그것은 엔지니어링으로 정복된 절감의 예술입니다.


    Disclaimer: 본 블로그의 정보는 개인의 단순 참고 및 기록용으로 작성된 것이며, 개인적인 조사와 생각을 담은 내용이기에 오류가 있거나 편향된 내용이 있을 수 있습니다.