Published on

VPC NAT Gateway 비용 폭증 10분 진단·절감

Authors

서버 비용은 대체로 서서히 오르지만, VPC NAT Gateway는 어느 날 갑자기 청구서가 ‘점프’하는 대표 항목입니다. 이유는 단순합니다. NAT는 시간당(게이트웨이 시간)처리 데이터(GB당) 두 축으로 과금되는데, 애플리케이션 변경·배포·로그/메트릭 설정 변경·엔드포인트 경로 하나만 바뀌어도 대량의 아웃바운드가 한 지점(NAT)으로 몰리기 때문입니다.

이 글은 “원인 분석에 하루를 쓰지 않고” 10분 안에 폭증 원인을 특정하고, 바로 적용 가능한 **절감 레버(경로 변경/엔드포인트 추가/캐시/아키텍처 분리)**를 제시합니다.

0) NAT Gateway 과금 구조부터 30초 정리

NAT Gateway 비용은 보통 아래 3가지로 폭증합니다.

  1. NAT Gateway Hourly: NAT를 AZ별로 두면 AZ 수만큼 시간당 과금이 누적
  2. NAT Data Processing (GB): 사설 서브넷 인스턴스가 인터넷/공개 AWS 서비스로 나가는 바이트가 모두 과금
  3. 추가 전송 비용: AZ 크로스(다른 AZ의 NAT 사용) 또는 VPC 간 트래픽 구조에 따라 전송비가 붙을 수 있음

즉, “NAT가 많아졌거나(시간당)” 혹은 “NAT를 통과하는 바이트가 늘었거나(GB당)” 둘 중 하나입니다.

1) 10분 진단 플로우(가장 빠른 순서)

아래 순서대로 보면, 대부분 10분 내에 범인이 잡힙니다.

1-1. Cost Explorer에서 ‘NAT Data Processing’ 급증 여부 확인(2분)

  • Cost Explorer → 서비스: Amazon VPC
  • Usage type 그룹핑에서 다음 키워드를 찾습니다.
    • NatGateway-Hours
    • NatGateway-Bytes / NATGateway-DataProcessing-Bytes (계정/리전 표기 차이 가능)

판단

  • Hours가 늘면: NAT 개수 증가, AZ별 NAT 추가, 테스트용 NAT 미삭제가 1순위
  • Bytes가 늘면: 트래픽 경로/대상 서비스가 바뀐 것

1-2. CloudWatch NAT Gateway 지표로 ‘언제부터’와 ‘얼마나’(2분)

NAT Gateway는 CloudWatch에 핵심 지표를 제공합니다.

  • BytesOutToDestination, BytesInFromDestination
  • ActiveConnectionCount, ConnectionAttemptCount

: 비용 폭증 시작 시각을 잡으면, 그 시각의 배포/배치/스케줄러/로그 설정 변경과 바로 매칭됩니다.

1-3. VPC Flow Logs로 “누가/어디로”를 1차 특정(4분)

NAT 비용의 실질 원인은 어떤 사설 리소스가 어떤 목적지로 나가느냐입니다. Flow Logs를 켜면 소스 ENI/서브넷/인스턴스까지 좁힐 수 있습니다.

  • VPC 또는 서브넷 레벨 Flow Logs 활성화
  • Destination(목적지) IP/포트, Source(소스) ENI/주소 기준으로 상위 트래픽을 집계

CloudWatch Logs 비용도 같이 튈 수 있으니(Flow Logs 자체가 로그) 로그 비용 급증도 함께 점검하는 게 좋습니다. 관련해서는 CloudWatch Logs 비용 폭증 원인과 절감 10가지도 같이 보세요.

1-4. “AWS 서비스인데 NAT를 타고 있나?”를 즉시 확인(2분)

가장 흔한 케이스는 이겁니다.

  • S3, ECR, CloudWatch, STS, KMS, Secrets Manager 등 AWS 서비스 호출이 NAT를 경유
  • 원래는 VPC Endpoint로 빠져야 하는데, 엔드포인트가 없거나 라우팅/DNS 설정이 어긋남

이 경우는 VPC Endpoint 추가만으로 NAT Data Processing을 크게 줄일 수 있습니다.

2) NAT 비용 폭증 ‘대표 원인’ 7가지와 즉시 대응

2-1. S3 다운로드/업로드가 NAT로 나감(가장 흔함)

증상

  • 배치/ETL, 모델 다운로드, 아티팩트 업로드가 늘면서 NatGateway-Bytes 급증

