커스텀 VPC에서 EC2 인터넷 안 됨 — Internet Gateway와 Route Table 설정 완전 가이드

커스텀 VPC를 직접 만들고 EC2를 띄웠는데 ping google.com이 응답하지 않는다. AWS 기본 VPC에서는 아무 설정 없이도 인터넷이 됐는데, 커스텀 VPC에서는 왜 안 될까 — 이 글은 그 질문에 대한 실전 답변이다.

TL;DR — 커스텀 VPC EC2 인터넷 불가 핵심 체크리스트

항목확인 내용CLI 명령
Internet Gateway 생성IGW가 존재하는가aws ec2 describe-internet-gateways
IGW VPC 연결IGW가 해당 VPC에 attach되었는가aws ec2 attach-internet-gateway
Route Table 경로0.0.0.0/0 → IGW 경로가 있는가aws ec2 describe-route-tables
서브넷 연결Public 서브넷이 해당 Route Table에 연결되어 있는가aws ec2 describe-subnets
Public IP 할당EC2에 Public IP 또는 EIP가 있는가aws ec2 describe-instances
Security Group아웃바운드 허용 규칙이 있는가aws ec2 describe-security-groups

커스텀 VPC에서 인터넷이 되려면 — 동작 원리

AWS 기본 VPC(Default VPC)는 계정 생성 시 자동으로 IGW, Route Table, Public 서브넷이 구성된다. 커스텀 VPC는 그 어떤 것도 자동으로 만들어지지 않는다. EC2가 인터넷과 통신하려면 다음 네 가지 조건이 모두 충족되어야 한다.

graph LR EC2["EC2 Instance
(Public IP 필요)"] --> SG["Security Group
아웃바운드 허용"] SG --> RT["Route Table
0.0.0.0/0 → IGW"] RT --> IGW["Internet Gateway
(VPC에 attached)"] IGW --> NET["인터넷"] SUBNET["Public 서브넷"] -.연결.-> RT EC2 -.위치.-> SUBNET style EC2 fill:#FF9900,color:#fff style IGW fill:#232F3E,color:#fff style NET fill:#1A9C3E,color:#fff
  1. Internet Gateway(IGW) — VPC와 인터넷 사이의 관문. VPC당 하나만 연결 가능하다.
  2. Route Table 경로0.0.0.0/0 목적지 트래픽을 IGW로 보내는 라우팅 항목이 있어야 한다.
  3. 서브넷-Route Table 연결 — EC2가 위치한 서브넷이 위 Route Table에 명시적으로 연결되어 있어야 한다.
  4. Public IP — EC2 인스턴스에 Public IP 또는 Elastic IP가 할당되어 있어야 한다. Private IP만 있으면 IGW를 통한 인터넷 통신이 불가능하다.
IGW는 라우터가 아니라 '문'에 가깝다. 문이 달려 있어도 지도(Route Table)에 그 문으로 가는 길이 없으면 패킷은 어디로도 가지 않는다.

단계별 진단 및 수정 — EC2 인터넷 연결 복구

1단계: Internet Gateway 생성 및 VPC 연결 확인

커스텀 VPC에 IGW가 없거나, 있어도 VPC에 연결되지 않은 경우가 가장 흔한 원인이다. IGW가 생성만 되고 VPC에 attach되지 않으면 콘솔에서 'detached' 상태로 표시되며, 라우팅 경로를 만들어도 트래픽이 나가지 않는다.

# 현재 계정의 IGW 목록과 연결 상태 확인
aws ec2 describe-internet-gateways \
  --query 'InternetGateways[*].{IGW:InternetGatewayId,State:Attachments[0].State,VPC:Attachments[0].VpcId}' \
  --output table

출력에서 해당 VPC ID에 연결된 IGW가 없거나 State가 비어 있다면, 아래 순서로 생성 및 연결한다.

# IGW 생성
aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=my-igw}]'

# 출력된 InternetGatewayId를 변수에 저장 (예시 ID)
IGW_ID=igw-0abc1234def56789a
VPC_ID=vpc-0123456789abcdef0

# IGW를 VPC에 연결
aws ec2 attach-internet-gateway \
  --internet-gateway-id $IGW_ID \
  --vpc-id $VPC_ID

# 연결 상태 재확인 — State가 attached로 바뀌었는지 확인한다
aws ec2 describe-internet-gateways \
  --internet-gateway-ids $IGW_ID \
  --query 'InternetGateways[0].Attachments'

2단계: Route Table에 인터넷 경로 추가

