【テクニカル・上級編】 複数VPC間ピーリング(VPC Peering)環境におけるNATゲートウェイの共有設計パターン – クラウド&コンテナネットワーク実践ガイド

疎結合の代償を「一極集中」で解く:VPC Peering環境におけるNATゲートウェイ共有の深淵

クラウドアーキテクチャの設計において、VPCの分離(Segmentation)はセキュリティの鉄則だ。しかし、システムが拡大し、マイクロサービスが数十のVPCに分散するようになると、全てのVPCにNATゲートウェイ(以下NATGW)を配置するのは経済的にも運用的にも悪夢となる。

「NATGWを共有し、セントラルなハブVPCから外へ出る」。この構成は一見シンプルだが、ここに足を踏み入れることは、パケットのルーティング制御という名の迷宮に挑むことを意味する。今日は、この泥臭くもエレガントな「セントラルNATGW設計」の深部を、カーネルレベルの挙動から紐解いていこう。

—

1. パケットの旅路:VPC Peeringを跨ぐルーティングの罠

VPC Peeringを通じて他VPCのNATGWへパケットを流す場合、ルーティングテーブルの設計には細心の注意が必要だ。

まず理解すべきは、NATGWはあくまで「パブリックサブネットに存在する、AWS/GCPのマネージドなゲートウェイ」であるという点だ。パケットが別VPCから送られてきた場合、NATGWは戻りのパケットを「どのルートで送信元のVPCへ送り返すべきか」を、自身のルーティングテーブルではなく、パケットのIPヘッダーとサブネットのルーティング設定に基づいて判断する。

ここで最も陥りやすい罠が、「戻りパケットのブラックホール化」だ。

# スポークVPC側でのルート設定例(AWS CLI)
# 0.0.0.0/0 をハブVPCのPeering Connection経由でNATGWへ向ける
aws ec2 create-route \
    --route-table-id rtb-12345678 \
    --destination-cidr-block 0.0.0.0/0 \
    --vpc-peering-connection-id pcx-abcdefgh

このとき、ハブVPC側では、戻りパケットをスポークVPCへ正しくルーティングするための「戻りルート」が必須となる。これを怠ると、TCPの SYN パケットは外へ出られても、SYN/ACK が帰ってこれず、コネクションはハングアップし、カーネルの netstat は SYN_SENT で溢れかえることになる。

—

2. トランスポート層の最適化:RTT削減とバッファチューニング

NATGWを共有するということは、物理的なホップ数と論理的な遅延(RTT)が増加することを意味する。高トラフィックなアプリケーションでは、このわずかな遅延が TCP window scaling の効率を著しく低下させる。

特に、広域な通信では BDP (Bandwidth Delay Product) を考慮したTCPバッファのチューニングが不可欠だ。以下は、Linuxノード側で考慮すべきチューニングパラメーターである。

# /etc/sysctl.conf への追記例
# ネットワークの遅延が大きい環境ではTCPウィンドウサイズを拡大する
net.ipv4.tcp_rmem = 4096 87380 16777216  # 受信バッファの最大値を16MBに拡大
net.ipv4.tcp_wmem = 4096 65536 16777216  # 送信バッファの最大値を16MBに拡大
net.ipv4.tcp_window_scaling = 1         # ウィンドウサイズのスケーリングを有効化

また、NATGWを介した通信では、NATデバイスによる TCP Connection Tracking がボトルネックになり得る。高負荷時には conntrack テーブルの枯渇を防ぐため、アプリ側で Keep-Alive を適切に設定し、不要な接続の乱立を防ぐことが肝要だ。

—

3. セキュリティとパケットの「覗き見」:TLSのハンドシェイク

NATGWを共有する際、最も危惧すべきは「セキュリティ境界の曖昧化」だ。複数のVPCから一つのNATGWにトラフィックを集約すると、そこはトラフィックのボトルネックであると同時に、攻撃の集約点となる。

トランスポート層におけるセキュリティ最適化として、TLS 1.3 の採用は必須条件だ。TLS 1.3 はハンドシェイクの往復回数を減らす(0-RTT Resumption)ため、NATGWを経由するオーバーヘッドを相殺できる。

さらに、パケットヘッダー圧縮アルゴリズム(HPACK や QPACK)を活用するHTTP/3の導入も検討すべきだ。これらは特に、パケットロスが起きやすいNAT環境において、ヘッダー情報の再送負荷を劇的に軽減する。

—

4. 現場の教訓:NATGWの「枯渇」をどう検知するか

最後に、実務において最も遭遇する「NATGWのポート枯渇」について触れておこう。AWSのNATGWは、送信元IPとポートの組み合わせで管理されている。短時間で大量の接続を行うと、Ephemeral Port が使い果たされ、NATGWは通信を破棄する。

これを回避するために、我々SREは CloudWatch Metrics で ErrorPortAllocation を監視するだけでなく、以下のようなロジックをシステムに組み込むべきだ。

1. コネクションプーリング: アプリケーション層でDB接続や外部API接続をプーリングし、再利用する。
2. 分散配置の検討: 限界を感じたら、NATGWの共有モデルを維持しつつ、複数のNATGWに負荷を分散する(AZごとのNATGW配置による冗長化)。

結論

NATGWの共有設計は、ネットワークの「効率」と「複雑性」のトレードオフだ。パケットがVPCの境界を越え、NATGWの静かなゲートを通り抜けてインターネットの海へ消えていく様子を想像できるだろうか。

インフラアーキテクトに求められるのは、単に設定コマンドを叩くことではなく、その裏でOSのカーネルやルーティングテーブルがどのようにパケットを捌いているのか、その「鼓動」を感じることだ。この設計を適用する際は、ぜひ、パケットキャプチャを採り、TCP Retransmission が発生していないかを自分の目で確かめてほしい。そこには、教科書には決して書かれていない、真のエンジニアリングの醍醐味が詰まっている。

コメント

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