
예전에 운영되던 서비스 프로젝트에서 이상하게 과금이 나오는 달이 많았다.
분명 서비스 트래픽은 많지 않은데, NAT Gateway 만 유독 금액이 많이 나왔었다.
15일만 계산해보면, $20.43
NAT Gateway가 비싼 이유
처음 AWS 쓸 때는 NAT Gateway에 대해서
Private Subnet에서 인터넷 나가려면 NAT Gateway가 당연히 필요하겠지.
NAT Gateway의 요금 구조는
- 시간당 비용 (가만히 있어도 돈을 떼감.)
- 처리한 데이터량당 비용 (트래픽마다 차곡차곡 저장됨.)
즉, Lambda가 외부 API를 한 번 호출하면 NAT Gateway를 지나가면서 그 호출 하나하나가 비용으로 쌓이게 되는 것이다.
Private Subnet → AWS 외부 이런 구조로 NAT Gateway를 통과하기 때문에 나중에 진짜 막대한 비용이 나올 수도 있다.
NAT Instance로의 전환
이때 참고했던 글이 두 개 였다.
이 두 글에서 공통적으로 말하는 핵심은 트래픽이 적은 서비스에서는 NAT Instance가 훨씬 효율적이고 경제적이라는 것이다.
그래서 바로 NAT Gateway를 없애고 NAT Instance로 바꾸기로 결정했다.
왜 NAT Instance로?
NAT Gateway의 장점으로는,
- 관리 안해도 됨.
- 서버 장애가 나면 알아서 복구가 됨.
- 대역폭이 넓음.
NAT Gateway의 단점으로는,
- 가격이 너무 비쌈 (소규모 개발 환경에선 너무 과함.)
- 트래픽 적어도 고정비는 계속 나감
- Lambda + 외부 API 호출 많은 구조일수록 금액이 폭증하게 됨.
반대로, NAT Instance의 경우엔
장점으로는,
- 엄청 싸다.
- 프리티어 EC2 + iptables 조합이면 거의 0원에 가깝다.
- 내가 관리할 수 있으므로 필요에 따라 커스터마이징이 가능하다.
단점으로는,
- 서버 장애가 나면 직접 고쳐야 한다.
- Auto Scaling, Multi-AZ 같은 고가용성 직접 구성해야 함.
- EC2 네트워크 대역폭 제한이 있음.
즉, 프로덕션 대규모 서비스는 NAT Gateway, 개인 프로젝트 및 소규모 서비스에서는 NAT Instance라고 봐도 무방하다.
그래서 나는 트래픽 낮은 소규모 서비스였으므로 NAT Instance로 갈아탈 이유가 충분했다.
어떻게 바꿨는가
참고 글들에서 다룬 구성 방식과 AWS 문서를 참고하면서 VPC 구조를 직접 뜯어고쳤다.
1) VPC 구조 다시 설계
기존의 구조는 Lambda → Private Subnet → NAT Gateway → 인터넷 이런 식으로 모든 외부 호출이 NAT Gateway 비용으로 이어졌었다.
그래서 이 구조를
- Public Subnet → NAT Instance + ALB
- Private Subnet → Lambda, RDS
- Private Subnet Route → NAT Instance로 연결
2) NAT Instance 생성
t2.micro 프리티어로도 충분했다고 판단했다. Elastic IP 연결하고 방화벽 열고 iptables 설정을 해주었다.
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o eth0 MASQUERADE이게 NAT Gateway가 내부적으로 하는 SNAT 기능과 동일하다.
IP MASQUERADE는 뭐고 왜 필요한가?
Private Subnet 내부 리소스들은 10.x.x.x 같은 사설 IP를 이용하는데, 사설 IP는 인터넷으로 직접 나갈 수 없다.
그래서 NAT Instance가 대신 외부로 나가는 출구 역할을 해줘야 하는데, 이때 필요한 기능이 바로 IP Masquerade이다.
- 내부 리소스(예: 10.0.1.21)가 외부로 요청을 보냄.
- NAT Instance가 그 요청을 받아 자기 공인 IP로 바꿔서 외부 API에 전달
- 외부 서버는 NAT Instance의 공인 IP만 봄
- 응답이 오면 다시 내부 IP로 돌려보내줌.
즉, 외부에서 보면 내부 서버들의 IP는 전혀 보이지 않는다. Private Subnet 내부의 모든 요청은 NAT Instance의 공인 IP 하나에서 나가는 것처럼 보이기 때문에, NAT Instance는 말 그대로 모든 요청에 대해 "일종의 가면(Masquerade)" 역할을 하게 된다.
3) 라우팅 테이블 수정
0.0.0.0/0 → NAT Instance
Private Subnet이 NAT Gateway로 연결되던 걸 생성한 NAT Instance로 바꿔주었다. 바꾸고 Lambda에서 외부 API 호출 테스트를 해보니 성공적으로 잘 돌아갔다.
그러면 비용은 얼마나 줄었을까?
| 프리티어 EC2 기존 인스턴스 1개 | NAT 게이트웨이 사용 시 | NAT 인스턴스(t2.micro) 사용 시 |
|---|---|---|
| NAT 게이트웨이 한 달 요금 | $ 32.4 | $ 0 |
| NAT 인스턴스 한 달 요금 | $ 0 | 15일 무료 + $ 4.2 |
| 한 달 요금 | $ 32.4 | $ 4.2 |
무려 8배가 절약되었다.
직접 운영해야한다는 관리 부담이 있긴 하지만 비용 절감 측면에선 압도적인 차이였다.
정리
1) 클라우드는 기본값으로 쓰면 비싸다.
AWS는 대부분 서비스가 관리형이다. 그만큼 안정성과 편리함이 크지만, 비싸다.
내 서비스 규모엔 상당한 오버스펙이었고 비용도 훨씬 많이 나왔다.
2) 네트워크 원리가 이해되면 비용을 줄일 수 있다.
VPC, Subnet, 라우팅, NAT, ... 그냥 필요하다고 해서 만든 구성 요소들이 아니라, 왜 이런 구조로 설계를 해야하고, 그 구조가 비용에 어떤 영향을 주는 지를 볼 수 있게 되었다.
3) 운영은 결국 비용과의 싸움이다.
Lambda가 외부 API 한 번 부르면 NAT Gateway가 과금되고 그게 누적이 되면 한 달에 32달러 이상이 나온다.
설계 하나가 비용을 만든다는 걸 직접 경험으로 배웠다.
트래픽도 없는데 왜 32달러가 나왔는지, 구조를 뜯어보고 나서야 이해됐다.
NAT Gateway는 존재 자체로 과금된다. Lambda가 외부 API를 한 번 부를 때마다 그 경로 위에 있는 NAT Gateway가 돈을 가져간다. 설계가 비용을 만든다는 걸 직접 경험으로 배웠다.