IGW가 연결되어 있어도 Route Table에 0.0.0.0/0 → IGW 항목이 없으면 외부로 나가는 패킷은 드롭된다. 커스텀 VPC의 기본 Route Table에는 로컬 VPC CIDR 경로만 존재한다 — 인터넷 경로는 수동으로 추가해야 한다.

# Public 서브넷에 연결된 Route Table ID 확인
aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=$VPC_ID" \
  --query 'RouteTables[*].{RTID:RouteTableId,Routes:Routes,Assoc:Associations[*].SubnetId}' \
  --output json

출력에서 0.0.0.0/0 항목이 없는 Route Table을 확인한다. Public 서브넷 전용 Route Table을 별도로 만드는 것이 운영 상 안전하다 — 메인 Route Table에 인터넷 경로를 추가하면 의도치 않은 서브넷까지 인터넷에 노출될 수 있다.

# Public 서브넷 전용 Route Table 생성
aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=public-rt}]'

RT_ID=rtb-0abc1234def56789b

# 0.0.0.0/0 → IGW 경로 추가
aws ec2 create-route \
  --route-table-id $RT_ID \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id $IGW_ID

3단계: Public 서브넷을 Route Table에 연결

Route Table에 인터넷 경로를 추가했어도, EC2가 위치한 서브넷이 그 Route Table에 연결되지 않으면 아무 효과가 없다. 서브넷은 명시적으로 연결하지 않으면 VPC의 메인 Route Table을 따른다.

SUBNET_ID=subnet-0abc1234def56789c

# 서브넷을 Public Route Table에 연결
aws ec2 associate-route-table \
  --route-table-id $RT_ID \
  --subnet-id $SUBNET_ID

# 연결 확인
aws ec2 describe-route-tables \
  --route-table-ids $RT_ID \
  --query 'RouteTables[0].Associations'

4단계: EC2 인스턴스의 Public IP 확인

라우팅이 완벽해도 EC2에 Public IP가 없으면 IGW는 패킷을 인터넷으로 내보낼 수 없다. IGW는 NAT 기능을 수행하는데, 이때 인스턴스의 Public IP가 반드시 필요하다. 커스텀 서브넷은 기본적으로 Public IP 자동 할당이 비활성화되어 있다.

INSTANCE_ID=i-0abc1234def56789d

# 인스턴스의 Public IP 확인
aws ec2 describe-instances \
  --instance-ids $INSTANCE_ID \
  --query 'Reservations[0].Instances[0].{PublicIP:PublicIpAddress,PrivateIP:PrivateIpAddress,State:State.Name}'

PublicIPnull이면 두 가지 방법으로 해결한다.

방법 A — 서브넷의 Public IP 자동 할당 활성화 (새 인스턴스에 적용)

aws ec2 modify-subnet-attribute \
  --subnet-id $SUBNET_ID \
  --map-public-ip-on-launch

방법 B — 실행 중인 인스턴스에 Elastic IP 연결

# EIP 할당
aws ec2 allocate-address --domain vpc

ALLOCATION_ID=eipalloc-0abc1234def56789e

# 인스턴스에 EIP 연결
aws ec2 associate-address \
  --instance-id $INSTANCE_ID \
  --allocation-id $ALLOCATION_ID

5단계: Security Group 아웃바운드 규칙 확인

여기까지 했는데도 ping이 안 된다면 Security Group을 확인한다. 기본 Security Group은 아웃바운드 전체 허용이지만, 커스텀 Security Group을 적용했다면 아웃바운드 규칙이 제한되어 있을 수 있다. ICMP(ping)와 TCP 443(HTTPS) 모두 명시적으로 허용되어 있는지 본다.

# 인스턴스에 연결된 Security Group 확인
aws ec2 describe-instances \
  --instance-ids $INSTANCE_ID \
  --query 'Reservations[0].Instances[0].SecurityGroups'

SG_ID=sg-0abc1234def56789f

# Security Group 아웃바운드 규칙 확인
aws ec2 describe-security-groups \
  --group-ids $SG_ID \
  --query 'SecurityGroups[0].IpPermissionsEgress'

아웃바운드 규칙이 없거나 제한적이라면 전체 아웃바운드를 허용하는 규칙을 추가한다.

aws ec2 authorize-security-group-egress \
  --group-id $SG_ID \
  --protocol -1 \
  --port -1 \
  --cidr 0.0.0.0/0

실제 장애 패턴 — 흔한 오진과 실제 원인

Route Table에 0.0.0.0/0 → igw-xxxxx 경로가 분명히 있는데 인터넷이 안 된다는 케이스가 있다. 콘솔에서 Route Table을 보면 경로가 있고, IGW도 attached 상태다. Security Group도 전체 허용이다. 그런데 SSH도 안 되고 ping도 안 된다.

