클라우드 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 확인 필요
instanceHealth[]
와 backend[].group
의 혼동 주의
4. list-instances
는 MIG 자체 상태get-health
는 LB 관점 상태
후속 작업 예정
- FastAPI 및 Frontend에 대해서도 동일한 구조 적용
- 롤백/확정 전용 워크플로우 구성 (예:
Confirm Deployment
,Rollback Deployment
) - 배포 버전별 디스코드 알림
결론
이 문서에서 구현한 배포 전략은 다음과 같은 목적을 완벽하게 충족합니다:
- 순단 없는 무중단 배포
- 실패 시 자동 롤백
- 두 버전 간의 안전한 MIG 전환
- GCP 인프라의 구조적 이해와 운영 감각 반영
이 구조는 일반적인 Cloud Run, App Engine 수준의 추상화된 환경이 아닌, 실제 VM 기반 배포 자동화를 위한 완성형 접근법입니다.