【実務・中級編】 パブリックサブネットの定義とインターネットゲートウェイ(IGW)とのルーティング設計 – クラウド&コンテナネットワーク実践ガイド

クラウドインフラの構築において、VPC(Virtual Private Cloud)の設計はシステムの命運を握るファーストステップです。なかでも「パブリックサブネット」と「インターネットゲートウェイ(IGW)」のルーティング設計は、一見すると教科書通りに作れば動くシンプルな領域に見えます。

しかし、現場のSREとして数々の本番障害や通信断のトラブルシュートを経験してくると、この基本の組み合わせこそが、ルーティングの競合、非対称ルーティング(Asymmetric Routing)、そして暗黙のステートフル制御の理解度を試す「最初の関所」であることに気づかされます。

今回は、パブリックサブネットがなぜインターネットに直結できるのか、その裏側にあるパケットの旅路と、実務で絶対に外せないルーティング設計の勘所を、泥臭い実運用者の視点から徹底的に解説します。

—

1. パブリックサブネットとIGWの本質的な関係

「パブリックサブネット」という言葉は、AWSをはじめとするメガクラウドのコンソール画面で日常的に使われますが、実はクラウドベンダーの内部実装において、サブネット自体に「パブリック」という特別なフラグがハードコードされているわけではありません。

サブネットがパブリックであるかプライベートであるかを決定づけている唯一の要素、それは「ルートテーブル(Route Table)のルーティング先(Target)にインターネットゲートウェイ(IGW)が設定されているかどうか」、これに尽きます。

IGWはルーターではなく「ソフトウェア定義のエッジプロキシ」だ

物理ネットワークの世界で育ったエンジニアほど、ゲートウェイと聞くとハードウェアのルーターを想像しがちです。しかし、AWSなどのパブリッククラウドにおけるIGWは、VPCのエッジに水平分散配置された、可用性とスケーラビリティが無限に担保された仮想的なソフトウェアモジュールです。

IGWの最大の役割は、VPC内のインスタンス(EC2やコンテナノードなど)が持つプライベートIPアドレスと、インターネット上のグローバルIPアドレス(パブリックIPv4アドレスやElastic IP)との間のNAT(Network Address Translation)、およびパケットの転送制御です。

—

2. パケットの往復を追う:IGW連携の通信フロー

外部のクライアントや外部APIサーバーから、パブリックサブネット上に配置されたWebサーバーへの通信がどのように流れるのか、そのパケットのライフサイクルをシーケンスとして追ってみましょう。

ここでは、AWS環境を例に、リクエストが到達し、レスポンスが返るまでの流れを紐解きます。

[外部クライアント] 
       │ (インターネット経由 / グローバルIP宛て)
       ▼
[インターネットゲートウェイ (IGW)] 
       │ (宛先IPをプライベートIPにNAT変換)
       ▼
[パブリックサブネットのルートテーブル]
       │ ( 0.0.0.0/0 -> igw-xxxxxxxx )
       ▼
[EC2インスタンス (Webサーバー / プライベートIP)]

1. インバウンド(外から中へ):
外部からグローバルIP宛てに送られたパケットがIGWに到達します。IGWは、自身が保持するNATマッピングテーブルを参照し、宛先IPアドレスをEC2インスタンスのプライベートIPアドレスに書き換えます(DNAT)。
2. ルートテーブルの参照:
サブネットのルートテーブルには、デフォルトルートとして 0.0.0.0/0 のターゲットにIGWが指定されています。しかし、インバウンドパケットの視点では、すでにVPC内に入ってきているため、次はインスタンス自身のENI(Elastic Network Interface)へとパケットが配送されます。
3. アウトバウンド(中から外へ):
サーバー側が処理を終え、レスポンスを返す際、送信元はプライベートIP、宛先は外部のグローバルIPとなります。
4. IGWでの逆変換(SNAT):
パブリックサブネット内のルートテーブルに従い、宛先不明のパケットはすべて 0.0.0.0/0 を通じてIGWに送り出されます。IGWはパケットの送信元プライベートIPを元のパブリックIP/EIPに書き換え(SNAT)、インターネットへ放流します。

この仕組みの肝は、パブリックサブネットに属するインスタンス自身がグローバルIPを直接インターフェースにバインドしているわけではなく、AWSのエッジ(IGW)が代理でNATを行っているという点です。

—

3. 実務で遭遇するエッジケースとハマりどころ

現場で設計・運用をしていると、教科書通りにいかないケースに直面します。特に注意すべき2つのエッジケースを共有します。

