cloudwithbass

[AWS] NAT Instance로 AWS 요금을 줄여보자 본문

AWS

[AWS] NAT Instance로 AWS 요금을 줄여보자

여영클 2024. 12. 19. 22:51

이 포스팅에선 최근 진행한 프로젝트에 NAT Instance를 도입한 과정을 작성했습니다.

목차


    1. NAT Instance 도입 배경

    최근 프로젝트를 진행하며 AWS에 서비스를 배포했습니다.

    프로젝트에서 알게 된 사실 중 하나는 NAT Gateway의 사용료가 꽤 비싸다는 점입니다.

    NAT Gateway의 사용료는 시간 당 $0.059이기 때문에 한 달 내내 사용 시 약 $42.5가 부과됩니다. (+ 트래픽에 따른 비용 청구)

    이는 1달러 당 1451원인 현재 환율로 약 61,600원이기 때문에 꽤 부담되는 금액입니다. 

     

    저 또한 과거에 테라폼을 공부하며 필요할 때만 사용했는데도 NAT에 30달러를 지불한 경험이 있습니다..

     

    서비스는 중단되어선 안 되며, 보안을 위해 Private subnet을 반드시 사용해야 합니다. 따라서 Piravte subnet에서 인터넷으로 트래픽을 전달할 수단 또한 반드시 필요합니다.

     

    저는 NAT Gateway의 비용 최적화 방안을 찾아봤고, 그 결과 저희 서비스에 NAT Instance를 사용할 수 있겠다고 생각했습니다.


     

    2. NAT Gateway vs NAT Instance

    이 내용은 아래 AWS 문서에 굉장히 자세히 정리되어 있습니다. 따라서 주요 차이점만을 작성하겠습니다.

    https://docs.aws.amazon.com/ko_kr/vpc/latest/userguide/vpc-nat-comparison.html

     

    NAT 게이트웨이 및 NAT 인스턴스 비교 - Amazon Virtual Private Cloud

    NAT 게이트웨이 및 NAT 인스턴스 비교 NAT 인스턴스와 NAT 게이트웨이의 차이점을 세부적으로 요약하면 다음과 같습니다. NAT 게이트웨이는 더 나은 가용성과 대역폭을 제공하고 관리에 소요되는 작

    docs.aws.amazon.com

     

    주요 차이점

    NAT Gateway: 고가용성이며, AWS 관리형 인스턴스입니다. 최대 100Gbps 대역폭까지 확장합니다.

    NAT Instance: 스크립트로 장애를 조치해야 하며, 사용자가 유지관리해야 합니다. EC2로 구현하기 때문에 EC2 인스턴스의 사용료를 지불합니다. 또한 bastion으로 사용이 가능합니다.

     

    AWS에선 NAT Gateway 사용을 권장하므로 2023년 12월 31일에 NAT AMI 유지관리 지원을 종료했습니다. (관련 문서)

     

     

    따라서 NAT Instance를 사용하기 위해선 자체 관리형의 NAT AMI가 필요합니다. 제 경우 NAT Instance가 하나만 필요해서 AMI까지 만들진 않았습니다.

     

    저의 프로젝트의 경우 적은 수의 사용자가 예상되므로 높은 수준의 가용성과 대역폭은 필요하지 않습니다. 오히려 트러블 슈팅 경험을 위해 서버가 다운되길 바랍니다.

    또한 가난한 취업 준비생 6명이서 진행한 프로젝트이기 때문에 비용을 최우선으로 고려해서 아키텍처를 설계해야 합니다.

    그래서 NAT Gateway보단 NAT Instance가 적합하다고 생각했습니다.


    3. NAT Instance 구성하기

    3-1. EC2 인스턴스 생성

    먼저 NAT Instaance로서 동작할 ec2 인스턴스를 생성합니다.

    인터넷으로 패킷을 전달해야 하니 당연히 Public Subnet에 생성해야 하며, Private subnet에서 들어오는 트래픽을 허용해야 합니다.

     


    3-2. 패킷 포워딩 활성화

    NAT Instance Flow Chart (https://docs.aws.amazon.com/ko_kr/vpc/latest/userguide/VPC_NAT_Instance.html)

    위 사진처럼 NAT Instance는 Private subnet의 패킷을 Internet Gateway로 전달하는 역할을 합니다. 이러한 동작을 패킷 포워딩이라고 합니다. 패킷 포워딩 기능은 기본적으로 비활성화 되어 있으므로 이를 활성화해야 합니다.

     

    /proc/sys/net/ipv4/ip_forward 파일을 확인하면 0으로 설정되어 있을 것입니다.

    이 파일의 내용이 0이면 패킷 포워딩을 비활성화, 1이면 활성화합니다.

     

    /etc/sysctl.conf 파일에서아래 net.ipv4.ip_forward=1 부분을 주석 해제합니다. 

    /etc/sysctl.conf 파일은 리눅스에서 커널 관련 설정을 정의한 파일입니다.

     

    그리고 sudo sysctl -p 명령을 실행합니다.

    이 명령은 /etc/sysctl.conf의 내용을 영구적으로 저장합니다. 

     


    3-3. 마스커레이드 활성화

    마스커레이드는 네트워크 내부의 IP들을 네트워크 외부의 공인 IP로 변환하는 기술입니다. 즉, NAT Gateway와 같은 역할을 합니다.

     

    우선 ip link show 명령으로 인스턴스의 네트워크 인터페이스를 확인합니다.

    제 경우 lo와 enX0을 응답합니다.

     

    1: lo는 루프백을 의미하며, 자기 자신과 통신하기 위한 네트워크 인터페이스입니다. 대표적으로 로컬호스트의 ip인 127.0.0.1이 루프백 인터페이스의 ip 주소입니다.

    2: enX0은 외부 네트워크와 통신하기 위한 네트워크 인터페이스입니다.

    사실 저도 구글링을 해서 알아낸 내용이고, 이 응답 내용만 보고 어떤 역할을 하는 지 구분하는 건 아직 어렵네요..

     

    아무튼, 네트워크 인터페이스를 확인했으니 iptables 명령으로 이 인터페이스에 대한 마스커레이드 규칙을 추가합니다.

    sudo iptables -t nat -A POSTROUTING -o enX0 -j MASQUERADE

    -t nat: NAT 라우팅 테이블에 적용합니다. (nat 외 mangle, filter 등의 테이블도 있습니다.)

    -A POSTROUTING: post routing 체인에 새 규칙을 추가합니다. post routinig 체인은 네트워크 인터페이스를 나간 직후에 적용됩니다. 네트워크 내부의 IP를 인터페이스를 거친 후 외부 IP로 변환해야 하기 때문입니다.

    -o enX0: 이 규칙을 어떤 인터페이스에서 나가는 패킷에 적용할 지 지정합니다. 외부 네트워크로 나가는 인터페이스는 enX0임을 확인했으니 이 인터페이스를 지정합니다.

    -j MASQUERADE: 마스커레이드 동작을 수행하라고 지정합니다.

     

     

    이제 sudo iptables -t nat -L 명령을 통해 테이블 내용을 리스트로 출력합니다.

     

    POSTROUTING에 마스커레이드 규칙이 추가된 것을 확인했다면 iptables-save 명령으로 저장합니다.


    4. 소스/대상 확인 비활성화

    각각의 EC2 인스턴스는 기본적으로 원본/대상 확인을 수행합니다. 즉, 인스턴스 자기 자신으로부터 나가거나(원본) 자기 자신에게 온(대상) 패킷만을 처리합니다.

    하지만 NAT 인스턴스는 자신의 대상이 아니므로 이런 동작을 비활성화해야 합니다.

    참고 문서: https://docs.aws.amazon.com/ko_kr/vpc/latest/userguide/work-with-nat-instances.html#EIP_Disable_SrcDestCheck

     

     

    AWS 콘솔에서 NAT 인스턴스를 선택 후 작업 -> 네트워킹 -> 소스/대상 확인 변경을 클릭합니다.

     

    중지를 누른 후 저장합니다.

     

    이제 NAT Instance의 설정을 마쳤습니다.

    마지막으로 Private subnet의 라우팅 테이블에서 기존 NAT Gateway를 향하던 라우팅 규칙을 NAT Instance로 향하게 해줍시다.

     

    Piravte subnet 내 인스턴스에서 성공적으로 인터넷에 ping 명령이 가능합니다.

    혹시 public과 private 간 ping이 안 된다면 보안 그룹의 인바운드에서 ICMP를 허용했는지, 서로의 서브넷에서 온 트래픽을 허용했는지 점검해 보시길 바랍니다.

     


     

    저는 현재 프리 티어 계정을 사용 중이고, NAT Instance로 t2.micro 유형의 인스턴스를 사용했으니 nat instance의 유지비는 없습니다.

    제가 매달 저희 팀의 61,000원을 아껴주었습니다 ㅎㅎ 기분이 좋네요 

     

    AWS SAA 시험을 공부할 때 NAT Instance는 depreacted 되었기 때문에 무작정 안 좋다고만 나와서 저도 부정적으로 생각했는데 NAT Instance가 더 좋은 경우도 있군요.

    역시 이론과 실무는 다른 듯싶습니다.


     

    참고 블로그: 마스커레이드 설정 시 네트워크 인터페이스로 eth0을 사용한다는 점 외에 저의 내용과 같습니다.

    https://coding-groot.tistory.com/169

     

    [AWS] VPC의 NAT 비용을 줄여보자 :: Ubuntu로 NAT 인스턴스 만들기

    두 배가 되어버린 AWS 비용.. 1달 전에는 테스트용으로 그냥 Public IP로 다 통신하도록 하고 최저 사양으로 다 올렸었다. 하지만 보안이나 비용적인 측면, 나중에 할 부하 테스트를 생각해서 Amazon EC

    coding-groot.tistory.com