이 글은 GCP에서 트래픽이 몰릴 때 서버가 자동으로 늘어나지 않는 문제를 겪는 클라우드 학습자를 위한 실습 기록입니다.
문제는 VM을 여러 대 만든다고 해서 트래픽이 자동으로 분산되거나, 부하가 올라간다고 해서 인스턴스 수가 자동으로 증가하지는 않는다는 점입니다.
이 글을 통해 Application Load Balancer와 Managed Instance Group, Autoscaling을 연결해 트래픽 분산과 자동 확장을 동시에 구현하는 방법을 실제 흐름대로 이해할 수 있습니다.
이 글의 핵심 질문
GCP에서 트래픽을 자동으로 분산하고, 부하에 따라 서버를 자동으로 늘리려면 어떻게 구성해야 하는가?
실습 환경
- Cloud: Google Cloud Platform
- 서비스: Compute Engine, Cloud Load Balancing, Managed Instance Group, Cloud NAT
- 네트워크: default VPC
- 리전: Region 1, Region 2, 부하 테스트용 Region 3
- 핵심 구성요소: Health Check, Cloud NAT, Custom Image, Instance Template, MIG, ALB, Autoscaling
아키텍처
이번 실습의 핵심 구조는 하나의 글로벌 진입점으로 들어온 HTTP 요청을 두 개 리전의 백엔드 인스턴스 그룹으로 분산하고, 부하가 커지면 각 인스턴스 그룹이 자동으로 확장되는 형태입니다. 사용자는 하나의 Anycast IP로 접속하지만, 내부적으로는 Global Forwarding Rule, Target Proxy, URL Map, Backend Service를 거쳐 Region 1과 Region 2의 Managed Instance Group으로 요청이 전달됩니다. 백엔드 VM은 외부 IP 없이 Cloud NAT를 통해 아웃바운드만 허용하고, 헬스체크와 방화벽 규칙을 통해 정상 인스턴스만 서비스에 참여합니다.