실제 원인은 서브넷 연결이었다. 해당 Route Table은 Public 서브넷에 연결되지 않고 VPC 메인 Route Table로 남아 있었고, EC2가 위치한 서브넷은 여전히 인터넷 경로가 없는 메인 Route Table을 따르고 있었다. 콘솔에서 Route Table 탭을 보면 경로가 보이지만, 그 Route Table이 실제로 어떤 서브넷에 연결되어 있는지는 'Subnet Associations' 탭을 별도로 확인해야 한다.

서브넷 연결 확인 없이 Route Table 경로만 보고 '설정이 맞다'고 판단하는 것이 이 문제의 전형적인 오진이다.

graph TD START["ping google.com 실패"] --> CHK1{"IGW가 VPC에
attached인가?"} CHK1 -- 아니오 --> FIX1["IGW 생성 후
attach-internet-gateway"] CHK1 -- 예 --> CHK2{"Route Table에
0.0.0.0/0 → IGW 있나?"} FIX1 --> CHK2 CHK2 -- 아니오 --> FIX2["create-route
0.0.0.0/0 → IGW"] CHK2 -- 예 --> CHK3{"서브넷이 해당
Route Table에 연결?"} FIX2 --> CHK3 CHK3 -- 아니오 --> FIX3["associate-route-table
서브넷 연결"] CHK3 -- 예 --> CHK4{"EC2에
Public IP 있나?"} FIX3 --> CHK4 CHK4 -- 아니오 --> FIX4["EIP 할당 또는
서브넷 자동할당 활성화"] CHK4 -- 예 --> CHK5{"SG 아웃바운드
허용 규칙 있나?"} FIX4 --> CHK5 CHK5 -- 아니오 --> FIX5["authorize-security-group-egress"] CHK5 -- 예 --> DONE["연결 성공"] FIX5 --> DONE style START fill:#d32f2f,color:#fff style DONE fill:#1A9C3E,color:#fff

최종 연결 검증

모든 설정이 완료되면 EC2에 SSH로 접속해 실제 인터넷 연결을 확인한다.

# EC2에 SSH 접속 후 실행
ping -c 4 google.com
curl -I https://aws.amazon.com

ping이 응답하고 curl이 HTTP 200을 반환하면 인터넷 연결이 정상이다. ping만 안 되고 curl은 된다면 Security Group의 ICMP 인바운드 규칙이 없는 것이다 — 인터넷 연결 자체는 정상이다.

커스텀 VPC EC2 인터넷 연결 — 마무리 및 다음 단계

커스텀 VPC에서 EC2 인터넷 연결이 안 되는 문제는 대부분 IGW 미연결, Route Table 경로 누락, 서브넷-Route Table 미연결, Public IP 미할당 중 하나다. 이 네 가지를 순서대로 확인하면 대부분 해결된다.

다음 단계로 고려할 사항:

  • Private 서브넷의 EC2가 인터넷에 나가야 한다면 NAT Gateway를 구성한다.
  • VPC Flow Logs를 활성화하면 패킷이 어느 지점에서 드롭되는지 추적할 수 있다.
  • Network ACL은 서브넷 레벨에서 동작하며, 기본값은 전체 허용이지만 커스텀 NACL을 적용했다면 인바운드/아웃바운드 규칙을 모두 확인해야 한다.

공식 문서: AWS VPC Internet Gateway 공식 문서

핵심 용어 정리

용어설명
Internet Gateway (IGW)VPC와 인터넷 사이의 수평 확장 가능한 관문. VPC당 하나만 연결 가능하다.
Route Table서브넷의 트래픽 라우팅 규칙 집합. 서브넷은 반드시 하나의 Route Table에 연결된다.
Public 서브넷인터넷 경로(0.0.0.0/0 → IGW)가 있는 Route Table에 연결된 서브넷.
Elastic IP (EIP)계정에 고정 할당되는 Public IPv4 주소. 인스턴스 재시작 후에도 변경되지 않는다.
Security Group인스턴스 레벨의 상태 기반(stateful) 방화벽. 인바운드/아웃바운드 규칙을 별도로 관리한다.

Related Posts

댓글

이 블로그의 인기 게시물

EC2 SSH 연결 시간 초과: 확인해야 할 보안 그룹(Security Group) 규칙

EC2 SSH 연결 타임아웃 완전 해결 가이드: Security Group 인바운드 규칙부터 라우팅까지

IAM User vs IAM Role 차이점 완전 정리 — EC2에서 S3 접근 시 무엇을 써야 하는가