【テクニカル・上級編】 Azure NAT Gatewayの複数パブリックIPアドレス(IPプール)割り当てとラウンドロビン方式 – クラウド&コンテナネットワーク実践ガイド

Azure NAT GatewayのIPプール戦略:ポート枯渇の呪縛から解放されるための低レイテンシ・アーキテクチャ

クラウドネイティブなインフラを構築していると、必ず遭遇する「ポート枯渇」という名の壁があります。特に高頻度で外部APIを叩くマイクロサービスや、膨大なトラフィックを捌くエグレス(Egress)ゲートウェイでは、単一のパブリックIPによるSNAT(Source NAT)は、まさにボトルネックの象徴です。

今回は、Azure NAT Gatewayが提供する「パブリックIPのプール機能」を深掘りし、単なる設定の羅列ではなく、パケットの挙動とカーネルレベルのチューニングまで踏み込んだ「現場の解」を提示します。

なぜ1つのIPでは足りないのか:SNATポートの物理的限界

Azure NAT Gatewayは、送信元ポートを動的に割り当てて外部通信を制御します。しかし、TCP/UDPのポート番号は16ビット(65,535)しかありません。システム予約ポートを除くと、実質的に利用可能なポートは 64,512 程度です。

高負荷な環境では、TIME_WAIT 状態のソケットが蓄積し、接続先IP+ポートの組み合わせが枯渇する「SNATポート枯渇」が発生します。Azure NAT GatewayのIPプール機能は、最大16個のパブリックIPを関連付けることで、理論上の最大ポート数を約100万個まで引き上げることが可能です。

IPプールの選択ロジック:ラウンドロビンか、あるいはランダムか

Azure NAT Gatewayに複数のIPを割り当てた際、重要なのは「どのパケットがどのIPから出ていくか」という決定論的な挙動です。

Azureの内部実装では、コネクションの5タプル(送信元IP/ポート、宛先IP/ポート、プロトコル)に基づいてハッシュ化が行われ、割り当てられたIPプールの中から送信元IPが決定されます。これは単純なラウンドロビンではなく、コネクション単位での一貫性(Sticky Session的挙動)を維持するための分散アルゴリズムです。

これにより、同一フローからのパケットは同一のパブリックIPから送信されることが保証され、宛先サーバー側でのステートフル・ファイアウォールやTLSハンドシェイクのセッション再開(Session Resumption)において、IP不一致による接続断や再認証のオーバーヘッドを最小化します。

パフォーマンスを最大化するためのカーネルチューニング

NAT Gatewayで出口を拡張しても、Linuxカーネル側の tcp_tw_reuse やバッファ設定が最適でなければ、コンテナ内のアプリケーションはポート枯渇に苦しみ続けます。

以下の設定は、高トラフィックなエグレスノードにおいて、カーネルレベルでパケット処理を最適化するための sysctl サンプルです。

# /etc/sysctl.conf に追記し、エフェメラルポートの範囲を広げる
# デフォルトの範囲を拡大し、SNATポート枯渇の閾値を引き上げる
net.ipv4.ip_local_port_range = 1024 65535

# TIME_WAIT ソケットの再利用を許可し、短寿命なコネクションのポートを即座に解放
net.ipv4.tcp_tw_reuse = 1

# TCPパケットのバッファサイズを最適化し、RTTの大きい通信でのスループットを向上
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# 変更を反映
sysctl -p

セキュリティと信頼性のトレードオフ:IPプール活用時の注意点

IPプールを増やすことは「ポートの拡張」という側面では有効ですが、セキュリティ専門家としては「IPレピュテーション」の観点を見逃してはいけません。

1. ファイアウォールホワイトリストの肥大化: 宛先側がIPベースのACLを採用している場合、16個のIPすべてを許可する必要があります。管理コストの増大を念頭に置いてください。
2. TLSハンドシェイクの最適化: 接続先が TLS 1.3 をサポートしている場合、0-RTT (Zero Round Trip Time) を活用することで、ハンドシェイクのRTTを削減可能です。NAT Gatewayを介す場合、IPの切り替わりが最小限になるよう、宛先ごとのコネクションプーリングをアプリケーション層(Keep-Alive の維持など)で徹底することが、真のパフォーマンス向上に繋がります。

実践:Azure CLIによるIPプールの構築

単にIPを割り当てるだけでなく、既存のNAT Gatewayを拡張する手順を記します。

# 既存のNAT Gatewayに新しいパブリックIPを追加する
# 1. 新しいパブリックIPアドレスを作成
az network public-ip create --name MyPublicIP2 --resource-group MyResourceGroup --sku Standard

# 2. NAT GatewayにIPを追加関連付け
az network nat gateway update --name MyNatGateway --resource-group MyResourceGroup \
  --public-ip-addresses MyPublicIP1 MyPublicIP2

結びに:ネットワークは「見えないインフラ」ではない

多くの場合、NAT Gatewayのトラブルは「ネットワーク遅延が…」といった曖昧な評価で片付けられます。しかし、実際には TCP SYN パケットの再送率や、TIME_WAIT の累積数を確認すれば、原因は一目瞭然です。

クラウドネットワークの設計において、IPプールは単なる「広さ」の確保ではありません。それは、アプリケーションが外部と対話する際の「窓」を増やすことであり、ボトルネックを分散させ、システム全体のスループットを底上げする極めて重要なアーキテクチャ上の意思決定です。

次は、あなたのインフラで netstat -an | grep TIME_WAIT | wc -l を叩いてみてください。そこに映し出される数字が、あなたのシステムが今すぐ改善すべき「伸び代」そのものなのです。

コメント

タイトルとURLをコピーしました