VPC 가 무엇인지 한 번 정리해보고 싶었다. 격리, 라우팅, 연결, 보안 — 네 갈래의 결정이 결국 같은 패킷 한 개 위에서 만나는데, 한 자리에서 보는 편이 분산된 글보다 멘탈 모델 잡기에 좋다고 봤다.
서비스 백엔드를 만지는 개발자 입장에서 실제 마주치는 결정만 추렸다. 네트워크 엔지니어 영역의 디테일(BGP, IPSec 내부, NAT instance vs Gateway 비교 등) 은 들어냈다.
VPC 와 Subnet
클라우드에서 VM 을 생성하면 특정 네트워크에 소속된다. 그 네트워크가 VPC 다. AWS·GCP·Alibaba 는 VPC, Azure 는 VNet 이라고 부르지만 가리키는 추상은 같다. 공용 클라우드 위에 SDN(Software-Defined Networking) 으로 구현한, 자체 사설 IP 공간을 가진 격리된 가상 네트워크다.
같은 물리 인프라에서 여러 고객의 워크로드가 동시에 실행되는 게 클라우드의 기본 구조다. 격리가 없으면 트래픽이 새고 IP 가 충돌한다. VPC 는 각자 자기만의 데이터센터를 가지는 구조에 가깝다.
CIDR
VPC 생성 시 가장 먼저 정하는 값이 CIDR(Classless Inter-Domain Routing) 블록이다. 10.0.0.0/16 같은 사설 IP 대역을 지정하면, 그 범위 안의 주소가 VPC 내부 자원에 할당된다.
RFC 1918 이 정의한 사설 대역(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) 중에서 고르는 게 표준이다. 인터넷에서 라우팅되지 않는 대역이라 외부와 충돌하지 않고, 다른 VPC 와도 같은 대역을 재사용할 수 있다.
다만 향후 다른 VPC 와 연결할 가능성이 있다면 같은 사설 대역끼리도 충돌이 생긴다. 두 VPC 가 모두 10.0.0.0/16 을 쓰고 있으면 Peering 이나 Transit Gateway 로 연결할 때 라우팅이 모호해진다. 처음부터 조직 단위로 IP 대역을 분배해 두는 편이 안전하다.
접두 길이도 한 번 정하면 바꾸기 어렵다. 미래 확장을 고려해 충분한 공간을 잡는다.
Subnet
VPC 단위 IP 공간을 더 작은 블록으로 쪼갠 단위가 Subnet 이다. 보통 가용영역(AZ) 단위로 만든다.
AZ 는 물리적으로 분리된 데이터센터 묶음이라, AZ 별 Subnet 배치가 가용성 보장의 기본이다. 한 AZ 가 장애를 겪어도 다른 AZ 의 Subnet 은 영향을 받지 않는다.
격리 관점에서 Subnet 의 역할은 분리 단위보다는 정책 적용 단위에 가깝다. 라우팅 규칙과 보안 규칙이 Subnet 단위로 걸린다. Public/Private Subnet 이라는 분류도 결국 라우팅 규칙의 결과로 나타나는데, 그 얘기는 다음 섹션이다.
물리 하드웨어 격리까지 가져가는 dedicated tenancy 옵션도 있지만, 백엔드 개발자가 결정할 지점은 거의 없다.
라우팅
VPC 안의 패킷이 어디로 갈지는 Route Table 이 결정한다. VPC 또는 Subnet 에 부착되는 규칙 묶음으로, 각 규칙은 목적지 CIDR 과 다음 홉(target) 을 짝짓는다.
매칭 방식은 longest prefix match. 더 구체적인 CIDR 규칙이 우선한다. 예를 들어 0.0.0.0/0 과 10.0.5.0/24 가 모두 있고 패킷 목적지가 10.0.5.42 면 10.0.5.0/24 규칙이 선택된다.
VPC 생성 시 Local route 가 자동으로 추가된다. VPC 의 CIDR 전체를 가리키는 규칙이라, 같은 VPC 안의 자원끼리는 별도 설정 없이도 통신할 수 있다. Local route 는 삭제할 수 없다.
IGW 와 NAT
외부 인터넷과의 출입은 두 종류의 출입구가 나눠 담당한다.
Internet Gateway(IGW)는 VPC 와 외부 인터넷 사이의 양방향 출입구다. VPC 당 하나 부착할 수 있다. 자원이 외부에서 도달 가능하려면 두 조건이 모두 필요하다. Public IP(또는 Elastic IP) 가 부착되어 있어야 하고, 그 자원이 속한 Subnet 의 Route Table 에 IGW 로 향하는 기본 경로가 있어야 한다. 둘 중 하나만 만족해서는 외부에서 접근할 수 없다.
NAT Gateway(Network Address Translation) 는 outbound 전용 출구다. Private Subnet 의 자원이 외부에 접근하면서도 외부에서 직접 도달하는 일은 막아야 할 때 쓴다. NAT 자체는 Public Subnet 에 두는데, 외부로 트래픽을 내보내려면 결국 IGW 를 거쳐야 하기 때문이다. Private Subnet 의 Route Table 은 기본 경로를 NAT 로 설정하고, NAT 가 그 트래픽을 자신의 Public IP 로 변환해 내보낸다.
외부에서 시작한 연결은 NAT 를 통과하지 못하므로 inbound 차단이 자연스럽게 따라온다. 다만 NAT Gateway 는 시간당 + 트래픽당 과금이 붙어 outbound 가 많은 워크로드에서는 비용 부담이 크다.
Public Subnet 과 Private Subnet 의 실체
백엔드 개발자가 가장 자주 헷갈리는 지점이다.
Public Subnet 과 Private Subnet 은 Subnet 의 속성이 아니다. Route Table 의 기본 경로가 어디로 향하는가 의 결과다.
- Public Subnet: 기본 경로가 IGW 로 향함
- Private Subnet: 기본 경로가 NAT 로 향하거나, 기본 경로 자체가 없음
flowchart LR
subgraph Public ["Public Subnet"]
VM_P["VM (Public IP)"] -.-> RT_P["Route Table
0.0.0.0/0 → IGW"]
end
subgraph Private ["Private Subnet"]
VM_R["VM"] -.-> RT_R["Route Table
0.0.0.0/0 → NAT"]
end
RT_P --> IGW["IGW"]
RT_R --> NAT["NAT Gateway"]
NAT --> IGW
같은 VPC 안의 두 Subnet 이 서로 다른 Route Table 에 묶여 있을 뿐, Subnet 자체에 Public/Private 플래그가 있는 게 아니다.
이 정의를 알고 나면 “Public IP 를 부착했는데 외부에서 접근되지 않는다” 같은 흔한 함정도 자연스럽게 풀린다. 자원이 속한 Subnet 의 Route Table 이 IGW 로 향하는 기본 경로를 갖고 있지 않으면, Public IP 가 있어도 외부에서 도달하지 못한다.
VPC 밖과의 연결
VPC 내부 라우팅이 해결되면 다음 질문은 VPC 밖과의 연결이다. 다른 VPC, 온프레미스 데이터센터, 외부 SaaS 서비스. 각각 다른 메커니즘이 있고, 어느 것을 고르느냐가 토폴로지와 비용을 결정한다.
VPC Peering
가장 단순한 옵션이다. 두 VPC 를 직접 연결해 서로의 사설 IP 공간에 도달할 수 있게 한다. 같은 리전·같은 계정뿐 아니라 다른 리전·다른 계정의 VPC 도 연결 가능하다.
한계는 transitive 라우팅이 지원되지 않는다는 점이다. A-B 와 B-C 를 Peering 으로 연결해도 A 에서 C 로는 직접 갈 수 없다. 양쪽이 직접 Peering 관계여야 한다. VPC 수가 늘면 연결 수가 N(N-1)/2 로 폭증하므로, 소수의 VPC 를 묶을 때만 적합하다.
Transit Gateway
VPC 수가 늘어나면 Peering 의 mesh 구조는 빠르게 부담이 된다. Transit Gateway 는 중앙 허브 역할을 한다. 다수의 VPC 가 spoke 로 연결되고, 허브를 통해 모든 spoke 간 통신이 transitive 하게 이뤄진다. VPC 수가 늘어도 연결 수가 선형으로 증가한다.
flowchart LR
subgraph Peering ["Peering: mesh"]
VA["VPC A"] --- VB["VPC B"]
VB --- VC["VPC C"]
VA --- VC
VC --- VD["VPC D"]
VA --- VD
VB --- VD
end
subgraph Transit ["Transit Gateway: hub-spoke"]
TGW(("TGW"))
TVA["VPC A"] --- TGW
TVB["VPC B"] --- TGW
TVC["VPC C"] --- TGW
TVD["VPC D"] --- TGW
end
비용 모델은 다르다. 시간당 부착 비용 + 트래픽당 처리 비용이 붙어, 작은 규모에서는 Peering 보다 비싸지만 N 이 커질수록 효율이 역전된다.
Site-to-Site VPN
VPC 와 온프레미스 데이터센터를 묶을 때 가장 먼저 떠오르는 옵션이다. 공용 인터넷을 통해 IPSec 터널을 세워 두 네트워크를 논리적으로 연결한다. 정적·동적(BGP) 라우팅 둘 다 제공된다.
다만 공용 인터넷이 매개라 대역폭과 지연이 변동성을 가진다. 안정적 연결이 필요하면 Direct Connect 나 Cloud Interconnect 같은 전용선 옵션이 별도로 있다.
PrivateLink
PrivateLink 는 서비스 단위로 endpoint 를 노출하는 방식이다. 앞의 세 메커니즘처럼 두 네트워크를 IP 단위로 잇지 않는다.
서비스 제공자 VPC 에 endpoint 를 만들면, 소비자 VPC 는 그 endpoint 를 ENI(Elastic Network Interface) 로 자기 VPC 안에서 인식한다. 두 VPC 의 IP 공간이 어떻게 분포해 있든 무관하다. endpoint 단위 연결이라 CIDR 충돌이 문제가 되지 않는다.
방향성도 다르다. PrivateLink 는 단방향이다. 제공자가 노출한 서비스를 소비자가 호출하는 형태고, 반대 방향은 별도 endpoint 를 만들어야 한다. SaaS 의 사적 노출, 클라우드 매니지드 서비스의 VPC 진입점 등에 자주 쓰인다.
비교
| 메커니즘 | 토폴로지 | Transitive | 비용 모델 | 주 사용처 |
|---|---|---|---|---|
| VPC Peering | 1:1 mesh | ❌ | 비교적 저렴 (트래픽당) | 소수 VPC 직접 연결 |
| Transit Gateway | hub-spoke | ✅ | 시간당 + 트래픽당 | 다수 VPC, 라우팅 도메인 분리 |
| Site-to-Site VPN | 사이트 ↔ VPC 터널 | (BGP 사용 시 ✅) | 시간당 + 트래픽당 | 온프레미스 ↔ VPC |
| PrivateLink | 서비스 endpoint | (해당 없음) | endpoint 당 + 트래픽당 | 서비스 단위 노출, CIDR 무관 |
앞 셋이 모두 IP 라우팅 기반이라는 점에서 한 가지 함정이 따라온다. 두 VPC 의 CIDR 가 겹치면 패킷의 행선지가 모호해져 라우팅이 깨진다. 이미 충돌이 발생한 환경이라면 PrivateLink 가 사실상 유일한 우회로다. IP 가 아니라 서비스 endpoint 노출이라 CIDR 가 같아도 통신할 수 있다.
보안
SG 와 NACL 은 같은 방화벽 규칙처럼 보이지만 적용 단위, 평가 방식, 상태성이 다르다. 백엔드 입장에서 자주 만지는 건 SG 쪽이고, NACL 은 Subnet 경계에 인프라/보안 팀이 잡아두는 한 단계로 받아들이는 게 보통이다.
Security Group
Security Group(SG) 은 인스턴스 또는 ENI 단위에 부착되는 규칙 묶음이다. 한 인스턴스에 여러 SG 를 부착할 수 있고, 그 경우 규칙은 합집합으로 적용된다.
가장 큰 특징은 stateful 이라는 점이다. 한 번 허용된 연결의 응답 트래픽은 별도 규칙 없이 자동으로 허용된다. inbound 로 들어온 요청에 대한 응답을 outbound 규칙에 따로 명시할 필요가 없다.
SG 는 allow-only 다. deny 규칙이 없고, 명시적으로 허용한 트래픽만 통과한다. 기본값은 outbound 전체 허용, inbound 전체 차단. 새 SG 를 만들면 우선 외부와의 모든 inbound 가 차단되어 있고, 필요한 포트와 출발지를 하나씩 추가해 가는 모델이다.
SG 의 source/destination 에는 IP CIDR 외에도 다른 SG 의 ID 를 지정할 수 있다. 같은 VPC 안의 자원끼리 “이 SG 가 부착된 자원만 허용” 같은 의미적 규칙을 직접 표현할 수 있어, 인스턴스 IP 가 바뀌어도 규칙이 깨지지 않는다. 백엔드 입장에서 가장 자주 쓰는 기능이다.
NACL
NACL(Network ACL) 은 Subnet 단위에 부착된다. 한 Subnet 에는 하나의 NACL 이 붙고, 그 Subnet 의 모든 자원이 같은 영향을 받는다.
NACL 은 stateless 다. inbound 와 outbound 규칙이 완전히 분리되어 있어, 한쪽에서 허용된 트래픽의 응답이라도 반대쪽에서 명시적으로 허용되지 않으면 차단된다. SG 에서는 자동 허용되던 응답 트래픽이 NACL 에서는 별도 규칙을 요구한다.
NACL 은 allow 와 deny 모두 표현할 수 있다. 명시적으로 차단해야 할 트래픽이 있을 때 NACL 이 필요한 이유다.
stateless 의 함정
NACL 의 outbound 는 허용했는데 응답이 차단된다. SG 만 쓸 때는 stateful 이라 보이지 않다가, NACL 을 추가로 도입한 순간 새로 등장하는 시나리오다.
응답 트래픽은 일반적으로 ephemeral port(1024-65535) 범위로 돌아온다. NACL inbound 규칙에 그 범위가 포함되어 있지 않으면 응답이 차단된다. NACL 을 직접 운영한다면 양방향 ephemeral port 범위를 함께 허용해 두는 게 정석이다.
비교
| 항목 | Security Group | NACL |
|---|---|---|
| 적용 단위 | 인스턴스 / ENI | Subnet |
| 상태성 | stateful (응답 자동 허용) | stateless (응답도 별도) |
| 규칙 종류 | allow only | allow + deny |
| 평가 | 모든 규칙 합집합 | 번호 순서, 첫 매칭으로 결정 |
| 기본값 | inbound 차단, outbound 허용 | (기본/커스텀에 따라) |
| Source | CIDR + 다른 SG 의 ID 가능 | CIDR 만 |
디버깅 체크리스트
트래픽이 도달하지 못할 때 점검 순서를 정리해 두면 멘탈 모델이 잡힌다. 위에서 아래로 한 칸씩 내려가면 대개 원인이 잡힌다.
- Security Group inbound. 가장 흔한 원인. 출발지 IP/SG 와 포트가 허용되어 있는가.
- Security Group outbound. 응답이 아니라 새 연결을 인스턴스가 거는 경우. 기본값이 전체 허용이지만 커스터마이징되어 있다면 점검.
- Subnet 의 Route Table. 기본 경로가 IGW(외부 인입 필요 시) 또는 NAT(outbound 필요 시) 로 향하는가. 같은 VPC 내부면 Local route 가 자동.
- Public IP / Elastic IP. 외부에서의 inbound 가 필요하면 Public IP 가 부착되어 있는가. 부착되어 있어도 Route Table 조건과 함께 만족되어야 함.
- NACL. Subnet 단위라 보통 인프라 팀 영역이지만, stateless 특성상 ephemeral port 가 빠져 있을 수 있음. SG 가 분명 허용인데도 응답이 오지 않으면 의심.
- CIDR 충돌. 다른 VPC 와 Peering/TGW 로 연결된 환경에서 통신이 안 된다면 CIDR 겹침을 의심.
벤더 명칭
이 글은 AWS 용어로 통일했다. 다른 벤더의 같은 추상은 다음과 같다.
| 개념 | AWS | GCP | Azure | Alibaba Cloud |
|---|---|---|---|---|
| 가상 사설 네트워크 | VPC | VPC | Virtual Network (VNet) | VPC |
| Subnet | Subnet | Subnet | Subnet | VSwitch |
| 외부 출입구 | Internet Gateway | (Routes 의 next hop) | Public IP + NSG | Internet Gateway |
| outbound 전용 출구 | NAT Gateway | Cloud NAT | NAT Gateway | NAT Gateway |
| 1:1 VPC 연결 | VPC Peering | VPC Network Peering | VNet Peering | VPC Peering |
| Hub-Spoke 다수 연결 | Transit Gateway | Network Connectivity Center | Virtual WAN | CEN |
| 온프레미스 IPSec | Site-to-Site VPN | Cloud VPN | VPN Gateway | VPN Gateway |
| 서비스 단위 노출 | PrivateLink | Private Service Connect | Private Link | PrivateLink |
| 인스턴스 단위 stateful | Security Group | Firewall Rule (대상 태그) | NSG (NIC 적용) | Security Group |
| Subnet 단위 stateless | Network ACL | (직접 모델 없음) | NSG (Subnet 적용) | Network ACL |
명칭이 살짝씩 다르지만 추상은 거의 같다. GCP 는 SG/NACL 을 Firewall Rules 라는 통합 모델로 다루고, Azure 는 NSG 하나가 NIC 와 Subnet 양쪽에 적용될 수 있다는 정도가 결정적 차이다.
네 추상을 따로 익혀도 결국 같은 패킷 위에서 만난다. 모아놓고 보니 디버깅할 때마다 네 가지가 한 화면에 떠올라 한결 수월했다.