본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 03. 05:07

축출(Eviction)에서 살아남기: GKE에서 중단에 탄력적인 AI 워크로드 구축 방법

요약

GKE의 Spot VM을 활용하여 AI 워크로드 비용을 절감할 때 발생하는 노드 회수(Eviction) 문제와 대응 방안을 다룹니다. SIGTERM 신호 포착을 통한 우아한 종료와 체크포인트 외부화를 통한 데이터 보존 방법을 설명합니다.

핵심 포인트

  • Spot VM 회수 시 발생하는 SIGTERM 신호를 애플리케이션에서 명시적으로 처리해야 함
  • 유예 기간 내에 메모리 데이터를 디스크로 플러시하고 안전하게 종료하는 로직 구현 필요
  • 컨테이너 소멸에 대비해 모델 가중치 등 체크포인트를 Cloud Storage와 같은 외부 저장소에 저장

당신은 모든 것을 올바르게 수행했습니다. 거대한 모델 학습 작업을 컨테이너화하여 Google Kubernetes Engine (GKE)에 배포했고, 컴퓨팅 비용을 최대 90%까지 절감하기 위해 Spot VM 노드 풀로 영리하게 라우팅했습니다.

38시간 동안 모든 것이 완벽하게 돌아가고 있었습니다. 그때, 우선순위가 높은 온디맨드(On-demand) 고객에게 용량이 필요해지자, Google Cloud가 기반이 되는 Spot VM을 회수했고 당신의 노드는 사라졌습니다.

비용 절감을 위해 선점형 Spot VMs를 사용하든, 희소한 GPU를 대기하기 위해 Dynamic Workload Scheduler (DWS)를 활용하든, 당신은 일시적인(ephemeral) 컴퓨팅 자원 위에서 구축하고 있는 것입니다. 하드웨어는 결국 회수될 것입니다. 예약되지 않은 용량(un-committed capacity)에서 중요한 AI 워크로드를 성공적으로 실행하려면, 애플리케이션 아키텍처는 실패를 당연한 전제로 가정해야 합니다.

다음은 GKE에서 중단 가능한(interruptible) 워크로드를 구축하기 위한 실무 가이드입니다.

1. 경고 포착하기 (Trap the warning)

Google Cloud가 Spot VM을 회수할 때, 즉시 전원 코드를 뽑아버리지는 않습니다. 대신 기반 노드에 전원 종료 사이클을 시작하도록 ACPI 신호를 보냅니다. Kubernetes는 이를 가로채어 실행 중인 컨테이너로 직접 전달되는 SIGTERM 신호로 변환합니다.

당신에게는 해당 SIGTERM과 치명적인 SIGKILL 사이의 유예 기간 (Grace period) (시스템이 아닌 포드의 경우 최대 15초)이 주어집니다.

애플리케이션은 반드시 이 신호를 명시적으로 수신해야 합니다. 신호가 포착되면, 코드는 즉시 새로운 배치를 받는 것을 중단하고, 현재 루프를 완료하며, 메모리 내의 모든 데이터를 디스크로 플러시(flush)한 다음, 0(성공) 상태로 종료해야 합니다.

다음은 Python에서 이 신호를 포착하는 방법에 대한 간단한 예시입니다:

import signal
import sys
import time
...

2. 체크포인트 외부화하기 (Externalize your checkpoints)

컨테이너가 종료되면 로컬 파일 시스템 (local filesystem) 내부의 모든 데이터도 함께 사라집니다. 중단 상황에서 살아남으려면 진행 상황(모델 가중치 (model weights), 옵티마이저 상태 (optimizer states), 에포크 카운터 (epoch counters) 등)을 외부 저장소 위치에 주기적으로 저장해야 합니다.

Google Cloud에서는 이를 위해 Cloud Storage (GCS)를 사용하는 것이 일반적인 해결책입니다.

  • 자주 저장하기: 작업 손실 비용과 저장소 쓰기 오버헤드 사이의 균형을 맞추는 체크포인트 (checkpointing) 간격을 결정하세요. 매 에포크 (epoch)마다 또는 수천 단계 (steps)마다 저장하는 것이 일반적이지만, 이는 필요에 따라 달라질 수 있습니다.
  • 로컬에 유지하기: 지연 시간 (latency)을 최소화하고 데이터 전송 비용 (outbound data transfer fees)을 피하기 위해 GCS 버킷이 GKE 클러스터와 동일한 리전(예: us-central1)에 있는지 확인하세요.
  • 재시작하지 말고 재개하기: 컨테이너의 시작 스크립트 (startup script)가 가장 먼저 해야 할 일은 해당 GCS 버킷을 확인하는 것입니다. 버킷에 체크포인트가 존재한다면, 이를 로드하고 정확히 그 단계부터 재개하세요.

3. 멱등성(Idempotency)을 고려한 설계

"멱등성 (Idempotency)"이란 어떤 작업을 두 번 수행하더라도 한 번 수행했을 때와 동일한 결과를 얻는다는 것을 의미하는 멋진 표현입니다.

이미지를 읽고, 처리한 다음, 결과를 데이터베이스에 쓰는 배치 추론 (batch inference) 작업을 상상해 보세요. 만약 데이터베이스에 기록을 남긴 직후, 하지만 작업을 완료로 표시하기 직전의 수 밀리초(milliseconds) 사이에 포드 (pod)가 선점(preempted)된다면, 다시 스케줄링된 포드는 해당 이미지를 다시 처리할 가능성이 높습니다.

데이터베이스가 새로운 행을 무조건 삽입한다면, 의도치 않은 중복 데이터가 발생하게 됩니다.

멱등성 파이프라인 (idempotent pipeline)을 구축하려면:

  • 고유 식별자(이미지 ID 등)를 기반으로 데이터베이스에서 UPSERT (update or insert) 작업을 사용하세요.
  • 비싼 GPU 사이클을 소모하여 처리하기 전에 해당 레코드가 이미 존재하는지 확인하세요.

4. 배치 처리를 위한 작업 큐 분리 (Decouple work queues for batch processing)

수천 개의 파일에 걸쳐 대규모 배치 처리(Batch processing) 또는 추론(Inference) 작업을 실행하는 경우, 정적인 CSV 목록을 반복하는 단일 구조(Monolithic)의 Python 스크립트를 작성하지 마세요. 만약 5,000번째 행에서 노드가 중단된다면, 어디서부터 다시 시작해야 할지 상태(State)를 관리하는 것은 악몽과 같습니다.

대신, 워크로드(Workload)를 분리(Decouple)하세요:

  1. 작업 게시 (Publish the work): 데이터셋을 개별 메시지로 분할하여 Pub/Sub과 같은 메시지 브로커(Message broker)에 푸시(Push)합니다.
  2. 작업 가져오기 (Pull the work): Spot VM 워커 포드(Worker pods)가 큐(Queue)에서 메시지를 하나씩 또는 작은 청크(Chunk, 예: 한 번에 10개씩) 단위로 가져오도록(Pull) 합니다.
  3. 완료 확인 (Acknowledge completion): 결과가 안전하게 저장된 후에만 Pub/Sub에

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0