- Published on
GCP VPC 피어링 라우트 안됨? 9가지 체크
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서로 다른 VPC를 피어링했는데도 통신이 안 되면, 대부분은 "피어링 자체"가 아니라 라우트 교환 조건이나 방화벽/경로 설계에서 막힙니다. 특히 GCP VPC Peering은 VPN처럼 임의 라우트를 마음대로 주고받는 구조가 아니라, 서브넷 라우트 교환과 커스텀 라우트 교환 옵션이 명확히 나뉘어 있어 체크 포인트가 정형화되어 있습니다.
이 글은 "피어링 연결 상태는 ACTIVE인데 라우트가 안 보인다", "특정 대역만 안 된다", "프라이빗 IP로는 안 되고 퍼블릭은 된다" 같은 상황에서, 빠르게 원인을 좁히기 위한 9가지 체크리스트를 제공합니다.
빠른 진단 흐름(권장)
- 라우트 테이블에서 피어링 라우트가 생성되었는지 확인
- 라우트가 있다면 방화벽과 대상 인스턴스의 OS/서비스 바인딩 확인
- 특정 대역만 실패하면 export/import custom routes 및 충돌 대역 확인
- GKE/Serverless/PSC 등이면 피어링이 지원하는 경로인지 확인
아래부터는 실무에서 가장 자주 터지는 순서대로 정리합니다.
1) 피어링 상태는 ACTIVE인가(기본이지만 필수)
피어링이 ACTIVE가 아니면 라우트가 생성되지 않습니다. 또한 양쪽 VPC 모두에서 피어링이 정상 상태여야 합니다.
gcloud compute networks peerings list \
--network=VPC_A \
--project=PROJECT_A
gcloud compute networks peerings list \
--network=VPC_B \
--project=PROJECT_B
출력에서 state: ACTIVE를 확인하세요. INACTIVE면 권한/설정 불일치 가능성이 큽니다.
2) 라우트가 실제로 생성되었는지(서브넷 라우트 교환)
GCP VPC Peering은 기본적으로 서브넷 라우트가 교환됩니다. 피어링을 만들었는데도 라우트가 안 보이면, 먼저 라우팅 테이블에서 피어링 라우트를 조회해보세요.
gcloud compute routes list \
--filter="network:VPC_A AND nextHopPeering:*" \
--project=PROJECT_A
여기서 핵심은 다음입니다.
- next hop이 peering으로 잡히는 라우트가 있어야 함
- 라우트
destRange가 기대한 서브넷 CIDR인지 확인
라우트가 없다면 3번, 4번을 최우선으로 확인합니다.
3) 커스텀 라우트 교환 옵션(export/import custom routes) 설정
가장 흔한 오해가 "피어링이면 라우트 다 넘어가겠지"입니다. 하지만 피어링은 기본적으로 서브넷 라우트만 교환합니다.
다음 같은 라우트는 기본 교환 대상이 아닐 수 있습니다.
- Cloud VPN 또는 Cloud Interconnect로 학습된 라우트
- 커스텀 정적 라우트
- 특정 서비스 연결을 위해 만든 라우트
이 경우 피어링 옵션에서 custom routes export/import를 켜야 합니다.
# VPC_A에서 VPC_B로 커스텀 라우트 export
gcloud compute networks peerings update PEERING_A_TO_B \
--network=VPC_A \
--export-custom-routes
# VPC_A가 VPC_B의 커스텀 라우트 import
gcloud compute networks peerings update PEERING_A_TO_B \
--network=VPC_A \
--import-custom-routes
주의: 이 설정은 양방향으로 각각 맞춰야 합니다. 한쪽만 export하고 반대쪽이 import하지 않으면 기대한 라우트가 안 들어옵니다.
4) 라우트 우선순위와 더 구체적인 경로(롱기스트 프리픽스) 충돌
라우트가 "있는데도" 트래픽이 엉뚱한 곳으로 가는 전형적인 케이스는 다음입니다.
- 더 구체적인 CIDR 라우트가 다른 next hop으로 존재
- 동일 CIDR에 대해 **우선순위(priority)**가 더 높은 라우트가 존재
예를 들어 10.10.0.0/16을 피어링으로 보내려는데, 로컬에 10.10.1.0/24가 NAT나 다른 게이트웨이로 잡혀 있으면, 실제 트래픽은 /24로 빠집니다.
gcloud compute routes list \
--filter="network:VPC_A AND destRange:(10.10.0.0/16 OR 10.10.1.0/24)" \
--project=PROJECT_A
해결은 보통 둘 중 하나입니다.
- 충돌 라우트를 제거하거나 더 적절한 next hop으로 수정
- 의도한 대역을 더 구체적으로 분리해 설계
5) 겹치는 CIDR(Overlapping IP range)로 인한 라우팅 불가
피어링은 두 VPC의 CIDR이 겹치면 성립하더라도 통신이 정상적으로 되지 않거나, 애초에 구성이 제한됩니다.
점검 포인트:
- VPC_A 서브넷 CIDR과 VPC_B 서브넷 CIDR이 겹치지 않는가
- 피어링 이후 추가로 만든 서브넷이 상대 CIDR과 겹치지 않는가
gcloud compute networks subnets list --project=PROJECT_A
gcloud compute networks subnets list --project=PROJECT_B
겹침이 있다면 정답은 대부분 "재설계"입니다. 운영 중이면 신규 대역으로 마이그레이션 계획을 잡는 편이 안전합니다.
6) 방화벽 룰: ingress만 보지 말고 egress도 확인
라우트가 잡혀도 방화벽에서 막히면 당연히 통신이 안 됩니다. 특히 GCP는 VPC 방화벽이 stateful이라 해도, 조직 정책이나 egress 제한을 걸어둔 환경에서는 왕복이 끊길 수 있습니다.
필수 확인:
- 대상 VM이 속한 VPC에서 ingress 허용
- 출발 VM이 속한 VPC에서 egress 허용
- 태그/서비스 계정 타깃팅이 맞는지
- 프로토콜과 포트가 맞는지(예: ICMP, TCP 443, TCP 5432)
gcloud compute firewall-rules list --project=PROJECT_A
gcloud compute firewall-rules list --project=PROJECT_B
팁: 테스트를 위해 최소 범위로 임시 룰을 만들 때도 CIDR을 넓게 열기보다, 상대 서브넷 CIDR만 정확히 지정하세요.
7) OS 레벨 문제: 서비스 바인딩과 로컬 방화벽(UFW, iptables)
네트워크 팀이 라우트/방화벽을 다 열어줬는데도 안 되는 경우, 최종 원인은 VM 내부에서 자주 나옵니다.
- 애플리케이션이
127.0.0.1에만 바인딩되어 외부 접속 불가 ufw또는iptables에서 드롭- 리스닝 포트가 다름
# 리스닝 확인
sudo ss -lntp
# 로컬 방화벽 확인(우분투)
sudo ufw status verbose
# iptables 확인
sudo iptables -S
특히 DB나 내부 API는 기본값이 로컬 바인딩인 경우가 많아서, 피어링을 아무리 고쳐도 해결이 안 됩니다.
8) 피어링은 트랜짓(Transit) 라우팅이 아니다
"A와 B를 피어링했고, B와 C도 피어링했으니 A에서 C로 가겠지"는 성립하지 않습니다. VPC Peering은 비전이성(non-transitive) 입니다.
즉 다음은 안 됩니다.
- VPC_A
-peering-VPC_B-peering-VPC_C 경유 통신 - 허브 VPC를 만들어 여러 VPC를 피어링으로 묶고 라우팅 허브로 쓰기
이 요구가 있다면 보통 선택지는 다음입니다.
- Cloud VPN/Interconnect + Cloud Router 설계
- Network Connectivity Center 기반 허브-스포크
- Shared VPC로 프로젝트를 묶는 구조
"라우트가 안 된다"의 본질이 "원래 지원하지 않는 경로"인 경우가 꽤 많습니다.
9) 대상이 GKE/Serverless/PSC면 경로 지원 여부부터 확인
피어링으로 통신시키려는 대상이 단순 VM이 아니라면, 지원 여부가 달라집니다.
- GKE: Pod CIDR, Service CIDR, 네이티브 라우팅/VPC 네이티브 여부에 따라 기대가 달라짐
- Serverless(Cloud Run 등): VPC 커넥터/인그레스 설정과 결합 이슈가 많음
- Private Service Connect, Managed 서비스: 피어링이 아니라 PSC 엔드포인트/프라이빗 IP 접근 패턴을 요구할 수 있음
여기서 실무 팁은 “어느 IP 대역으로 접근하고 있는지”를 먼저 고정하는 것입니다.
- VM
-to-VM: 서브넷 CIDR 간 통신 - VM
-to-GKE Pod: Pod CIDR이 실제 라우팅 대상인지 확인 - VM
-to-서비스: 내부 LB VIP인지, 엔드포인트 IP인지 확인
GKE 네트워킹에서 비슷한 "겉으론 정상인데 실제 연결이 안 됨" 패턴은 쿠버네티스에서도 자주 나오니, 원인 분해 방식은 아래 글도 참고할 만합니다.
실전 점검용: 최소 재현 테스트(핑, TCP)
문제 재현을 단순화하면 원인 좁히기가 빨라집니다.
- ICMP(핑)가 허용되는지
ping -c 3 10.20.0.10
- TCP 포트가 열리는지
# 예: 443
nc -vz 10.20.0.10 443
# 예: 5432(PostgreSQL)
nc -vz 10.20.0.10 5432
- 경로 확인(리눅스)
ip route
# 특정 목적지로 어떤 경로를 타는지
ip route get 10.20.0.10
이때 ip route get 결과가 피어링 경로로 나가야 정상입니다. 로컬에서 다른 게이트웨이로 나가면 4번(충돌) 가능성이 큽니다.
자주 묻는 케이스별 결론
- 피어링은 ACTIVE인데 라우트가 안 보임: 2번, 3번을 먼저
- 라우트는 있는데 통신이 안 됨: 6번, 7번을 먼저
- 특정 대역만 안 됨: 4번, 5번을 먼저
- 허브-스포크처럼 쓰려다 실패: 8번이 정답
마무리: "라우트" 문제는 대부분 설정 3종으로 귀결된다
GCP VPC 피어링에서 라우팅 장애는 결국 아래 3가지로 수렴하는 경우가 많습니다.
- 라우트 교환 범위: 서브넷 라우트 vs 커스텀 라우트(export/import)
- 충돌: 겹치는 CIDR 또는 더 구체적인 라우트
- 차단: VPC 방화벽 또는 OS 방화벽/바인딩
위 9가지를 순서대로 체크하면, "왜 라우트가 안 잡히는지" 또는 "라우트가 잡혀도 왜 안 통하는지"를 보통 30분 내로 특정할 수 있습니다.
추가로, 네트워크 문제는 애플리케이션 레벨에서 재시도/회로차단 같은 복원력 설계가 함께 있으면 장애 체감이 크게 줄어듭니다. 네트워크 단절이 빈번한 환경이라면 아래 글도 같이 보면 도움이 됩니다.