이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • 배포 실패가 발생했을 때 어떤 순서로 확인해야 하는가?
  • Rollback 전에 반드시 확인해야 할 조건은 무엇인가?
  • 배포 실패 Runbook에는 어떤 증거와 중단 조건이 들어가야 하는가?

목적

이 Runbook은 배포 직후 장애가 발생했을 때 영향을 줄이고 원인을 좁히기 위한 실행 순서다.

목표는 빠르게 새 배포를 밀어붙이는 것이 아니다.

사용자 영향을 제한하고, 새 버전과 이전 버전의 호환성을 확인하고, 안전한 되돌림 또는 우회를 결정하는 것이다.

Spring 백엔드 배포에서는 artifact, profile, 환경 변수, DB migration, readiness, 외부 의존성이 함께 실패할 수 있다.

적용 조건

다음 중 하나라도 해당하면 이 Runbook을 연다.

  • 배포 직후 5xx, timeout, 핵심 API 실패가 증가한다.
  • 새 버전 Pod 또는 프로세스가 준비 상태가 되지 않는다.
  • smoke test가 실패한다.
  • 새 설정 적용 후 DB, cache, 외부 API 연결이 실패한다.
  • migration 이후 이전 버전 또는 새 버전이 시작하지 못한다.
  • 특정 instance만 새 버전으로 바뀐 뒤 오류가 증가한다.

사용자 영향이 없고 배포 pipeline 내부 실패라면 먼저 build/deploy 로그를 확인한다.

첫 5분

  1. 배포 중단 버튼이 있다면 추가 배포를 멈춘다.
  2. 장애 채널에 배포 실패 Runbook 시작을 알린다.
  3. 배포 시작 시각, artifact version, commit, 환경을 기록한다.
  4. 사용자 영향 기능과 대표 오류를 한 문장으로 적는다.
  5. 현재 새 버전과 이전 버전이 각각 얼마나 트래픽을 받고 있는지 확인한다.
  6. 데이터 변경 또는 migration 실행 여부를 확인한다.
  7. Rollback 가능 여부를 임시 판단한다.

이 단계에서 원인을 단정하지 않는다.

데이터 변경 여부를 모르면 Rollback을 즉시 실행하지 않는다.

확인 순서

1. 새 버전 준비 상태

확인할 것:

  • 새 process 또는 Pod가 정상 기동했는가?
  • readiness 또는 상태 endpoint가 통과하는가?
  • port와 profile이 기대값인가?
  • 환경 변수가 누락되지 않았는가?

예시 명령:

systemctl status order-api
journalctl -u order-api -n 100 --no-pager
kubectl rollout status deploy/order-api
kubectl get pod -l app=order-api

기대 결과는 “프로세스가 살아 있다”가 아니라 “요청을 받을 준비가 되어 있다”이다.

2. 핵심 API smoke test

확인할 것:

  • 로그인, 주문 생성, 조회 같은 핵심 API가 성공하는가?
  • 이전 버전과 새 버전의 응답 차이가 있는가?
  • 특정 endpoint만 실패하는가?

예시:

curl -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://api.example.com/orders/health
curl -sS -H "X-Request-Id: deploy-check-001" https://api.example.com/orders/test

smoke test는 읽기 요청과 쓰기 요청을 구분한다.

운영 데이터에 영향을 주는 쓰기 테스트는 사전에 정해진 테스트 계정과 rollback 방법이 있어야 한다.

3. Migration과 데이터 호환성

확인할 것:

  • migration이 실행되었는가?
  • 이전 버전이 새 schema와 호환되는가?
  • 새 버전이 예전 데이터 상태를 읽을 수 있는가?
  • destructive change가 포함되었는가?

예시:

./gradlew flywayInfo -Penv=prod

Migration이 이미 데이터 구조를 바꿨다면 애플리케이션 Rollback만으로 해결되지 않을 수 있다.

이때는 forward fix, feature flag, 읽기 전용 전환을 함께 검토한다.

분기 조건

  • 새 버전만 실패하고 데이터 변경이 없다.
    • 이전 artifact로 Rollback한다.
  • 새 버전만 실패하지만 migration이 이미 실행됐다.
    • 이전 버전 호환성을 확인하고, 불확실하면 feature flag나 forward fix를 우선 검토한다.
  • 모든 버전이 실패한다.
    • 배포 외부 원인, 공통 설정, DB, 외부 의존성을 확인한다.
  • 특정 instance만 실패한다.
    • 해당 instance를 트래픽에서 제외하고 로그와 환경을 비교한다.
  • smoke test는 성공하지만 사용자 오류가 증가한다.
    • 특정 사용자군, 데이터 상태, endpoint별 지표를 확인한다.

안전한 완화 조치

  • 새 배포를 멈추고 현재 traffic split을 고정한다.
  • 문제 instance 또는 target만 트래픽에서 제외한다.
  • feature flag로 새 기능을 끈다.
  • 읽기 기능만 유지하고 쓰기 기능을 제한한다.
  • 이전 artifact로 Rollback한다.
  • migration 영향이 있으면 forward fix 또는 보정 배치를 검토한다.

완화 조치마다 기대 신호를 적는다.

예를 들어 “새 기능 flag off 후 주문 생성 5xx가 5분 안에 1% 미만으로 내려가야 한다”처럼 쓴다.

하지 말아야 할 대응

  • 실패한 배포를 새 배포로 덮어쓰지 않는다.
  • migration 실행 여부를 모른 채 Rollback하지 않는다.
  • 오류 로그를 확인하기 전에 문제 instance를 삭제하지 않는다.
  • 환경 변수를 임시로 바꾼 뒤 기록 없이 방치하지 않는다.
  • 배포 pipeline 성공만 보고 서비스 정상이라고 판단하지 않는다.

인프라 담당자와 공유할 자료

  • 서비스명, 환경, 배포 버전, commit, artifact
  • 배포 시작/종료 시각과 오류 시작 시각
  • 실패한 endpoint와 사용자 영향
  • 새 버전/이전 버전 traffic 비율
  • readiness, smoke test, 로그 샘플
  • migration 실행 여부와 적용 버전
  • 이미 실행한 완화 조치와 결과

종료 조건

Runbook을 종료하려면 다음이 확인되어야 한다.

  • 핵심 API 성공률이 기준 이상으로 회복됐다.
  • error rate와 응답 시간이 안정화 관찰 시간 동안 정상 범위다.
  • 새 배포가 중단되었거나 안전하게 되돌려졌다.
  • 데이터 변경이 있었다면 추가 보정 필요 여부를 확인했다.
  • 장애 채널에 최종 상태와 남은 follow-up을 남겼다.

확인 질문

확인 질문

  • 배포 실패에서 Rollback 전에 반드시 확인할 것은 무엇인가?
    • 데이터 변경이나 migration이 이미 실행되었는지 확인해야 한다.
  • 새 버전만 실패하는지 모든 버전이 실패하는지 나눠야 하는 이유는 무엇인가?
    • 전자는 배포 문제일 가능성이 크고, 후자는 공통 의존성이나 설정 문제일 가능성이 크기 때문이다.
  • Runbook 종료 조건에는 무엇이 있어야 하는가?
    • 사용자 영향 회복, 안정화 관찰, 데이터 후속 확인, 최종 공유가 있어야 한다.