Users → Anycast IP → Global Forwarding Rule → Target Proxy → URL Map → Backend Service → us-1-mig / notus-1-mig → Autoscaling
전체 흐름
이번 실습은 크게 6단계로 진행됩니다.
- Health Check 방화벽 규칙 생성
- Cloud NAT와 Cloud Router 구성
- 웹서버용 커스텀 이미지 생성
- Instance Template과 두 개의 Managed Instance Group 생성
- 글로벌 외부 Application Load Balancer 구성
- 부하 테스트로 글로벌 분산과 Autoscaling 확인
즉, 이번 글의 핵심은 단순 로드밸런서 생성이 아니라 실제 운영형 구조처럼 “분산 + 확장 + 헬스체크 + 아웃바운드 NAT”를 같이 설계하는 것입니다.
■ 강사 설명
실습 문서는 Google의 Application Load Balancing(HTTP/HTTPS)이 전 세계 POP(Points of Presence) 엣지에서 동작하며, 사용자 요청이 가장 가까운 POP에 진입한 뒤 글로벌 네트워크를 통해 충분한 용량을 가진 가장 가까운 백엔드로 전달된다고 설명합니다. 또한 이번 구성은 두 리전의 백엔드 인스턴스 그룹을 대상으로 트래픽을 분산하고, 부하 테스트를 통해 글로벌 로드밸런싱과 오토스케일링을 직접 확인하는 구조입니다.
■ 내가 이해한 핵심
이번 실습의 본질은 아래 한 줄로 정리됩니다.
Load Balancer는 트래픽을 나누고, Autoscaling은 서버 수를 늘린다
즉, 둘 중 하나만 있어서는 완전한 운영 구조가 아닙니다. 로드밸런서만 있으면 분산은 되지만 부하 증가 시 서버 수는 그대로일 수 있고, 오토스케일링만 있으면 서버는 늘어나도 요청을 안정적으로 나누는 진입 구조가 부족할 수 있습니다.
■ 내가 실제로 겪은 문제
처음에는 같은 이미지를 쓰는 VM을 여러 개 만들면 자동으로 분산될 것이라고 생각하기 쉽습니다. 하지만 실제로는 그렇지 않습니다. 요청을 어떤 기준으로 어느 VM에 보낼지 결정하는 프런트 구조가 없으면 사용자는 특정 서버에만 접속하게 됩니다. 반대로 로드밸런서를 붙여도 Autoscaling 정책이 없으면 서버는 늘어나지 않습니다.
즉, “서버 여러 대”와 “자동 분산 + 자동 확장”은 전혀 다른 문제입니다.
실습 단계
1단계. Health Check 방화벽 규칙 생성
목적: Load Balancer가 백엔드 인스턴스의 정상 여부를 판단할 수 있도록 헬스체크 트래픽을 허용하는 단계입니다.
실습 문서는 헬스체크 프로브가 130.211.0.0/22와 35.191.0.0/16 대역에서 들어오므로, 이 소스 IP 범위와 TCP 80 포트를 허용하는 방화벽 규칙 fw-allow-health-checks를 만들도록 안내합니다. 대상 태그는 allow-health-checks입니다.
이 단계가 중요한 이유는 간단합니다. 방화벽이 헬스체크를 막으면 백엔드가 실제로는 살아 있어도 로드밸런서는 그 서버를 비정상으로 판단합니다. 즉, 방화벽 규칙 하나가 전체 분산 구조를 망가뜨릴 수 있습니다.
2단계. Cloud NAT와 Cloud Router 구성
목적: 외부 IP 없이 동작하는 백엔드 VM이 인터넷으로 나갈 수 있게 만드는 단계입니다.
실습에서는 백엔드 VM에 외부 IP를 붙이지 않습니다. 대신 Region 1에 nat-config라는 Cloud NAT와 nat-router-us1라는 Cloud Router를 만들어, 백엔드 인스턴스가 아웃바운드 인터넷 연결만 가능하게 합니다.
이 설계가 중요한 이유는 보안과 운영 원칙 때문입니다. 백엔드 VM은 외부에서 직접 접근할 수 없고, 오직 로드밸런서를 통해서만 인바운드 요청을 받습니다. 반면 패키지 설치나 업데이트 같은 아웃바운드 연결은 Cloud NAT를 통해 처리됩니다. 즉, “직접 노출은 막고 필요한 통신만 허용”하는 구조입니다.
3단계. 웹서버 커스텀 이미지 생성
목적: 동일한 웹서버 VM을 반복적으로 생성할 수 있는 기준 이미지를 만드는 단계입니다.
먼저 Region 1 / Zone 1에 webserver라는 VM을 만들고, Debian 12(bookworm)를 선택합니다. 이때 네트워크 태그로 allow-health-checks를 넣고, 외부 IPv4 주소는 None으로 설정합니다. 그 다음 SSH로 접속해 Apache2를 설치합니다.
sudo apt-get update
sudo apt-get install -y apache2
sudo service apache2 start
설치 후에는 아래 명령으로 부팅 시 자동 실행되도록 설정합니다.
sudo update-rc.d apache2 enable
실습 문서도 VM을 리셋한 뒤 sudo service apache2 status를 통해 Apache가 자동으로 다시 올라오는지 확인하도록 안내합니다. 이 확인이 중요한 이유는, 이후 커스텀 이미지를 기반으로 새 VM이 생성될 때도 웹서버가 바로 서비스 가능한 상태여야 하기 때문입니다.
이후 부트 디스크 삭제 규칙이 Keep으로 되어 있는지 확인한 뒤 VM 인스턴스를 삭제하고, 남아 있는 디스크를 소스로 사용해 mywebserver라는 커스텀 이미지를 만듭니다. 이 단계가 끝나면 “한 대의 웹서버 설치 작업”이 “반복 가능한 표준 이미지”로 바뀝니다.
4단계. Instance Template과 Health Check 생성
목적: Managed Instance Group이 동일한 서버를 자동 생성할 수 있는 설계도를 만드는 단계입니다.
Compute Engine의 Instance templates에서 mywebserver-template를 생성합니다. 위치는 Global, 머신 타입은 e2-micro, 부트 디스크는 Custom images의 mywebserver를 선택합니다. 네트워크 태그는 역시 allow-health-checks, 외부 IPv4는 None으로 둡니다.
이후 별도로 Health checks 메뉴에서 http-health-check를 생성하고, 프로토콜은 TCP, 포트는 80으로 설정합니다. 실습 문서도 이 헬스체크가 Managed Instance Group의 Autohealing에 사용되며, 비정상 인스턴스를 감지하면 삭제 후 재생성하는 기준이 된다고 설명합니다.
즉, 이 단계의 핵심은 “서버를 많이 만드는 것”이 아니라 서버를 항상 같은 상태로 자동 생성하고, 비정상이면 자동 교체하는 기준을 만드는 것입니다.
5단계. 두 개의 Managed Instance Group 생성과 Autoscaling 연결
목적: 서로 다른 두 리전에 동일한 웹서버 풀을 만들고, 부하 기준으로 자동 확장하게 하는 단계입니다.
첫 번째 인스턴스 그룹은 Region 1의 us-1-mig입니다. 두 번째는 Region 2의 notus-1-mig입니다. 둘 다 Multiple zones로 생성하고, 인스턴스 템플릿은 mywebserver-template를 사용합니다.
Autoscaling은 다음처럼 설정합니다.
- Minimum instances: 1
- Maximum instances: 2
- Signal type: HTTP load balancing utilization
- Target HTTP load balancing utilization: 80
- Initialization period: 60 seconds
Autohealing에는 http-health-check를 붙이고 Initial delay를 60초로 설정합니다. 실습 문서는 이 초기 지연이 너무 길면 실습 확인이 느려지므로 60초로 줄여 두라고 설명합니다.
이 단계에서 중요한 포인트는 Autoscaling 기준이 단순 CPU가 아니라 HTTP load balancing utilization이라는 점입니다. 즉, 실제 LB 기준 부하를 신호로 삼아 확장하므로 웹 트래픽 대응 구조에 더 직접적으로 연결됩니다.
6단계. 글로벌 외부 Application Load Balancer 구성
목적: 하나의 글로벌 진입점으로 들어온 요청을 두 리전의 백엔드 인스턴스 그룹으로 분산하는 단계입니다.
Network Services > Load balancing에서 새 로드밸런서를 생성합니다. 타입은 Application Load Balancer (HTTP/HTTPS), 외부(public facing), 글로벌(best for global workloads), 세대는 Global external Application Load Balancer를 선택합니다. 로드밸런서 이름은 http-lb입니다.
프런트엔드는 두 개를 구성합니다.
- HTTP / IPv4 / Ephemeral / Port 80
- HTTP / IPv6 / Auto-allocate / Port 80
실습 문서는 IPv6 클라이언트 요청도 글로벌 로드밸런싱 계층에서 종료되고, 내부 백엔드로는 IPv4로 프록시된다고 설명합니다.
백엔드 서비스는 http-backend로 만들고, 첫 번째 백엔드로 us-1-mig를 붙입니다. 포트는 80, Balancing mode는 Rate, 최대 RPS는 50입니다. 두 번째 백엔드로 notus-1-mig를 추가하고, Balancing mode는 Utilization, 최대 backend utilization은 80으로 둡니다. 헬스체크는 http-health-check, 로깅은 enable, sample rate는 1로 설정합니다.
이 단계가 중요한 이유는 로드밸런서가 단순히 “서버 여러 대를 붙이는 기능”이 아니라, 어떤 백엔드에 어떤 기준으로 얼마만큼 트래픽을 보낼지를 제어하는 정책 엔진이기 때문입니다.
7단계. 부하 테스트로 글로벌 분산과 Autoscaling 확인
목적: 지금까지 만든 구조가 실제로 트래픽을 분산하고, 필요 시 다른 리전과 추가 인스턴스를 활용하는지 검증하는 단계입니다.
먼저 Load Balancer의 IPv4 주소를 확인한 뒤 Cloud Shell에서 아래 루프로 준비 상태를 확인합니다.
LB_IP=[LB_IP_v4]
while [ -z "$RESULT" ] ;
do
echo "Waiting for Load Balancer";
sleep 5;
RESULT=$(curl -m1 -s $LB_IP | grep Apache);
done
그 다음 Region 3에 stress-test VM을 하나 더 만들고, 커스텀 이미지 mywebserver를 사용해 생성합니다. 실습 문서는 Region 3이 Region 1에 더 가깝기 때문에 초기에는 트래픽이 주로 Region 1의 us-1-mig로 가야 한다고 설명합니다.
SSH 접속 후 Load Balancer IP를 환경 변수로 저장하고, ApacheBench로 부하를 겁니다.
export LB_IP=<LB_IP_v4>
ab -n 50000 -c 200 http://$LB_IP/
실습 문서에 따르면 처음에는 가장 가까운 Region 1 백엔드로만 트래픽이 집중되지만, RPS가 높아지면 Region 2의 notus-1-mig에도 트래픽이 분산됩니다. 또한 Instance Group Monitoring 화면에서 인스턴스 수와 LB capacity가 늘어나는 모습을 확인할 수 있습니다. 즉, 이 단계는 “가까운 곳 우선 + 부하 시 멀티 리전 분산 + 오토스케일링”이 실제로 동작함을 보여주는 검증 단계입니다. :contentReference[oaicite:1]{index=1}
실습 증거
1. 헬스체크 허용 IP 대역
실습 문서는 Application Load Balancer 헬스체크가 130.211.0.0/22와 35.191.0.0/16 대역에서 들어오므로, 이 소스 범위를 TCP 80 포트로 허용해야 한다고 명시합니다. 이는 정상 백엔드 판정의 핵심 조건입니다. :contentReference[oaicite:2]{index=2}
2. 외부 IP 없는 백엔드 + Cloud NAT 구조
문서는 백엔드 VM이 외부 IP 없이 생성되며, 아웃바운드는 Cloud NAT를 통해서만 나가고 인바운드는 로드밸런서를 통해서만 들어오도록 설계한다고 설명합니다. 이는 보안형 백엔드 구조의 직접 증거입니다. :contentReference[oaicite:3]{index=3}
3. Autoscaling 정책
us-1-mig와 notus-1-mig 모두 최소 1, 최대 2 인스턴스이며, 신호는 HTTP load balancing utilization, 목표값은 80, 초기화 시간은 60초로 설정합니다. 이는 단순 정적 서버풀이 아니라 실제 확장 정책이 붙은 구조임을 보여줍니다. :contentReference[oaicite:4]{index=4}
4. 부하 테스트 명령과 동작 확인
실습 문서는 ab -n 50000 -c 200 부하 테스트 후 처음에는 가까운 Region 1으로, 이후 부하가 커지면 Region 2로도 트래픽이 분산된다고 설명합니다. 이는 글로벌 로드밸런싱과 오토스케일링이 실제로 동작하는 검증 증거입니다. :contentReference[oaicite:5]{index=5}
트러블슈팅
문제 증상:
백엔드 인스턴스가 정상인데도 Load Balancer가 트래픽을 보내지 않는다.
원인 분석:
헬스체크 방화벽 규칙이 없거나, 대상 태그가 인스턴스에 붙어 있지 않아서 Health Check가 실패했을 수 있다.
확인 방법:
방화벽 규칙에서 소스 IP가 130.211.0.0/22, 35.191.0.0/16으로 열려 있는지와, VM/템플릿에 allow-health-checks 태그가 있는지 확인한다.
해결 방법:
Health Check 허용 규칙을 만들고, 인스턴스 템플릿과 VM에 올바른 네트워크 태그를 지정한다.
재발 방지 방법:
로드밸런서 구성 전에 “헬스체크 IP 허용 + 태그 지정”을 체크리스트로 고정한다.
문제 증상:
트래픽은 분산되는데 인스턴스 수는 늘어나지 않는다.
원인 분석:
MIG에 Autoscaling 정책이 없거나, Autoscaling signal / target 값이 올바르게 설정되지 않았을 수 있다.
확인 방법:
Instance Group 설정에서 최소/최대 인스턴스 수, Signal type, Target utilization 값을 확인한다.
해결 방법:
Autoscaling을 활성화하고, 실습 문서처럼 HTTP load balancing utilization 기준과 목표값 80을 지정한다.
재발 방지 방법:
분산 구조를 만들 때는 LB 구성과 Autoscaling 정책을 별개로 확인하지 말고 항상 함께 점검한다.
문제 증상:
백엔드 VM이 외부 IP가 없어 패키지 설치나 업데이트가 안 된다.
원인 분석:
Cloud NAT가 구성되지 않았거나 NAT Gateway 상태가 아직 Running이 아닐 수 있다.
확인 방법:
Cloud NAT 화면에서 게이트웨이 상태와 연결된 Cloud Router를 확인한다.
해결 방법:
Cloud Router와 Cloud NAT를 먼저 생성하고, NAT 상태가 Running이 된 뒤 다음 단계를 진행한다.
재발 방지 방법:
외부 IP 없는 백엔드 설계에서는 NAT를 “선택 옵션”이 아니라 필수 전제 조건으로 본다.
실무 핵심 포인트
이번 실습의 가장 중요한 교훈은 아래 한 문장으로 정리됩니다.
안정적인 서비스는 서버 수가 아니라, “분산 구조 + 복구 구조 + 확장 구조”를 함께 설계할 때 만들어진다
즉, Application Load Balancer만 붙인다고 고가용성이 자동으로 끝나는 것이 아닙니다. 백엔드가 외부에 직접 노출되지 않도록 NAT와 방화벽을 설계하고, 비정상 인스턴스를 Health Check와 Autohealing으로 감지하며, 실제 트래픽 증가에는 Autoscaling으로 대응해야 합니다. 이 조합이 있어야 진짜 운영형 구조가 됩니다.
결론
핵심 원칙
GCP에서 트래픽 분산과 자동 확장을 구현하려면 Application Load Balancer, Managed Instance Group, Health Check, Autoscaling을 하나의 구조로 함께 설계해야 한다.
실무 적용 시 주의점
- 헬스체크 IP 대역과 방화벽 규칙을 먼저 정확히 열어야 한다
- 백엔드 VM은 외부 IP 없이 두고 Cloud NAT로 아웃바운드만 허용하는 구조가 더 안전하다
- 커스텀 이미지를 만들어야 동일한 웹서버를 반복 생성할 수 있다
- Load Balancer는 분산을 담당하고, Autoscaling은 확장을 담당한다는 점을 분리해서 이해해야 한다
- 부하 테스트와 모니터링까지 해야 실제 동작 여부를 확인할 수 있다
다음 학습 단계 제안
다음에는 여기에 HTTPS 인증서, Cloud CDN, 경로 기반 라우팅, Blue/Green 배포까지 추가해 더 실무형 아키텍처로 확장해보면 좋습니다.
'서버 구축·실습' 카테고리의 다른 글
| BigQuery에서 날짜 파티션 테이블을 만드는 방법: 쿼리 비용과 성능을 줄이는 실습 가이드 (0) | 2026.03.27 |
|---|---|
| BigQuery에서 JOIN 오류가 발생하는 이유와 해결 방법 (데이터 조인 실습 완전 가이드) (0) | 2026.03.26 |
| BigQuery에서 JSON·ARRAY·STRUCT를 다루는 방법: 중첩 데이터 완전 이해 실습 (0) | 2026.03.26 |
| GCP Vision API로 이미지에서 텍스트 추출하고 번역하는 방법 (OCR 실습 완전 가이드) (0) | 2026.03.25 |
| GCP AutoML로 이미지 분류 모델 만드는 방법 (Cloud Vision API 실습 기반 완전 가이드) (0) | 2026.03.25 |