AWS NATゲートウェイの「沈黙のパケットドロップ」を回避せよ:スケーリング仕様とマイクロバースト対策の極意
SREの現場でよく聞く悲鳴があります。「なぜか特定の時間帯だけ、APIのレイテンシが跳ね上がる」「パケットロスが発生しているのに、ログには明確なエラーが残らない」。
その犯人が、実はAWSの NAT Gateway であるケースは少なくありません。AWSのドキュメントには「自動的にスケーリングする」と書かれていますが、その「自動」という言葉を過信すると、大規模トラフィックの洗礼を受けることになります。今日は、NATゲートウェイの裏側にある「5Gbpsから45Gbpsへの動的スケーリング」の現実と、現場でパケットを捨てさせないための設計指針について解説します。
—
NATゲートウェイの「自動スケーリング」という名の時差
まず、大前提を共有しましょう。AWSの NAT Gateway は、「トラフィックに応じて自動的に帯域幅をスケールする」という仕様です。
- 初期状態: 5Gbpsの帯域幅
- 最大値: 45Gbpsまで拡張可能
ここで重要なのは、このスケールアップが「即座」に行われるわけではないという点です。公式には「トラフィックが急増した際に、最大45Gbpsまで段階的にスケールする」とされていますが、現場の実感値としては、急激なバーストには追従できないケースが多々あります。
特に、数分間でトラフィックが5Gbpsを超えて跳ね上がるような「マイクロバースト」が発生した場合、NATゲートウェイは処理しきれないパケットを無情にも破棄(ドロップ)します。TCP通信であれば再送制御(Retransmission)が働きますが、レイテンシは劇的に悪化し、クライアント側では ETIMEDOUT や Connection reset by peer が多発する地獄絵図となります。
—
なぜパケットがドロップするのか?
NATゲートウェイでのボトルネックを理解するには、以下の3つの制約を把握しておく必要があります。
1. 帯域幅の制限: 前述の5Gbps〜45Gbpsの制限。
2. 接続数(ポート)の枯渇: NAT Gateway 1つにつき、送信先IP/ポートごとに最大64,512の同時接続が可能です。これを超えると、新しい通信が拒否されます。
3. PPS(Packet Per Second)の制限: 帯域幅に余裕があっても、小さなパケットが大量に押し寄せると、NATゲートウェイのCPU(内部処理)が追いつかずにドロップします。
—
現場で使える「予防的設計」とデバッグ手順
1. CloudWatch メトリクスによる監視の徹底
まずは何が起きているかを知ることから始まります。以下のメトリクスをダッシュボードに常駐させてください。
ErrorPortAllocation: ポート枯渇を示すバロメーター。ErrorDropCount: NATゲートウェイが処理しきれずに捨てたパケット数。BytesOutToInternet: 帯域の利用率を確認。
特に ErrorDropCount が0より大きい場合は、即座に設計見直しが必要です。
2. トラフィックの分散(複数AZ配置)
AWSのベストプラクティスは、各アベイラビリティーゾーン(AZ)ごとに NAT Gateway を配置することです。単一の NAT Gateway に負荷を集中させるのではなく、トラフィックを分散させることで、個々のゲートウェイが抱える帯域制限のリスクを下げます。
3. クライアント側の接続再利用(Keep-Alive)
アプリケーション側で接続の都度 TCP Handshake を行うのは、NATゲートウェイにとっても過酷な負荷です。HTTP Keep-Alive を有効にし、コネクションプールを適切に管理しましょう。
Python (requests) でのコネクションプール例:
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# セッションを再利用してコネクションプールを保持する
session = requests.Session()
# リトライ設定を追加して、一時的なパケットドロップをケアする
retry = Retry(total=3, backoff_factor=0.1)
adapter = HTTPAdapter(pool_connections=100, pool_maxsize=100, max_retries=retry)
session.mount('https://', adapter)
# これによりTCP接続を使い回し、NAT Gatewayのポート枯渇を抑制する
response = session.get('https://api.example.com/data')
4. そもそもNATゲートウェイを通さないという選択肢
もし、通信先が S3 や DynamoDB であるならば、NAT Gateway を通すのはコストとパフォーマンスの無駄です。必ず VPC Endpoint (Gateway型) を利用してください。これにより、パブリックな経路を介さずにAWSネットワーク内で完結するため、帯域制限の影響を一切受けません。
—
まとめ:トラブルを未然に防ぐために
NATゲートウェイは「魔法の箱」ではありません。以下の指針を常に意識してください。
- 予測可能なバーストにはスケールしない: 突発的なアクセス増を見越して、事前負荷試験を実施すること。
- ポート枯渇を甘く見ない:
NAT Gatewayの設計上の制限を理解し、コネクションプールを最適化する。 - 出口を分ける: インターネットへ出る通信と、AWS内サービスへの通信を
VPC Endpointで分離する。
インフラは「なんとなく動いている」ときが一番危険です。パケットがどこを通り、どこで詰まる可能性があるのか。その地図を頭の中に描きながら、堅牢なシステムを構築していきましょう。皆さんのサービスが、突発的なトラフィックにも動じない強靭な基盤の上に成り立つことを願っています。
コメント