AWS Private Subnet NAT Gateway 연결했는데 인터넷이 안 될 때

Published by

on

Private Subnet에 EC2를 두고 NAT Gateway를 연결했다.
Route Table도 0.0.0.0/0 → nat-xxxx로 설정했다.
그런데 여전히 curl은 timeout이 난다.

DNS는 되는데 외부 연결이 안 되는 경우,
이건 NAT Gateway 구조가 잘못된 경우다.


문제 증상

EC2에서 다음 명령을 실행했을 때

curl -v www.github.com

결과는 이렇게 나온다.

* Host www.github.com:80 was resolved.
* IPv4: 20.200.245.247
* connect to 20.200.245.247 port 80 failed: Connection timed out

DNS는 정상이다.
즉, VPC의 enableDnsSupport, enableDnsHostnames는 켜져 있다.
하지만 TCP 연결이 되지 않는다.
패킷이 NAT Gateway를 통과하지 못하고 끊기는 상황이다.


NAT 구조

NAT Gateway는 Private Subnet의 트래픽을 대신 외부로 내보내주는 역할을 한다.

EC2 (Private Subnet)
   ↓
NAT Gateway (Public Subnet)
   ↓
Internet Gateway (IGW)

이 경로 중 하나라도 잘못되어 있으면
DNS는 되지만 “Connection timed out” 상태가 된다.


1. NAT Gateway가 Public Subnet이 아님

가장 흔한 실수다.

NAT Gateway는 반드시 Public Subnet 안에 있어야 한다.
Public Subnet의 Route Table에는 다음 경로가 존재해야 한다. (즉 같은 AZ 에 있어야 한다는 의미 아래 자세희 설명)

DestinationTarget
0.0.0.0/0igw-xxxxxx

이 경로가 없으면 NAT은 인터넷으로 나갈 수 없다.
Private Subnet이 NAT을 향하더라도 NAT이 IGW로 못 나가면 EC2는 timeout 상태가 된다.


2. NAT Gateway에 Elastic IP(EIP)가 연결되어 있지 않음

이것도 자주 발생한다.

NAT Gateway를 만들 때 EIP를 연결하지 않으면,
NAT은 외부와 통신할 수 없다.

EIP는 NAT이 IGW를 통해 외부와 통신할 때 사용하는 공인 IP다.
EIP가 없으면 NAT Gateway는 외부 요청을 보낼 수 없다.


3. NAT Gateway와 Private Subnet의 AZ(가용 영역)가 다름

이건 놓치기 쉬운 포인트다.

NAT Gateway는 AZ 단위 리소스다.
즉, NAT을 만들 때 선택한 Subnet의 AZ 내부에서만 동작한다.
예를 들어 NAT이 ap-northeast-2a에 있고 EC2가 ap-northeast-2b에 있다면
Route Table에 NAT을 지정해도 트래픽은 전달되지 않는다.

이유는 NAT Gateway가 Cross-AZ 트래픽을 지원하지 않기 때문이다.
각 AZ는 물리적으로 분리된 네트워크이므로
“다른 AZ의 NAT”을 통해 외부로 나가면 비효율적이며
AWS도 이를 비권장으로 명시하고 있다.

“For high availability, create a NAT gateway in each Availability Zone and configure your routing to use the NAT gateway in the same zone.”
AWS NAT Gateway Best Practices


4. NAT 상태가 Pending 또는 Failed

EIP 연결이 누락되었거나 잘못된 Subnet에 생성된 경우
NAT Gateway 상태가 Available이 아니라 Pending 혹은 Failed로 남는다.
이 상태에서는 아무 통신도 되지 않는다.

AWS 콘솔에서 NAT Gateway 상태가 Available인지 꼭 확인해야 한다.


AZ 단위 NAT 구조 이해하기

가용성(HA)을 확보하려면 각 AZ마다 NAT을 따로 두는 것이 정석이다.

VPC
├── Public Subnet A (ap-northeast-2a)
│     └── NAT Gateway A (EIP 연결)
├── Private Subnet A (ap-northeast-2a)
│     └── Route → NAT Gateway A
├── Public Subnet B (ap-northeast-2b)
│     └── NAT Gateway B (EIP 연결)
└── Private Subnet B (ap-northeast-2b)
      └── Route → NAT Gateway B

이렇게 구성하면
각 AZ의 EC2는 자기 NAT을 통해 외부로 나가며,
특정 AZ가 장애가 나더라도 다른 AZ는 영향을 받지 않는다.


점검 순서

  1. NAT Gateway가 Public Subnet에 있는지 확인
  2. NAT Gateway에 EIP가 연결되어 있는지 확인
  3. NAT Gateway와 EC2의 AZ가 같은지 확인
  4. NAT 상태가 Available인지 확인

이 네 가지가 대부분의 장애 원인이다.
NACL 문제는 거의 없다.
AWS 기본 NACL은 모든 트래픽을 허용하므로,
별도로 제한하지 않았다면 원인이 아니다.


정상 구조 예시

[VPC]
 ├─ Public Subnet
 │    ├─ NAT Gateway (EIP 연결)
 │    └─ Route → Internet Gateway (0.0.0.0/0 → igw-xxxx)
 ├─ Private Subnet
 │    ├─ EC2 (내부 서비스, Runner 등)
 │    └─ Route → NAT Gateway (0.0.0.0/0 → nat-xxxx)

이 구성이 완성되면, Private Subnet의 EC2에서도
curl https://github.com 명령이 정상적으로 응답한다.


NAT 생성 시 마지막 포인트

  1. Subnet 선택
    NAT Gateway는 반드시 Public Subnet을 선택해야 한다.
    Private Subnet을 선택하면 NAT이 IGW로 나가지 못한다.
  2. Elastic IP 연결
    NAT 생성 시 반드시 EIP를 연결해야 한다.
    연결하지 않으면 외부 트래픽이 나가지 않는다.
  3. Public Subnet 라우팅 확인
    NAT이 있는 Public Subnet의 Route Table에
    0.0.0.0/0 → Internet Gateway 경로가 있어야 한다.

이 세 가지가 빠지면 NAT Gateway는 “정상처럼 보이지만 통신되지 않는다.”
Private Subnet의 라우팅보다 NAT의 출구(IGW 경로)가 먼저 확보되어야 한다.


결론

DNS는 되는데 curl이 timeout으로 멈춘다면
Private Subnet의 설정이 아니라 NAT Gateway 구성을 확인해야 한다.

Public Subnet + Elastic IP + IGW 경로 + 같은 AZ
이 네 가지가 NAT Gateway의 핵심 조건이다.


참고 문서

댓글 남기기

오픈바이브 | oftenvibe.com에서 더 알아보기

지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

계속 읽기