본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 20. · 4 Views
NAT Gateway와 인터넷 접근 완벽 가이드
Private Subnet에서 인터넷에 접근하는 방법을 배웁니다. NAT Gateway의 개념부터 실전 구성까지, AWS 네트워킹의 핵심을 이해합니다.
목차
- NAT Gateway란?
- NAT Gateway 생성
- 라우팅 테이블 설정
- NAT Gateway vs NAT 인스턴스
- 비용 고려사항
- 불필요한 외부 API 호출을 캐싱으로 줄임 → 트래픽 30% 감소
- 고가용성 구성
1. NAT Gateway란?
어느 날 김개발 씨는 AWS에 서버를 구축하면서 이상한 문제를 발견했습니다. Private Subnet에 있는 인스턴스가 외부 API를 호출하지 못하는 것이었습니다.
보안상 Public IP를 부여하지 않았는데, 그렇다면 어떻게 인터넷에 접근해야 할까요?
NAT Gateway는 Private Subnet의 리소스가 인터넷에 접근할 수 있게 해주는 관문입니다. 마치 회사의 보안 담당자가 내부 직원의 외부 통신을 대신 처리해주는 것과 같습니다.
외부에서는 Private 리소스에 직접 접근할 수 없지만, 내부에서는 외부로 나갈 수 있는 단방향 통신을 가능하게 합니다.
다음 코드를 살펴봅시다.
import boto3
# NAT Gateway 생성
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# Elastic IP 할당 (NAT Gateway에 필요)
allocation = ec2.allocate_address(Domain='vpc')
allocation_id = allocation['AllocationId']
# NAT Gateway 생성
nat_gateway = ec2.create_nat_gateway(
SubnetId='subnet-public123', # Public Subnet에 생성
AllocationId=allocation_id,
TagSpecifications=[{
'ResourceType': 'natgateway',
'Tags': [{'Key': 'Name', 'Value': 'MyNATGateway'}]
}]
)
print(f"NAT Gateway ID: {nat_gateway['NatGateway']['NatGatewayId']}")
김개발 씨는 AWS 클라우드 엔지니어로 입사한 지 2개월이 된 주니어 개발자입니다. 오늘 받은 업무는 데이터베이스 서버를 Private Subnet에 배치하는 것이었습니다.
보안 요구사항에 따라 외부에서 직접 접근할 수 없어야 하기 때문입니다. 그런데 문제가 생겼습니다.
데이터베이스가 패키지를 업데이트하려면 인터넷에 접근해야 하는데, Private Subnet에 있어서 외부와 통신이 불가능한 것입니다. 선배 개발자 박시니어 씨가 모니터를 보며 말했습니다.
"아, NAT Gateway를 설정해야 하는데 빼먹었네요. 이것 없이는 Private Subnet에서 인터넷을 쓸 수 없어요." NAT Gateway란 무엇일까요?
쉽게 비유하자면, NAT Gateway는 마치 회사의 보안 게이트와 같습니다. 회사 내부 직원들이 외부로 나갈 때는 보안 게이트를 통과할 수 있지만, 외부 사람들이 함부로 들어올 수는 없습니다.
직원이 밖으로 나갈 때 보안 담당자가 신분을 확인하고 출입을 허가하는 것처럼, NAT Gateway도 Private Subnet의 리소스가 인터넷으로 나가는 것을 중계해줍니다. 왜 이런 것이 필요한가요?
AWS에서 서버를 구축할 때 보안을 위해 Private Subnet을 사용합니다. 데이터베이스나 애플리케이션 서버처럼 외부에 직접 노출되면 안 되는 리소스들을 배치하는 곳입니다.
하지만 이런 서버들도 때로는 인터넷이 필요합니다. 운영체제 업데이트를 받거나, 외부 API를 호출하거나, 클라우드 스토리지에 접근해야 할 때가 있습니다.
그렇다고 Public IP를 부여하면 어떻게 될까요? 외부에서 직접 접근할 수 있게 되어 보안 위험이 커집니다.
해커들의 공격 대상이 될 수 있습니다. 바로 이런 딜레마를 해결하기 위해 NAT Gateway가 등장했습니다.
NAT는 Network Address Translation의 약자입니다. 말 그대로 네트워크 주소를 변환해주는 것입니다.
Private IP를 Public IP로 바꿔주어 인터넷 통신이 가능하게 만들지만, 외부에서 들어오는 요청은 차단합니다. 위의 코드를 살펴보겠습니다.
먼저 Elastic IP를 할당받습니다. NAT Gateway가 인터넷과 통신하려면 고정된 Public IP가 필요하기 때문입니다.
그 다음 create_nat_gateway 함수로 NAT Gateway를 생성합니다. 여기서 중요한 점은 SubnetId에 Public Subnet을 지정해야 한다는 것입니다.
NAT Gateway 자체는 Public Subnet에 위치해야 인터넷 게이트웨이를 통해 외부와 통신할 수 있습니다. 실제 현업에서는 어떻게 활용할까요?
전자상거래 플랫폼을 운영한다고 가정해봅시다. 주문 처리 서버는 Private Subnet에 배치하여 보안을 강화합니다.
하지만 이 서버가 결제 API를 호출하거나, 재고 관리 시스템과 통신하려면 인터넷이 필요합니다. NAT Gateway를 구성하면 주문 서버는 안전하게 외부 서비스와 통신할 수 있으면서도, 외부의 직접적인 공격은 차단할 수 있습니다.
주의할 점도 있습니다. NAT Gateway는 반드시 Public Subnet에 생성해야 합니다.
초보자들이 흔히 하는 실수가 Private Subnet에 NAT Gateway를 만드는 것입니다. 그러면 NAT Gateway 자체가 인터넷에 접근할 수 없어서 제 역할을 하지 못합니다.
또한 NAT Gateway는 가용 영역별로 생성됩니다. 하나의 NAT Gateway는 하나의 가용 영역에만 존재합니다.
고가용성을 위해서는 각 가용 영역마다 NAT Gateway를 만들어야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 듣고 NAT Gateway를 생성한 김개발 씨는 이제 Private Subnet의 인스턴스가 패키지를 업데이트할 수 있게 되었습니다. NAT Gateway를 이해하면 AWS 네트워킹의 핵심을 파악할 수 있습니다.
보안과 접근성이라는 두 마리 토끼를 모두 잡는 방법입니다.
실전 팁
💡 - NAT Gateway는 반드시 Public Subnet에 생성하세요
- Elastic IP는 NAT Gateway 생성 전에 미리 할당받아야 합니다
- 생성 후 상태가 'available'이 될 때까지 기다려야 사용할 수 있습니다
2. NAT Gateway 생성
김개발 씨는 NAT Gateway의 개념은 이해했지만, 실제로 어떻게 만드는지가 궁금했습니다. AWS 콘솔을 열어보니 VPC 메뉴 안에 NAT Gateway 항목이 있었습니다.
그런데 생성 버튼을 누르자 여러 가지 옵션이 나타났습니다.
NAT Gateway 생성은 몇 가지 필수 단계를 거칩니다. Public Subnet 선택, Elastic IP 할당, 그리고 태그 설정이 핵심입니다.
AWS 콘솔이나 CLI, SDK를 통해 생성할 수 있으며, 생성 후 몇 분 정도 기다려야 사용 가능한 상태가 됩니다.
다음 코드를 살펴봅시다.
import boto3
import time
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 1. Elastic IP 할당
eip = ec2.allocate_address(Domain='vpc')
print(f"Elastic IP 할당: {eip['PublicIp']}")
# 2. NAT Gateway 생성
response = ec2.create_nat_gateway(
SubnetId='subnet-pub1a2b3c', # Public Subnet ID
AllocationId=eip['AllocationId'],
TagSpecifications=[{
'ResourceType': 'natgateway',
'Tags': [
{'Key': 'Name', 'Value': 'Production-NAT'},
{'Key': 'Environment', 'Value': 'prod'}
]
}]
)
nat_gateway_id = response['NatGateway']['NatGatewayId']
print(f"NAT Gateway 생성 중: {nat_gateway_id}")
# 3. 상태 확인 (available 될 때까지 대기)
while True:
status = ec2.describe_nat_gateways(NatGatewayIds=[nat_gateway_id])
state = status['NatGateways'][0]['State']
print(f"현재 상태: {state}")
if state == 'available':
print("NAT Gateway 생성 완료!")
break
elif state == 'failed':
print("생성 실패!")
break
time.sleep(10) # 10초마다 확인
박시니어 씨가 김개발 씨의 화면을 가리키며 설명을 시작했습니다. "NAT Gateway 생성은 생각보다 간단해요.
하지만 몇 가지 순서를 정확히 지켜야 합니다." 첫 번째 단계는 무엇일까요? 바로 Elastic IP 할당입니다.
Elastic IP는 AWS에서 제공하는 고정 Public IP 주소입니다. 일반적인 Public IP는 인스턴스를 재시작하면 바뀔 수 있지만, Elastic IP는 한 번 할당받으면 해제하기 전까지 계속 유지됩니다.
NAT Gateway는 인터넷과 통신하기 위해 이 고정 IP가 필요합니다. 코드의 첫 부분을 보면 allocate_address 함수로 Elastic IP를 할당받습니다.
Domain='vpc' 파라미터는 VPC 내에서 사용할 IP라는 의미입니다. 이 함수를 실행하면 AWS가 사용 가능한 Public IP 중 하나를 할당해줍니다.
두 번째 단계는 실제 NAT Gateway 생성입니다. create_nat_gateway 함수에 세 가지 중요한 정보를 전달합니다.
첫째, SubnetId입니다. 앞서 말했듯이 반드시 Public Subnet의 ID를 지정해야 합니다.
Private Subnet을 지정하면 NAT Gateway가 작동하지 않습니다. 둘째, AllocationId입니다.
방금 할당받은 Elastic IP의 ID를 여기에 넣습니다. 이렇게 하면 NAT Gateway가 그 IP 주소를 사용하여 인터넷과 통신합니다.
셋째, 태그입니다. 태그는 필수는 아니지만 운영 관리를 위해 꼭 붙이는 것이 좋습니다.
'Name' 태그로 NAT Gateway의 용도를 명확히 하고, 'Environment' 태그로 개발/스테이징/프로덕션 환경을 구분할 수 있습니다. 그런데 여기서 중요한 점이 있습니다.
NAT Gateway는 생성 요청을 하자마자 바로 사용할 수 있는 것이 아닙니다. 세 번째 단계는 상태 확인입니다.
NAT Gateway가 'pending' 상태에서 'available' 상태로 바뀌는 데는 보통 1~2분 정도 걸립니다. 위의 코드에서는 반복문을 사용하여 10초마다 상태를 확인합니다.
describe_nat_gateways 함수로 현재 상태를 조회하고, 'available'이 되면 루프를 빠져나옵니다. 만약 'failed' 상태가 되면 어떻게 될까요?
생성에 실패한 것입니다. 주로 Elastic IP가 이미 다른 리소스에 할당되어 있거나, Subnet ID가 잘못되었을 때 발생합니다.
실제 프로덕션 환경에서는 어떻게 사용할까요? 대규모 서비스를 운영하는 회사에서는 보통 Infrastructure as Code(IaC) 도구를 사용합니다.
Terraform이나 CloudFormation 같은 도구로 NAT Gateway를 코드로 정의하고, 자동으로 생성하고 관리합니다. 하지만 처음 배울 때는 위와 같이 직접 SDK를 사용해보는 것이 이해에 도움이 됩니다.
김개발 씨가 코드를 실행했습니다. 터미널에 "NAT Gateway 생성 중"이라는 메시지가 나타나고, 10초마다 상태가 출력되기 시작했습니다.
"pending... pending...
available!" 드디어 생성이 완료되었습니다. 박시니어 씨가 웃으며 말했습니다.
"이제 라우팅 테이블만 설정하면 Private Subnet에서 인터넷을 쓸 수 있어요." NAT Gateway 생성 자체는 복잡하지 않습니다. 하지만 Elastic IP 할당, Public Subnet 선택, 상태 확인이라는 세 가지 단계를 정확히 이해하고 있어야 실수하지 않습니다.
실전 팁
💡 - Elastic IP는 사용하지 않으면 요금이 부과되므로, NAT Gateway에 즉시 연결하세요
- 생성 후 반드시 'available' 상태를 확인하고 다음 작업을 진행하세요
- 태그를 잘 활용하면 나중에 비용 추적과 관리가 훨씬 쉬워집니다
3. 라우팅 테이블 설정
NAT Gateway를 생성했지만, Private Subnet의 인스턴스는 여전히 인터넷에 접근할 수 없었습니다. 김개발 씨는 당황했지만, 박시니어 씨는 예상했다는 듯이 말했습니다.
"아직 라우팅 테이블을 설정하지 않았잖아요. 길을 만들었으면 이정표도 세워야죠."
라우팅 테이블 설정은 NAT Gateway를 실제로 사용하기 위한 필수 단계입니다. Private Subnet의 라우팅 테이블에 인터넷 트래픽(0.0.0.0/0)을 NAT Gateway로 보내는 규칙을 추가해야 합니다.
이것이 없으면 NAT Gateway가 있어도 트래픽이 도달하지 않습니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# Private Subnet의 라우팅 테이블 ID
route_table_id = 'rtb-private123'
nat_gateway_id = 'nat-0a1b2c3d4e5f'
# 인터넷 트래픽을 NAT Gateway로 라우팅
response = ec2.create_route(
RouteTableId=route_table_id,
DestinationCidrBlock='0.0.0.0/0', # 모든 인터넷 트래픽
NatGatewayId=nat_gateway_id
)
print(f"라우팅 규칙 생성: {response['Return']}")
# 라우팅 테이블 확인
routes = ec2.describe_route_tables(RouteTableIds=[route_table_id])
for route in routes['RouteTables'][0]['Routes']:
print(f"목적지: {route.get('DestinationCidrBlock', 'N/A')}, "
f"대상: {route.get('NatGatewayId', route.get('GatewayId', 'local'))}")
김개발 씨는 고개를 갸우뚱했습니다. "NAT Gateway를 만들었는데 왜 안 되는 거죠?" 박시니어 씨가 화이트보드를 가리키며 설명을 시작했습니다.
"네트워크는 길찾기와 같아요. NAT Gateway는 톨게이트라고 생각하면 됩니다.
톨게이트를 지어놨는데, 차들에게 그 톨게이트로 가라고 알려주지 않으면 아무도 그리로 가지 않겠죠?" 바로 그 역할을 하는 것이 라우팅 테이블입니다. 라우팅 테이블은 네트워크 트래픽이 어디로 가야 하는지를 알려주는 이정표입니다.
AWS VPC에서 각 Subnet은 라우팅 테이블과 연결되어 있습니다. Private Subnet의 인스턴스가 외부 IP로 패킷을 보내려고 할 때, 라우팅 테이블을 확인하여 어디로 보내야 할지 결정합니다.
기본적으로 Private Subnet의 라우팅 테이블에는 무엇이 있을까요? 보통 VPC 내부 통신을 위한 'local' 경로만 있습니다.
예를 들어 VPC의 CIDR이 10.0.0.0/16이라면, 10.0.0.0/16 대역으로 가는 트래픽은 local, 즉 VPC 내부에서 직접 처리됩니다. 하지만 외부 인터넷으로 가는 경로는 정의되어 있지 않습니다.
바로 여기에 우리가 만든 NAT Gateway로 가는 경로를 추가해야 합니다. 위의 코드를 살펴보겠습니다.
create_route 함수가 핵심입니다. 첫 번째 파라미터는 수정할 라우팅 테이블의 ID입니다.
Private Subnet과 연결된 라우팅 테이블을 지정해야 합니다. 두 번째 파라미터 DestinationCidrBlock은 '0.0.0.0/0'입니다.
이것은 모든 인터넷 트래픽을 의미합니다. 즉, "VPC 내부가 아닌 모든 외부 트래픽은 이 규칙을 따르라"는 뜻입니다.
세 번째 파라미터는 NAT Gateway의 ID입니다. 앞서 생성한 NAT Gateway를 지정하면, 모든 외부 트래픽이 그 NAT Gateway를 거쳐 나가게 됩니다.
코드의 두 번째 부분은 확인 작업입니다. describe_route_tables 함수로 라우팅 테이블의 모든 규칙을 조회합니다.
그러면 'local' 경로와 함께 우리가 방금 추가한 '0.0.0.0/0 → NAT Gateway' 규칙이 나타날 것입니다. 실제로 이 설정이 어떻게 작동할까요?
Private Subnet에 있는 EC2 인스턴스가 외부 API(예: api.example.com)를 호출한다고 가정해봅시다. 인스턴스는 먼저 DNS로 도메인을 IP 주소로 변환합니다.
그 다음 해당 IP로 패킷을 보내려고 할 때 라우팅 테이블을 확인합니다. "목적지 IP가 VPC 내부가 아니네?
0.0.0.0/0 규칙을 따라야겠다. NAT Gateway로 보내자!" 패킷은 NAT Gateway에 도착하고, NAT Gateway는 출발지 IP를 자신의 Elastic IP로 바꿔서 인터넷으로 보냅니다.
응답이 돌아오면 NAT Gateway가 다시 원래 Private IP로 주소를 변환하여 인스턴스에 전달합니다. 주의할 점이 있습니다.
Public Subnet의 라우팅 테이블에는 NAT Gateway를 추가하면 안 됩니다. Public Subnet은 이미 인터넷 게이트웨이(IGW)로 연결되어 있기 때문입니다.
만약 Public Subnet에 NAT Gateway 규칙을 추가하면 라우팅 충돌이 발생할 수 있습니다. 또한 여러 Private Subnet이 있다면, 각 Subnet의 라우팅 테이블에 모두 NAT Gateway 규칙을 추가해야 합니다.
하나의 라우팅 테이블을 여러 Subnet과 공유할 수도 있고, Subnet마다 별도의 라우팅 테이블을 만들 수도 있습니다. 김개발 씨가 코드를 실행하고 라우팅 테이블을 확인했습니다.
화면에 두 개의 경로가 나타났습니다. 목적지: 10.0.0.0/16, 대상: local 목적지: 0.0.0.0/0, 대상: nat-0a1b2c3d4e5f 박시니어 씨가 고개를 끄덕였습니다.
"이제 Private Subnet의 인스턴스에 접속해서 외부 인터넷이 되는지 확인해보세요." 김개발 씨는 인스턴스에 SSH로 접속하여 curl google.com을 실행했습니다. 드디어 구글의 HTML이 화면에 나타났습니다.
성공입니다! 라우팅 테이블 설정은 NAT Gateway를 실제로 동작하게 만드는 마지막 퍼즐 조각입니다.
톨게이트를 지었으면 이정표도 세워야 한다는 박시니어 씨의 말이 이제 완벽히 이해되었습니다.
실전 팁
💡 - 0.0.0.0/0은 모든 인터넷 트래픽을 의미하는 CIDR 표기법입니다
- Private Subnet의 라우팅 테이블만 수정하고, Public Subnet은 건드리지 마세요
- 라우팅 규칙 추가 후 반드시 실제 인터넷 접속을 테스트해보세요
4. NAT Gateway vs NAT 인스턴스
박시니어 씨가 커피를 마시며 말했습니다. "예전에는 NAT Gateway가 없었어요.
그때는 NAT 인스턴스를 직접 구성해서 사용했죠." 김개발 씨는 궁금했습니다. 둘 다 같은 역할을 하는데, 왜 AWS는 NAT Gateway라는 새로운 서비스를 만들었을까요?
NAT Gateway는 AWS 관리형 서비스이고, NAT 인스턴스는 EC2에 NAT 소프트웨어를 설치하여 직접 운영하는 방식입니다. NAT Gateway는 관리가 쉽고 고가용성이 보장되지만 비용이 높습니다.
NAT 인스턴스는 비용을 절약할 수 있지만 직접 관리해야 하는 부담이 있습니다.
다음 코드를 살펴봅시다.
# NAT Gateway 생성 (AWS 관리형)
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 방법 1: NAT Gateway (권장)
nat_gw = ec2.create_nat_gateway(
SubnetId='subnet-public123',
AllocationId='eipalloc-abc123'
)
# AWS가 자동으로 관리, 패치, 확장 처리
# 가용성: AWS가 보장
# 대역폭: 자동 확장 (최대 100 Gbps)
# 방법 2: NAT 인스턴스 (레거시)
# EC2 인스턴스를 직접 생성
instance = ec2.run_instances(
ImageId='ami-nat-instance', # NAT AMI
InstanceType='t3.small',
SubnetId='subnet-public123',
# Source/Destination Check 비활성화 필수
)
# 직접 관리 필요: OS 패치, 모니터링, 장애 대응
# 가용성: 직접 구성 필요 (자동 복구 스크립트 등)
# 대역폭: 인스턴스 타입에 제한됨
print("NAT Gateway: 관리형, 고가용성, 고비용")
print("NAT 인스턴스: 직접 관리, 저비용, 유연성")
김개발 씨는 회사 위키를 뒤적이다가 3년 전 문서를 발견했습니다. "NAT 인스턴스 구성 가이드"라는 제목의 문서였습니다.
내용을 읽어보니 EC2 인스턴스에 NAT 기능을 직접 설정하는 방법이 상세히 적혀 있었습니다. "이거 되게 복잡한데요?" 김개발 씨가 박시니어 씨에게 물었습니다.
박시니어 씨가 웃으며 대답했습니다. "맞아요.
그래서 NAT Gateway가 나온 거예요. 하지만 상황에 따라 NAT 인스턴스가 더 나을 때도 있어요." 먼저 NAT 인스턴스의 역사를 알아봅시다.
AWS 초창기에는 NAT Gateway 같은 서비스가 없었습니다. 개발자들이 Private Subnet에서 인터넷을 사용하려면 직접 EC2 인스턴스를 하나 띄우고, 그 안에 NAT 소프트웨어를 설치해야 했습니다.
Linux의 iptables를 이용하여 IP 포워딩과 NAT 규칙을 직접 설정하는 방식이었습니다. 이 방식의 문제점은 무엇이었을까요?
첫째, 관리가 복잡했습니다. OS 업데이트, 보안 패치, NAT 소프트웨어 설정 등을 모두 직접 해야 했습니다.
NAT 인스턴스가 다운되면 Private Subnet의 모든 인스턴스가 인터넷을 사용할 수 없게 되므로, 모니터링과 장애 대응 체계도 갖춰야 했습니다. 둘째, 고가용성 구성이 어려웠습니다.
인스턴스가 장애 나면 수동으로 복구하거나, 복잡한 자동 복구 스크립트를 만들어야 했습니다. 두 개의 가용 영역에 NAT 인스턴스를 배치하고, Health Check를 하고, 장애 시 라우팅을 바꾸는 자동화를 직접 구현해야 했습니다.
셋째, 성능 제한이 있었습니다. EC2 인스턴스의 네트워크 대역폭은 인스턴스 타입에 따라 제한됩니다.
트래픽이 증가하면 더 큰 인스턴스로 교체해야 했고, 그 과정에서 다운타임이 발생했습니다. 그래서 AWS는 NAT Gateway를 출시했습니다.
NAT Gateway는 완전 관리형 서비스입니다. 사용자가 할 일은 생성 버튼을 누르고 라우팅 테이블을 설정하는 것뿐입니다.
AWS가 알아서 하드웨어를 관리하고, 소프트웨어를 업데이트하고, 고가용성을 보장합니다. 가용성은 어떻게 보장될까요?
NAT Gateway는 하나의 가용 영역 내에서 자동으로 이중화됩니다. 내부적으로 여러 대의 서버가 동작하고 있어서, 하나가 고장 나도 서비스가 중단되지 않습니다.
성능은 어떨까요? NAT Gateway는 자동으로 확장됩니다.
트래픽이 늘어나면 AWS가 자동으로 용량을 늘려줍니다. 최대 100 Gbps까지 지원하므로, 웬만한 서비스에서는 성능 걱정을 하지 않아도 됩니다.
그렇다면 NAT 인스턴스는 완전히 사라진 걸까요? 아닙니다.
여전히 NAT 인스턴스를 선택하는 경우가 있습니다. 첫째, 비용입니다.
NAT Gateway는 시간당 고정 요금과 데이터 처리 요금을 모두 부과합니다. 한국 리전 기준 시간당 약 60원, 그리고 처리한 데이터 1GB당 약 60원이 추가됩니다.
하루 종일 켜두고 100GB를 처리하면 월 10만 원이 넘습니다. 반면 NAT 인스턴스는 EC2 요금만 냅니다.
t3.nano 같은 작은 인스턴스를 사용하면 월 5천 원 정도로 운영할 수 있습니다. 트래픽이 적은 개발 환경이나 스타트업에서는 이것이 큰 차이입니다.
둘째, 유연성입니다. NAT 인스턴스는 그냥 EC2 인스턴스이므로 추가 기능을 설치할 수 있습니다.
예를 들어 트래픽 필터링, 로깅, VPN 등을 같은 인스턴스에서 처리할 수 있습니다. NAT Gateway는 NAT 기능만 제공하므로 이런 커스터마이징이 불가능합니다.
셋째, 특수한 네트워크 요구사항입니다. 어떤 경우에는 NAT 동작을 세밀하게 제어해야 할 때가 있습니다.
NAT 인스턴스를 사용하면 iptables 규칙을 직접 수정하여 원하는 대로 동작을 조정할 수 있습니다. 현업에서는 어떻게 선택할까요?
대부분의 프로덕션 환경에서는 NAT Gateway를 사용합니다. 관리 부담이 없고, 안정성이 높기 때문입니다.
개발팀이 인프라 관리에 시간을 쓰는 것보다, 서비스 개발에 집중하는 것이 더 가치 있습니다. 하지만 비용이 중요한 소규모 프로젝트나 개발 환경에서는 NAT 인스턴스를 고려해볼 만합니다.
트래픽이 적고, 가끔 다운타임이 발생해도 괜찮다면 NAT 인스턴스로 비용을 크게 절감할 수 있습니다. 김개발 씨가 물었습니다.
"그럼 우리 회사는 왜 NAT Gateway를 쓰나요?" 박시니어 씨가 대답했습니다. "프로덕션 서비스니까요.
고객 서비스가 멈추면 안 되잖아요. 관리 부담 없이 안정적으로 운영하는 게 비용보다 중요해요." NAT Gateway와 NAT 인스턴스는 각각 장단점이 있습니다.
프로덕션 환경에서는 NAT Gateway가, 비용이 중요한 환경에서는 NAT 인스턴스가 적합합니다. 상황에 맞게 선택하는 것이 중요합니다.
실전 팁
💡 - 프로덕션 환경에서는 대부분 NAT Gateway를 권장합니다
- 개발/테스트 환경에서 비용을 절약하려면 NAT 인스턴스를 고려하세요
- NAT 인스턴스를 사용한다면 Source/Destination Check를 반드시 비활성화해야 합니다
5. 비용 고려사항
월말이 되자 김개발 씨는 AWS 비용 리포트를 받았습니다. NAT Gateway 항목을 보니 예상보다 많은 비용이 청구되어 있었습니다.
당황한 김개발 씨는 박시니어 씨를 찾아갔습니다. "NAT Gateway가 이렇게 비쌀 줄 몰랐어요!"
NAT Gateway 비용은 시간당 요금과 데이터 처리 요금으로 구성됩니다. 24시간 운영 시 월 고정 비용이 발생하고, 처리한 데이터량에 따라 추가 요금이 부과됩니다.
비용을 절감하려면 불필요한 NAT Gateway 삭제, 트래픽 최적화, VPC 엔드포인트 활용 등의 방법을 고려해야 합니다.
다음 코드를 살펴봅시다.
# NAT Gateway 비용 계산 및 최적화
# 비용 구조 (서울 리전 기준, 2024년)
NAT_GATEWAY_HOURLY = 0.059 # 시간당 USD
DATA_PROCESSING_PER_GB = 0.059 # GB당 USD
# 월간 비용 계산
def calculate_monthly_cost(hours_per_month, data_gb_per_month):
"""NAT Gateway 월간 비용 계산"""
# 시간당 요금
hourly_cost = NAT_GATEWAY_HOURLY * hours_per_month
# 데이터 처리 요금
data_cost = DATA_PROCESSING_PER_GB * data_gb_per_month
total_cost = hourly_cost + data_cost
return {
'hourly_cost_usd': round(hourly_cost, 2),
'data_cost_usd': round(data_cost, 2),
'total_usd': round(total_cost, 2),
'total_krw': round(total_cost * 1300, 0) # 환율 1,300원 가정
}
# 예시: 24/7 운영, 월 1TB 처리
result = calculate_monthly_cost(
hours_per_month=730, # 30일 기준
data_gb_per_month=1000 # 1TB
)
print(f"시간당 요금: ${result['hourly_cost_usd']}")
print(f"데이터 처리 요금: ${result['data_cost_usd']}")
print(f"총 비용: ${result['total_usd']} (약 {result['total_krw']:,}원)")
# 비용 절감 체크리스트
print("\n비용 절감 방법:")
print("1. VPC Endpoint 사용 (S3, DynamoDB)")
print("2. 불필요한 NAT Gateway 삭제")
print("3. 트래픽 모니터링 및 최적화")
박시니어 씨가 비용 리포트를 보더니 고개를 끄덕였습니다. "NAT Gateway는 편리하지만 확실히 비용이 만만치 않죠.
비용 구조를 정확히 이해해야 최적화할 수 있어요." NAT Gateway의 비용은 크게 두 가지로 나뉩니다. 첫째는 시간당 요금입니다.
NAT Gateway가 존재하는 시간만큼 요금이 부과됩니다. 트래픽이 없어도 NAT Gateway가 켜져 있기만 하면 시간당 요금이 나갑니다.
서울 리전 기준 시간당 약 0.059 달러입니다. 한 달을 30일로 계산하면 730시간입니다.
0.059 × 730 = 약 43달러입니다. 환율을 1,300원으로 계산하면 월 56,000원 정도가 고정 비용으로 나갑니다.
NAT Gateway를 3개 사용한다면? 월 17만 원이 기본으로 청구됩니다.
둘째는 데이터 처리 요금입니다. NAT Gateway를 통과한 데이터량에 따라 GB당 요금이 부과됩니다.
서울 리전 기준 GB당 약 0.059 달러입니다. 만약 한 달에 1TB의 데이터를 NAT Gateway를 통해 처리했다면?
1,000GB × 0.059 = 약 59달러, 한화로 약 77,000원이 추가됩니다. 고정 비용 56,000원과 합치면 월 13만 원이 넘습니다.
김개발 씨가 놀라며 말했습니다. "생각보다 훨씬 비싸네요!" 박시니어 씨가 대답했습니다.
"맞아요. 그래서 비용 최적화가 중요해요." 비용을 줄이는 방법은 무엇이 있을까요?
첫 번째 방법은 VPC 엔드포인트 사용입니다. AWS의 여러 서비스들은 VPC 엔드포인트를 지원합니다.
S3, DynamoDB, CloudWatch 등이 대표적입니다. VPC 엔드포인트를 사용하면 이 서비스들에 접근할 때 NAT Gateway를 거치지 않고 AWS 내부 네트워크를 통해 직접 연결됩니다.
예를 들어 Private Subnet의 인스턴스가 S3에서 매일 100GB의 데이터를 다운로드한다고 합시다. NAT Gateway를 사용하면 이 100GB에 대한 처리 요금이 부과됩니다.
한 달이면 3,000GB, 비용은 약 177달러입니다. 하지만 S3 VPC 엔드포인트를 생성하면?
S3 트래픽이 NAT Gateway를 거치지 않으므로 이 비용이 0원이 됩니다. S3 Gateway 엔드포인트는 시간당 요금도 없고 데이터 처리 요금도 없습니다.
완전히 무료입니다. 두 번째 방법은 불필요한 NAT Gateway 삭제입니다.
개발 환경에서 테스트용으로 NAT Gateway를 만들고 잊어버리는 경우가 많습니다. 사용하지 않아도 시간당 요금은 계속 나갑니다.
정기적으로 NAT Gateway 목록을 검토하고, 쓰지 않는 것은 삭제해야 합니다. 또한 각 가용 영역마다 NAT Gateway를 만들 필요가 있는지 고려해야 합니다.
고가용성이 중요한 프로덕션 환경이라면 각 AZ마다 NAT Gateway를 두는 것이 맞지만, 개발 환경이라면 하나만 사용하는 것도 방법입니다. 세 번째 방법은 트래픽 최적화입니다.
어떤 트래픽이 NAT Gateway를 많이 사용하는지 모니터링해야 합니다. CloudWatch를 이용하여 NAT Gateway의 BytesOutToDestination 메트릭을 확인할 수 있습니다.
불필요한 외부 API 호출을 줄이거나, 캐싱을 도입하여 반복적인 요청을 줄일 수 있습니다. 네 번째 방법은 개발 환경에서 NAT 인스턴스 사용입니다.
앞서 말했듯이 개발이나 테스트 환경에서는 NAT 인스턴스를 고려할 수 있습니다. t3.nano 인스턴스를 사용하면 월 5,000원 정도로 NAT 기능을 제공할 수 있습니다.
NAT Gateway의 10분의 1 비용입니다. 실제 사례를 보겠습니다.
어느 스타트업이 3개의 가용 영역에 각각 NAT Gateway를 두고 있었습니다. 월 AWS 비용을 분석해보니 NAT Gateway만 40만 원이 나오고 있었습니다.
이들은 다음과 같은 최적화를 했습니다.
3. 불필요한 외부 API 호출을 캐싱으로 줄임 → 트래픽 30% 감소
실전 팁
💡 - CloudWatch로 NAT Gateway의 데이터 처리량을 정기적으로 모니터링하세요
- S3, DynamoDB 등 지원되는 서비스는 VPC 엔드포인트를 적극 활용하세요
- 개발 환경에서는 NAT 인스턴스로 비용을 절감할 수 있습니다
6. 고가용성 구성
김개발 씨는 NAT Gateway를 하나 만들고 뿌듯해했습니다. 그런데 박시니어 씨가 아키텍처 다이어그램을 보더니 고개를 저었습니다.
"이러면 NAT Gateway가 있는 가용 영역에 장애가 나면 전체 서비스가 멈춰요. 고가용성 구성이 필요해요."
고가용성 NAT Gateway 구성은 각 가용 영역마다 별도의 NAT Gateway를 생성하는 것입니다. 각 Private Subnet은 같은 가용 영역에 있는 NAT Gateway를 사용하도록 라우팅 테이블을 구성합니다.
이렇게 하면 한 가용 영역에 장애가 발생해도 다른 영역은 정상 작동합니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 고가용성 NAT Gateway 구성
# 가용 영역마다 NAT Gateway 생성
availability_zones = ['ap-northeast-2a', 'ap-northeast-2c']
public_subnets = {
'ap-northeast-2a': 'subnet-pub-2a',
'ap-northeast-2c': 'subnet-pub-2c'
}
private_subnets = {
'ap-northeast-2a': 'subnet-pri-2a',
'ap-northeast-2c': 'subnet-pri-2c'
}
route_tables = {
'ap-northeast-2a': 'rtb-pri-2a',
'ap-northeast-2c': 'rtb-pri-2c'
}
nat_gateways = {}
for az in availability_zones:
# 1. Elastic IP 할당
eip = ec2.allocate_address(Domain='vpc')
# 2. NAT Gateway 생성
nat_gw = ec2.create_nat_gateway(
SubnetId=public_subnets[az],
AllocationId=eip['AllocationId'],
TagSpecifications=[{
'ResourceType': 'natgateway',
'Tags': [{'Key': 'Name', 'Value': f'NAT-{az}'}]
}]
)
nat_gateway_id = nat_gw['NatGateway']['NatGatewayId']
nat_gateways[az] = nat_gateway_id
# 3. Private Subnet 라우팅 테이블에 규칙 추가
ec2.create_route(
RouteTableId=route_tables[az],
DestinationCidrBlock='0.0.0.0/0',
NatGatewayId=nat_gateway_id
)
print(f"{az}: NAT Gateway {nat_gateway_id} 생성 완료")
print("\n고가용성 구성 완료!")
print("각 AZ의 Private Subnet은 같은 AZ의 NAT Gateway를 사용합니다.")
김개발 씨는 의아했습니다. "NAT Gateway 하나로는 부족한가요?" 박시니어 씨가 화이트보드에 그림을 그리며 설명하기 시작했습니다.
"AWS의 가용 영역은 물리적으로 분리된 데이터센터예요. 한 가용 영역에 정전이나 네트워크 장애가 발생해도 다른 가용 영역은 영향을 받지 않도록 설계되어 있죠." 그렇다면 NAT Gateway는 어떨까요?
NAT Gateway는 특정 가용 영역에 생성됩니다. 예를 들어 ap-northeast-2a 영역의 Public Subnet에 NAT Gateway를 만들면, 그 NAT Gateway도 2a 영역에만 존재합니다.
만약 모든 Private Subnet이 이 하나의 NAT Gateway를 사용한다면 어떻게 될까요? 2a 영역에 장애가 발생하면 NAT Gateway도 사용할 수 없게 됩니다.
그러면 2c 영역의 Private Subnet도 인터넷에 접근할 수 없게 됩니다. 한 영역의 장애가 전체 서비스에 영향을 미치는 것입니다.
바로 이런 문제를 방지하기 위해 고가용성 구성이 필요합니다. 고가용성 NAT Gateway 구성의 원칙은 간단합니다.
각 가용 영역마다 NAT Gateway를 하나씩 만들고, 각 Private Subnet은 같은 가용 영역에 있는 NAT Gateway를 사용하도록 라우팅하는 것입니다. 위의 코드를 살펴보겠습니다.
두 개의 가용 영역(2a, 2c)에 대해 반복문을 실행합니다. 각 영역마다 다음 작업을 수행합니다.
첫째, Elastic IP를 할당받습니다. 각 NAT Gateway는 독립적인 Public IP가 필요하므로, 영역마다 별도의 EIP를 할당받아야 합니다.
둘째, 해당 영역의 Public Subnet에 NAT Gateway를 생성합니다. 2a 영역의 NAT Gateway는 2a의 Public Subnet에, 2c 영역의 NAT Gateway는 2c의 Public Subnet에 생성됩니다.
셋째, 해당 영역의 Private Subnet 라우팅 테이블에 인터넷 트래픽 규칙을 추가합니다. 중요한 점은 2a의 Private Subnet은 2a의 NAT Gateway를, 2c의 Private Subnet은 2c의 NAT Gateway를 사용한다는 것입니다.
이렇게 구성하면 어떤 이점이 있을까요? 장애 격리가 가능합니다.
만약 2a 영역에 장애가 발생하면, 2a의 NAT Gateway와 그 영역의 인스턴스들은 영향을 받습니다. 하지만 2c 영역은 자체 NAT Gateway를 사용하므로 계속 정상 작동합니다.
전체 서비스의 50%는 유지되는 것입니다. 또한 네트워크 지연도 줄어듭니다.
같은 가용 영역 내에서 통신하므로, 다른 영역의 NAT Gateway를 사용하는 것보다 빠릅니다. 비록 몇 밀리초 차이지만, 대량의 트래픽을 처리할 때는 의미가 있습니다.
실제 프로덕션 아키텍처를 보겠습니다. 전형적인 3-tier 웹 애플리케이션을 구축한다고 합시다.
두 개의 가용 영역을 사용하여 다음과 같이 구성합니다. AZ-2a: - Public Subnet: ALB, NAT Gateway - Private Subnet: 애플리케이션 서버, 데이터베이스 AZ-2c: - Public Subnet: ALB, NAT Gateway - Private Subnet: 애플리케이션 서버, 데이터베이스 각 영역의 Private Subnet은 같은 영역의 NAT Gateway를 사용하도록 라우팅 테이블을 설정합니다.
이렇게 하면 한 영역 전체가 다운되어도 다른 영역에서 서비스를 계속할 수 있습니다. 주의할 점이 있습니다.
고가용성 구성은 비용이 두 배가 됩니다. NAT Gateway를 2개 운영하므로 시간당 요금도 두 배, 데이터 처리 요금도 영역마다 부과됩니다.
따라서 서비스의 중요도를 고려하여 결정해야 합니다. 프로덕션 환경에서는 대부분 고가용성 구성을 권장합니다.
하지만 개발이나 테스트 환경에서는 비용 절감을 위해 하나의 NAT Gateway만 사용하는 것도 합리적입니다. 개발 환경에서 잠깐 인터넷이 안 되는 것은 큰 문제가 아니기 때문입니다.
또 하나 주의할 점은 교차 영역 트래픽입니다. 만약 Private Subnet이 다른 영역의 NAT Gateway를 사용하도록 설정하면, 교차 영역 데이터 전송 비용이 발생합니다.
반드시 같은 영역끼리 매칭해야 합니다. 김개발 씨가 이해했다는 듯 고개를 끄덕였습니다.
"아, 가용 영역마다 독립적인 NAT Gateway를 두는 거군요. 그래야 장애 격리가 되는구나." 박시니어 씨가 만족스러운 표정으로 말했습니다.
"맞아요. AWS는 이런 고가용성 아키텍처를 권장해요.
Multi-AZ 구성이 AWS 설계의 기본이죠." 김개발 씨는 코드를 실행하여 두 개의 NAT Gateway를 생성하고, 각 Private Subnet의 라우팅 테이블을 수정했습니다. 이제 한 영역에 장애가 나더라도 서비스는 계속될 것입니다.
고가용성 NAT Gateway 구성은 AWS 아키텍처의 핵심입니다. 각 가용 영역마다 독립적인 NAT Gateway를 두어 장애를 격리하고, 서비스 연속성을 보장할 수 있습니다.
비용은 늘어나지만, 중요한 서비스라면 반드시 고려해야 하는 설계입니다.
실전 팁
💡 - 프로덕션 환경에서는 최소 2개의 가용 영역에 NAT Gateway를 배치하세요
- 각 Private Subnet은 반드시 같은 가용 영역의 NAT Gateway를 사용하도록 라우팅하세요
- 개발 환경에서는 비용 절감을 위해 단일 NAT Gateway를 고려할 수 있습니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
Spring Cloud Gateway 완벽 가이드
MSA 환경에서 필수적인 API Gateway 패턴을 Spring Cloud Gateway로 구현하는 방법을 배웁니다. 라우팅, 필터, Predicate 등 핵심 개념을 실무 예제와 함께 쉽게 설명합니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.