こんにちは!SREとして日夜クラウドインフラの荒波と格闘している筆者です。
AWSのVPC(Virtual Private Cloud)を使い始めると、パブリックサブネットやプライベートサブネット、そしてインターネットゲートウェイといった仕組みにワクワクしますよね。「プライベートサブネットに置いた安全なサーバーから、どうやって安全に外のインターネットへ出ていくんだろう?」そんな疑問を持った方も多いのではないでしょうか。
そこで登場するのが、今回の主役である「NATゲートウェイ(NAT Gateway)」です。
一見すると、プライベートなサーバーの「おつかい代行」をしてくれる非常に頼もしい存在なのですが、大規模なシステムを運用し始めると、突然「なんだか外と通信できなくなったぞ!?」という不可解なトラブルに直面することがあります。その原因の多くが、今回深掘りする「ソースポート枯渇問題」です。
難解なパケットの仕組みやプロトコルの詳細な仕様書を開く前に、まずは私たちの身近な世界に置き換えて、この現象の正体を優しく紐解いていきましょう!一歩ずつ理解していけば、決して怖くありませんよ。
—
1. NATゲートウェイって、現実世界でたとえると?
プライベートサブネットにあるサーバー(たとえば、外のAPIと頻繁に通信するWebアプリなど)には、直接インターネット上の住所(グローバルIPアドレス)が割り当てられていません。セキュリティを保つためには当然の設計ですね。
しかし、このサーバーが「外部のAPIサーバーにデータを送りたい!」と言い出したとき、どうすればいいでしょうか? 宛先はインターネットの向こう側なので、プライベートな住所のままでは帰るに戻れません。
ここで登場するのがNATゲートウェイです。現実世界にたとえるなら、ここは「巨大なオフィスの外回り専用・郵便局の窓口」のような場所です。
- プライベートサーバーたち:オフィスの中で黙々とデスクワーク(社内処理)をしている社員たち。
- NATゲートウェイ(窓口):社員の代わりに外へ手紙を出しに行ってくれる、唯一の受付係。
社員(サーバー)たちが「この手紙を外の取引先に送って!」と窓口(NATゲートウェイ)に手紙を預けると、窓口の人は自分の住所(NATゲートウェイ自体のグローバルIPアドレス)を封筒の差出人に書き換えて、外のポストへ投函してくれます。そして、取引先から返事が返ってきたら、窓口の人が「あ、これはさっきの〇〇さんの手紙の返事だな」と気づいて、本人に手渡してくれるのです。
この「住所を書き換えて取り次ぐ」仕組みを、ネットワークの世界では PAT(Port Address Translation) と呼びます。
—
2. なぜ起こる?「ソースポート枯渇」の恐怖
さて、この窓口(NATゲートウェイ)の仕組み、平和なうちは全く問題ありません。しかし、会社が急成長して、社員(サーバー)たちが一斉に何万通もの手紙を外へ出し始めたらどうなるでしょうか?
ここで、窓口係の人が抱える「ある大きなお仕事ルール」が問題になってきます。
窓口係のメモ帳ルールとポートの限界
窓口係の人は、誰から預かった手紙の返事が、誰宛のものなのかを絶対に間違えてはいけません。そのため、外へ手紙を出すとき、自分の手元にある「整理券番号(これがネットワーク用語で言うソースポート番号です)」を封筒の差出人欄に書き込みます。
たとえば、
- 社員Aの手紙には「整理券番号:
10001」を振る - 社員Bの手紙には「整理券番号:
10002」を振る
といった具合です。この整理券番号は、1つのIPアドレスあたり、おおよそ 6万5千個 しか用意されていません(正確には 1 から 65535 までのポート番号です)。
5つの要素(5タプル)による制限の罠
さらに、AWSのNATゲートウェイには、通信先を管理する上で重要な仕様があります。それが「接続先(宛先IPアドレス・宛先ポート・プロトコル)ごと」に、使えるポートが割り振られるというルールです。
少し難しく聞こえますが、要するにこういうことです。
「同じ宛先のサーバーに対して同時に通信できるのは、最大で約 55,000 ポートまで」という厳密な制限が、1つのNATゲートウェイのIPアドレスあたりに存在します。
もし、あなたのシステムのプライベートサーバーたちが、一瞬のあいだに同じ外部の決済APIやクラウドサービスに対して、6万件を超える膨大な同時リクエストを送りつけたとしましょう。
するとどうなるでしょうか?
窓口係の持っている整理券(ポート)が、その宛先に対してすべて底をついてしまいます。これが、インフラエンジニアを震撼させる「ソースポート枯渇(Port Exhaustion)」の瞬間です。
新しく手紙を出そうとしても、窓口係は「あぁ、もう整理券がないから外に出せないよ!」と、通信エラー(Connection Timeout や Cannot assign requested address など)を叩き返してしまうのです。
—
3. 現場でどう防ぐ?実践的な対策と設定アプローチ
「じゃあ、大人気サービスを作ったら、いつか必ずこの壁にぶつかってしまうの?」と不安になりますよね。ご安心ください!SREやクラウドアーキテクトたちは、この限界を突破するためにいくつかの巧妙な手を用意しています。
実務の現場で直面した際に、そのまま参考にできるアプローチをいくつか見ていきましょう。
対策その1:接続の「使い回し」(コネクションプーリング)
一番の根本治療は、毎回新しい手紙(TCPコネクション)を新しく作ってすぐ捨てるような無駄な通信をなくすことです。
たとえば、アプリケーションコード(PythonやPHPなど)から外部APIへリクエストを送る際、HTTPクライアントのコネクションプーリング(Keep-Alive)を有効に設定し、既存の通信路を効率よく使い回します。
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# セッションを作成し、コネクションプールを有効化する
session = requests.Session()
# リトライ設定とプールサイズを適切にチューニング
retries = Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
adapter = HTTPAdapter(pool_connections=50, pool_maxsize=50, max_retries=retries)
session.mount('https://', adapter)
# これにより、同じ宛先への通信でポートを毎回消費し続けるのを防げます
response = session.get('https://api.example.com/data')
print(response.status_code)
対策その2:NATゲートウェイを複数並べる(スケールアウト)
1つのNATゲートウェイが持つポートの限界(約55,000ポート/宛先IP)を超えるトラフィックが予想される場合は、VPCのアーキテクチャそのものを拡張します。
可用性を高めるためにも、複数のAZ(アベイラビリティゾーン)にそれぞれNATゲートウェイを配置し、プライベートサブネットからのルートテーブルを適切に分散させましょう。
AWS CLIを使って、複数のパブリックサブネットにNATゲートウェイを構築する際の手順イメージは以下の通りです。
# 1. パブリックサブネットAにNATゲートウェイ用のEIP(Elastic IP)を割り当て
aws ec2 allocate-address --domain vpc --tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=nat-gw-eip-az1}]'
# 2. パブリックサブネットBにも同様にEIPを割り当て
aws ec2 allocate-address --domain vpc --tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=nat-gw-eip-az2}]'
# ※ この後、それぞれのEIPとパブリックサブネットを指定して aws ec2 create-nat-gateway を実行します。
このようにIPアドレス(窓口の数)自体を増やすことで、使えるソースポートの総数を物理的に増やすことができます。
—
まとめ
今回は、インフラ初学者の方向けに、NATゲートウェイの裏側にある「ソースポート枯渇問題」を郵便窓口のたとえを交えて解説しました。
- NATゲートウェイは、プライベートサーバーの代わりに外へ通信して戻してくれる「郵便窓口」のようなもの。
- 窓口が使える「整理券(ソースポート)」には数に限りがあり、同じ宛先へ同時に大量の通信を送ると枯渇してしまう。
- 対策として、アプリ側でコネクションを使い回したり(Keep-Alive)、NATゲートウェイやIPアドレスを分散させることが重要。
クラウドのネットワークは、目に見えないだけに最初は難しく感じられますが、私たちの身近なルールと照らし合わせてみると、非常にロジカルで面白い仕組みで動いています。
現場で「あれ、急に外との通信がタイムアウトするぞ?」となったときは、ぜひ今回の「窓口の整理券が足りなくなっているかも?」という景色を思い出してみてくださいね。
それでは、快適なクラウドライフを!SREチームより愛を込めて。
コメント