대응

  • S3 Gateway Endpoint 추가(가장 강력)
  • S3 접근이 특정 버킷 위주면 Endpoint policy로 범위 제한

2-2. ECR 이미지 풀/푸시가 NAT로 나감(ECS/EKS에서 자주 발생)

증상

  • 배포 횟수 증가, 노드 스케일 아웃으로 이미지 풀 트래픽 폭발

대응

  • ECR Interface Endpoint(api, dkr) + S3 Gateway Endpoint(레이어 전송이 S3를 쓰는 케이스가 많음)
  • 노드 로컬 캐시/이미지 프리풀 전략

2-3. CloudWatch Logs/Metric/OTel Exporter가 NAT를 태움

증상

  • 로깅 레벨 변경, 샘플링 해제, 디버그 로그 증가 직후 NAT 바이트 폭증

대응

  • CloudWatch Logs/Monitoring 관련 Interface Endpoint 고려
  • 애플리케이션 로그 샘플링/버퍼링/전송 주기 조정

2-4. 외부 API 호출(결제/지도/LLM 등) 폭증

증상

  • 특정 마이크로서비스가 외부로 대량 호출 → NAT 집중

대응

  • 캐시(CloudFront/ElastiCache) 또는 응답 재사용
  • 동시성 제한, 재시도 정책 점검(무한 재시도는 NAT를 태웁니다)
  • 타임아웃/재시도 설계는 Python httpx ReadTimeout·ConnectError 재시도 설계 같은 원칙을 적용해 “폭주형 재시도”를 제거

2-5. AZ 크로스 NAT(다른 AZ의 NAT로 라우팅)

증상

  • NAT는 1개인데 서브넷은 여러 AZ → 일부는 다른 AZ NAT로 나감
  • 전송비(크로스 AZ) + NAT 바이트가 함께 증가

대응

  • AZ별 NAT Gateway를 두고 각 프라이빗 서브넷이 같은 AZ NAT를 사용하도록 라우트 테이블 분리
  • 반대로 “시간당 비용”이 부담이면, 트래픽 패턴에 따라 단일 NAT + 크로스 비용을 비교(정답은 트래픽에 따라 다름)

2-6. IPv6 경로 미사용(IPv4 NAT 강제)

증상

  • 외부 목적지가 IPv6 지원인데도 IPv4만 사용 → NAT 필수

대응

  • 가능하면 Dual-stack(IPv4/IPv6) 로 전환하고, IPv6는 Egress-Only Internet Gateway 경로를 검토(워크로드/보안정책에 따라 적용)

2-7. 프록시/에이전트가 대량 업로드(로그/덤프/코어파일)

증상

  • 장애 덤프 업로드, 대형 파일 업로드가 반복

대응

  • 업로드 대상이 AWS라면 Endpoint로 전환
  • 업로드 크기/주기 제한, 압축, 청크 업로드 적용

3) “원인 특정”을 위한 VPC Flow Logs 쿼리 예시(CloudWatch Logs Insights)

Flow Logs를 CloudWatch Logs로 보낸 경우, 아래처럼 상위 송신자를 빠르게 찾을 수 있습니다.

fields @timestamp, interfaceId, srcAddr, dstAddr, dstPort, bytes, action
| filter action = "ACCEPT"
| stats sum(bytes) as total_bytes by srcAddr, dstAddr, dstPort
| sort total_bytes desc
| limit 20
  • srcAddr가 특정 프라이빗 IP 대역/인스턴스로 좁혀지면 해당 워크로드의 아웃바운드 설정(배포 시각, 크론, 스케일링)을 바로 추적합니다.
  • dstAddr가 AWS 퍼블릭 IP로 보이면(예: S3 퍼블릭 엔드포인트), 엔드포인트 미구성이 의심됩니다.

4) 즉시 절감 레버 6가지(효과 큰 순서)

4-1. VPC Endpoint를 먼저 깔아라(가장 ROI 큼)

  • S3: Gateway Endpoint
  • ECR/CloudWatch/STS/KMS/Secrets Manager 등: Interface Endpoint

Endpoint 적용 후에는 해당 서비스 트래픽이 NAT를 우회하는지(CloudWatch NAT Bytes 하락)로 검증합니다.

4-2. NAT를 ‘필요한 서브넷’에만 연결(라우트 테이블 최소화)

