클라우드 GCP 기반 백엔드 Blue‐Green 배포 자동화 설계 및 구현 문서 - 100-hours-a-week/16-Hot6-wiki GitHub Wiki

GCP 기반 Blue-Green 배포 자동화 설계 및 구현 문서

개요

이 문서는 Google Cloud Platform(GCP)에서 HTTPS Load Balancer와 Managed Instance Group(MIG)을 기반으로 한 무중단 Blue-Green 배포 구조를 구성하고, 이를 GitHub Actions로 자동화한 전 과정에 대한 기록입니다.

단순한 인프라 리소스 생성이 아닌, 실제 운영 서비스의 신뢰성과 배포 안정성 확보를 위한 구체적인 기술적 결정을 문서화한 것입니다.

전체 아키텍처 요약

(이상 생략)
Cloudfront (443)
↓
GCP HTTPS Load Balancer
↓
URL Map → Backend Service → MIG (onthetop-backend-blue / green)
↓
VM (e2-small, Startup Script 통해 Spring Boot 실행)

  • 로드밸런서: GCP HTTPS Global LB
  • Slot 구조: onthetop-backend-blue, onthetop-backend-green 2개의 MIG를 번갈아 사용
  • CI/CD 트리거: GitHub Actions workflow_dispatch
  • 헬스체크: HTTP 기반, /api/v1/health 경로

HTTPS LB 구성 요소

리소스 설명
Global Static IP LB를 위한 고정 IP
Managed SSL Certificate 도메인 인증서 (Route53 도메인 활용)
Certificate Map 여러 인증서를 LB에 연결
Target HTTPS Proxy URL 맵과 인증서를 사용하는 L7 프록시
URL Map 요청 라우팅 룰 정의
Backend Service MIG와 Health Check를 연결
Health Check /api/v1/health 기준 HTTP 200 응답 검사
Forwarding Rule 실제 포트(443)에 트래픽 연결

처음에는 HTTPS 인증서가 LB 생성 화면에 표시되지 않았는데, 이는 Certificate Map이 미설정된 상태였기 때문.

배포 절차 요약 (GitHub Actions)

1. 템플릿 및 MIG 생성

  • 버전명을 기반으로 instance template 명명
  • --network-interface=no-address 옵션으로 public IP 없이 배포
  • tags: http-server, onthetop-server 등 명확히 설정
  • MIG 초기 크기: 1개, initial-delay: 180초

2. Health Check 확인 (MIG 기준)

gcloud compute instance-groups managed list-instances ... \
  --format=json | jq '.instanceHealth[].detailedHealthState'
  • instanceHealth[0].detailedHealthState 기준 HEALTHY 여부 확인

3. Backend Service에 새 MIG 등록

gcloud compute backend-services add-backend ...
  • --named-ports=http:8080 로 포트 명시 필요

4. LB 단 헬스체크 확인

gcloud compute backend-services get-health $SERVICE --global --format=json | \
jq '.[] | select(.backend == MIG_URL) | .status.healthStatus[0].healthState'
  • MIG 자체가 HEALTHY하다고 해서 LB가 트래픽을 넘겨주는 게 아님
  • LB는 backend-service 기준으로 다시 헬스체크 수행 → 이 체크가 완료되기 전에는 실제 트래픽 분배 안 됨

5. 기존 MIG 제거

gcloud compute backend-services remove-backend ...
  • 새 MIG가 HEALTHY한 것이 확인된 뒤, 기존 MIG(blue 또는 green)를 제거

롤백 대응 전략

  • 새 MIG가 HEALTHY하지 못하면:

    • 바로 remove-backend 수행
    • 워크플로우 exit 1로 중단
  • 이전 MIG는 제거하지 않았으므로 자동적으로 rollback 가능

주요 GitHub Actions 구성 요소

slot/버전별 명명 규칙

TEMPLATE_NAME="onthetop-backend-${SLOT}-v${VERSION//./-}"
MIG_NAME="onthetop-backend-${SLOT}"

MIG HEALTH 확인

jq '[.[] | select((.instanceHealth[0].detailedHealthState // "") != "HEALTHY")] | length'

LB HEALTH 확인

jq -r --arg MIG "$MIG_URL" '
  .[] | select(.backend == $MIG) |
  .status.healthStatus[0].healthState // "UNKNOWN"
'

배움 및 주요 포인트 정리

1. MIG 헬스체크와 LB 헬스체크는 다르다

  • MIG는 내부적으로 앱이 살아있는지를 기준으로 판단
  • LB는 Backend Service 기준의 별도 헬스체크를 수행
  • 트래픽 분배 여부는 오직 LB 기준 HEALTH 여부에 따라 결정됨

2. MIG를 먼저 붙이고 HEALTHY 여부를 기다린 후에만 전환

  • 기존 MIG를 먼저 제거하면 순단 발생 가능성 있음
  • 새 MIG를 붙이고 HEALTHY 상태 확인 → 순단 없이 배포 가능

3. GCP HTTPS LB는 구성 요소 간 연결이 복잡함

  • certificate map, proxy, url map, backend-service, forwarding-rule 간 연결 흐름 이해 필수
  • 인증서가 LB UI에서 안 보이는 경우 → certificate-map 확인 필요

4. instanceHealth[]backend[].group의 혼동 주의

  • list-instances는 MIG 자체 상태
  • get-health는 LB 관점 상태

후속 작업 예정

  • FastAPI 및 Frontend에 대해서도 동일한 구조 적용
  • 롤백/확정 전용 워크플로우 구성 (예: Confirm Deployment, Rollback Deployment)
  • 배포 버전별 디스코드 알림

결론

이 문서에서 구현한 배포 전략은 다음과 같은 목적을 완벽하게 충족합니다:

  • 순단 없는 무중단 배포
  • 실패 시 자동 롤백
  • 두 버전 간의 안전한 MIG 전환
  • GCP 인프라의 구조적 이해와 운영 감각 반영

이 구조는 일반적인 Cloud Run, App Engine 수준의 추상화된 환경이 아닌, 실제 VM 기반 배포 자동화를 위한 완성형 접근법입니다.