エッジケース①:パブリックサブネットなのにアウトバウンド通信ができない?

「パブリックサブネットなのだから、配置したインスタンスは当然外のAPIを叩けるはずだ」と思っていませんか?
ここで問題になるのが、インスタンス自体がパブリックIPv4アドレスまたはElastic IP(EIP)を持っているか、あるいはAWSの機能であるENIレベルでのパブリックIP割当が有効になっているかという点です。

パブリックサブネットのルートテーブルに 0.0.0.0/0 -> IGW が設定されていても、インスタンス自身に紐づくグローバルIPが存在しない場合、IGWは「どのパブリックIPにNATしていいか分からない」ため、アウトバウンドパケットをドロップします。

エッジケース②:非対称ルーティング(Asymmetric Routing)の罠

Kubernetesクラスター(EKSや自前構築のK8s)をパブリックサブネットとプライベートサブネットにまたがって構築したり、複数のENIを1つのインスタンスにアタッチしたりする高度な設計では、非対称ルーティングの罠に陥りがちです。
パケットの往路と復路で異なるゲートウェイやルートを通ると、ステートフルなファイアウォール(AWSのセキュリティグループやネットワークACL)によって「不正なパケット」とみなされ、接続がランダムに切断されるという、原因特定が非常に困難な障害を引き起こします。

—

4. 実装例:IaCとアプリケーションコードの確認

ここからは、実際にTerraformでのルートテーブル構築設定と、パブリックサブネット上のアプリケーションから外部APIへ疎通確認を行うコードを見ていきます。

TerraformによるパブリックサブネットとIGWのルーティング定義

実務で最も一般的に使われるTerraformのコードスニペットです。

# インターネットゲートウェイの作成
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "production-igw"
  }
}

# パブリックサブネット用ルートテーブルの作成
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  # すべての外部トラフィック(0.0.0.0/0)をIGWに向けるデフォルトルート
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }

  tags = {
    Name = "production-public-rt"
  }
}

# パブリックサブネットとルートテーブルの関連付け
resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

Pythonによる外部Web APIへの疎通テストコード

パブリックサブネット上のコンテナやEC2から、外部の決済APIやSaaSへ正しくリクエストが飛ぶかを検証するためのPython(requestsライブラリ)スクリプトです。タイムアウト設定と例外処理を明記し、本番の死活監視にも耐える実装にしています。

import requests
import sys

def check_external_connectivity():
    target_url = "https://api.ipify.org?format=json" # 自身のグローバルIPを返すパブリックAPI
    
    try:
        # 接続タイムアウトを3秒、読み込みタイムアウトを5秒に設定
        response = requests.get(target_url, timeout=(3.0, 5.0))
        
        # HTTPステータスコードが200番台以外の場合は例外を発生させる
        response.raise_for_status()
        
        data = response.json()
        print(f"[SUCCESS] 外部ネットワークへの疎通に成功しました。")
        print(f"[INFO] IGWを通過したグローバルIPアドレス: {data.get('ip')}")
        
    except requests.exceptions.Timeout:
        print("[ERROR] 外部APIへの接続がタイムアウトしました。ルートテーブルのIGW設定やセキュリティグループを確認してください。", file=sys.stderr)
        sys.exit(1)
    except requests.exceptions.RequestException as e:
        print(f"[ERROR] 予期せぬネットワークエラーが発生しました: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    check_external_connectivity()

—

5. まとめ:シニアSREからの実務的アドバイス

パブリックサブネットとIGWのルーティング設計は、クラウドネットワークの基本中の基本ですが、それゆえに「動いて当たり前」として見落とされがちなポイントでもあります。

トラブルシューティングの現場では、まず以下のチェックリストを上から順に確認してください。

1. ルートテーブルの存在確認: サブネットに関連付けられているルートテーブルに 0.0.0.0/0 -> igw-xxxxxxxx が正しく記述されているか。
2. IGWのVPCアタッチ確認: インターネットゲートウェイ自体が、対象のVPCにアタッチ(Attached)されているか。
3. グローバルIPの有無: インスタンスやENIにパブリックIPv4/EIPが正しく付与されているか(アウトバウンド時)。
4. セキュリティグループとNACL: アウトバウンド(送信)のトラフィックが 0.0.0.0/0 に対して許可されているか。

これら一つひとつの要素が噛み合ってはじめて、安全でスムーズなインターネット通信が実現します。ネットワークのパケットの挙動を頭の中でイメージできるようになれば、どんな複雑なマルチVPC環境であっても恐れることはありません。日々のインフラ運用・設計の精度を高めていきましょう。

コメント

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