프라이빗 서브넷이라고 해서 모두 인터넷이 필요하지 않습니다.

  • DB 서브넷, 내부 전용 워커는 NAT 경로 제거
  • “기본 라우트(0.0.0.0/0)”가 NAT로 향하는 라우트 테이블이 과도하게 붙어 있는지 점검

4-3. 아웃바운드가 많은 워크로드를 퍼블릭 서브넷으로 옮길지 검토

보안팀 정책이 허용한다면,

  • 외부 호출이 많은 배치/크롤러는 퍼블릭 서브넷 + 보안그룹 제한 + 고정 EIP로 운영하는 편이 더 쌀 수 있습니다.
  • 단, 인바운드는 최소화하고, 아웃바운드만 필요할 때에 한합니다.

4-4. 캐시/미러링으로 “같은 다운로드”를 줄이기

  • 모델/아티팩트/패키지 다운로드는 S3/CloudFront 캐시, 내부 아티팩트 리포지토리(예: CodeArtifact, Nexus)로 전환
  • 컨테이너 이미지는 노드 풀에서 프리풀/캐시

4-5. 재시도/폴링/헬스체크 트래픽을 줄이기

NAT 바이트 폭증의 숨은 원인은 “정상 트래픽”이 아니라

  • 과도한 폴링
  • 실패 후 공격적인 재시도
  • 짧은 타임아웃으로 인한 반복 연결

입니다. 외부 API/프록시 타임아웃이 흔들리면 트래픽이 기하급수로 늘 수 있으니, 애플리케이션 레벨에서 재시도 상한과 지수 백오프를 강제하세요.

4-6. NAT Gateway 수/AZ 전략 재검토

  • 트래픽이 큰 서비스: AZ별 NAT로 크로스 AZ 전송비/지연 감소
  • 트래픽이 작고 NAT 시간당이 부담: 단일 NAT(단, 장애 허용/리스크 고려)

정답은 “가용성과 비용”의 트레이드오프입니다.

5) Terraform 예시: S3 Gateway Endpoint로 NAT 우회

아래는 S3 트래픽을 NAT 대신 VPC 내부로 돌리는 가장 전형적인 구성입니다.

resource "aws_vpc_endpoint" "s3" {
  vpc_id            = aws_vpc.main.id
  service_name      = "com.amazonaws.${var.region}.s3"
  vpc_endpoint_type = "Gateway"

  route_table_ids = [
    aws_route_table.private_a.id,
    aws_route_table.private_b.id
  ]

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect   = "Allow"
      Principal = "*"
      Action   = ["s3:GetObject", "s3:PutObject", "s3:ListBucket"]
      Resource = [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ]
    }]
  })
}

적용 후 검증:

  • NAT Gateway BytesOutToDestination가 유의미하게 감소
  • S3 요청이 정상 동작(특히 버킷 정책/엔드포인트 정책 충돌 여부)

6) 운영 체크리스트(재발 방지)

6-1. 알람

  • NAT BytesOutToDestination가 평소 대비 N배 증가 시 알람
  • Cost Anomaly Detection에서 Amazon VPC 비용 감시

6-2. 배포 파이프라인에 “엔드포인트/라우팅 변경 감지” 넣기

  • 새 워크로드가 S3/ECR/CloudWatch를 쓰면 VPC Endpoint 유무를 자동 점검
  • 프라이빗 서브넷에서 0.0.0.0/0 NAT 라우트가 추가되면 PR에서 경고

6-3. 로그/메트릭 폭주도 같이 본다

NAT 폭증과 CloudWatch Logs 폭증은 종종 같은 사건(로그 레벨 변경, exporter 설정 오류)에서 동시에 터집니다. 로그 비용 쪽도 함께 점검하면 원인 파악이 빨라집니다.

7) 10분 결론: 가장 많이 먹히는 ‘한 방’

  • NAT Bytes 폭증이면: 1) Flow Logs로 상위 송신자/목적지 식별 → 2) 대상이 AWS 서비스면 VPC Endpoint로 우회 → 3) 외부 API면 캐시/재시도/폴링을 줄여 트래픽 자체를 깎기
  • NAT Hours 폭증이면: NAT가 늘어난 이유(멀티 AZ, 테스트 리소스, 환경 분리)를 확인하고 불필요 NAT를 정리

NAT Gateway 비용은 “아키텍처가 잘못됐다”기보다, 대개 경로가 한 번 틀어진 결과입니다. 위 플로우대로 보면, 대부분은 라우팅/엔드포인트/로그 설정 중 하나에서 10분 안에 답이 나옵니다.