【実務・中級編】 カスタムルートテーブルの伝播(Route Propagation)とVPN/Direct Connectの挙動 – クラウドインフラと仮想化ネットワーク実践ガイド

AWSのネットワーク設計において、VPC内のプライベートサブネットからオンプレミス環境(データセンターやオフィス)へ安全に通信を伸ばす際、避けて通れないのが「ルートテーブルの管理」です。

朝会でインフラエンジニアの同僚が「あれ、オンプレ側の新しいサブネットへの疎通が急に切れたぞ?」と頭を抱えているシーンに出くわしたことはないでしょうか。原因を追っていくと、大抵は静的ルートのメンテナンス漏れか、今回取り上げる「ルート伝播(Route Propagation)」と静的ルートの優先順位の誤解に起因しています。

今回は、仮想プライベートゲートウェイ(VGW)やAWS Transit Gatewayを用いた環境において、ルート伝播がどのようにVPCのルートテーブルを動的に書き換えるのか、そして静的ルートとがっぷり四つに組んだときどちらが勝つのか、現場のリアルな挙動を交えて徹底解説します。

—

1. ルート伝播(Route Propagation)とは何か? パケットの旅路と背景

クラウドとオンプレミスをAWS Direct Connect(DX)やAWS Site-to-Site VPNで接続するとき、VPC側にはVirtual Private Gateway(VGW)がアタッチされます。

オンプレミスのルーター側で新しい拠点やサブネットが追加されるたびに、AWS側のルートテーブルを人間がポチポチ手動で更新するのは、ヒューマンエラーの温床であり、SREの美学に反します。ここで登場するのが「ルート伝播」です。

ルート伝播を有効にすると、BGP(Border Gateway Protocol)などのルーティングプロトコルを介して、オンプレミス側からVGWへ流れてきた経路情報が、AWSのバックエンドコントロールプレーンによって自動的に指定したルートテーブルへ動的に追加・削除されます。

通信の裏側で何が起きているのか(シーケンスのイメージ)

1. ルートの広告: オンプレミスのルーターが、BGPで新しいCIDR(例: 192.168.100.0/24)をVGWに向けてアナウンスします。
2. VGWの受信: VGWがそのルートを受け取り、AWSの内部ルーティング管理システムへ引き渡します。
3. ルートテーブルの自動更新: ルート伝播が有効化されているVPCルートテーブルに、ターゲットが vgw-xxxxxxxx である経路が数秒〜数十秒の間に動的に挿入されます。
4. パケットの転送: アプリケーションサーバーからオンプレミス宛てのパケットが送信されると、ルートテーブルの最長一致(Longest Prefix Match)に基づき、VGWへとルーティングされます。

—

2. 徹底比較:静的ルート vs 伝播ルートの優先順位

実務で最もハマりやすいのが、「同じ宛先CIDRに対して、静的ルートと伝播ルートが両方存在する場合、どっちが優先されるのか」という疑問です。

AWSの公式仕様において、ルートテーブルのルーティング決定ロジックは非常にシンプルかつ厳格です。

  • 原則 1: 最長一致(Longest Prefix Match)

もし静的ルートが 10.0.0.0/16 で、伝播ルートが 10.0.0.0/24 であれば、より詳細な /24 を持つ伝播ルートが優先されます(逆も同様)。

  • 原則 2: 完全一致のCIDRが競合する場合

もし静的ルートと伝播ルートが完全に同じCIDR(例: 両方とも 192.168.10.0/24)を指している場合、静的ルートが常に優先されます。

> SREの現場の教訓:
> 「以前設定したテスト用の静的ルートがルートテーブルに残ったままで、BGPでいくら新しいルートを伝播させてもトラフィックが古い宛先に吸い込まれ、半日デバッグに費やした」というのは、ネットワーク運用における古典的かつ最高のトラップです。競合時は静的ルートが勝つため、動的ルーティングへ移行する際は必ず古い静的ルートを掃除しましょう。

—

3. 実践:AWS CLIを用いたルート伝播の設定と確認

マネジメントコンソールでポチポチ設定するのも良いですが、IaC(Terraform/CloudFormation)全盛の昨今、CLIやAPIレベルでの挙動を理解しておくことはトラブルシューティングにおいて強力な武器になります。

ここでは、AWS CLIを使用してルート伝播を有効化し、ルートテーブルの実際の状態を確認する手順を見ていきます。

ステップ1: VGWのルート伝播を有効化する

特定のルートテーブル(例: rtb-1234567890abcdef0)に対して、VGW(例: vgw-0987654321fedcba0)からのルート伝播を有効にします。

aws ec2 create-transit-gateway-route-table-propagation # または VGW向けコマンド
# VGWの場合のルート伝播有効化コマンド
aws ec2 enable-vgw-route-propagation \
    --route-table-id rtb-1234567890abcdef0 \
    --gateway-id vgw-0987654321fedcba0

*実行時のTips*: コマンドが成功すると、数秒後にルートテーブルのステータスが propagating から active に変化します。

ステップ2: ルートテーブルの状態をJSONで確認する

現在のルートテーブルにどのようなルートが登録されており、どれが伝播によるものかを確認します。

aws ec2 describe-route-tables \
    --route-table-ids rtb-1234567890abcdef0 \
    --query "RouteTables[0].Routes[*].{Destination:DestinationCidrBlock, Gateway:GatewayId, Origin:Origin}" \
    --output table

出力例の読み方

このコマンドを実行すると、以下のようなテーブルが出力されます。

------------------------------------------------------------------------------------
|                              DescribeRouteTables                                 |
+----------------------+-----------------------------+-----------------------------+
|     Destination      |           Gateway           |           Origin            |
+----------------------+-----------------------------+-----------------------------+
|  10.0.0.0/16         |  local                      |  CreateRouteTable           |
|  0.0.0.0/0           |  igw-11111111111111111      |  CreateRoute                |
|  192.168.100.0/24    |  vgw-0987654321fedcba0      |  Propagate                  |  <-- 注目!
+----------------------+-----------------------------+-----------------------------+
  • Origin: Propagate となっているものは、VGW/TGWから動的に伝播してきたルートです。
  • Origin: CreateRoute は、ユーザーが手動で作成した静的ルートです。

—

4. アプリケーション層からの検証と死活監視

インフラ側でルート伝播が正しく機能しているか、アプリケーションやAPIサーバーのコンテナ内から実際にパケットを飛ばして検証してみましょう。

ここでは、Pythonスクリプトを用いて、オンプレミス側のプライベートAPIサーバーに対する死活チェック(疎通確認)を行うサンプルコードを提示します。

import urllib.request
import urllib.error
import time
import sys

# オンプレミス側のプライベートAPIエンドポイント
TARGET_API_URL = "http://192.168.100.50/healthz"
TIMEOUT_SECONDS = 3.0

def check_onprem_connectivity():
    """
    VPC内からルート伝播を経由してオンプレミス環境へパケットが届いているか検証する
    """
    print(f"[{time.strftime('%Y-%m-%d %H:%M:%S' )}] 疎通確認を開始します: {TARGET_API_URL}")
    
    try:
        req = urllib.request.Request(TARGET_API_URL, method="GET")
        with urllib.request.urlopen(req, timeout=TIMEOUT_SECONDS) as response:
            status_code = response.getcode()
            if status_code == 200:
                print(f"SUCCESS: オンプレミスとの通信に成功しました。HTTP Status: {status_code}")
                return True
            else:
                print(f"WARNING: 接続は成功しましたが、ステータスコードが異常です: {status_code}")
                return False
                
    except urllib.error.URLError as e:
        print(f"ERROR: オンプレミスへの通信に失敗しました。原因: {e.reason}")
        print("-> トラブルシューティングのヒント: ルートテーブルの伝播ステータス、セキュリティグループ、オンプレ側のファイアウォールを確認してください。")
        return False

if __name__ == "__main__":
    success = check_onprem_connectivity()
    # 失敗時はCI/CDや監視ツールのために非ゼロの終了コードを返す
    sys.exit(0 if success else 1)

—

5. 現場で役立つトラブルシューティング Tips

最後に、ルート伝播まわりで現場が炎上したときに確認すべきポイントをチェックリスト形式でまとめました。

1. BGPセッションは本当に確立しているか?

  • ルートテーブルを疑う前に、まずDirect Connectの仮想インターフェイス(VIF)やVPNトンネルの状態(CloudWatchメトリクス: TunnelState)が「UP」になっているか確認します。

2. ルート制限(上限)に達していないか?

  • AWSでは、1つのルートテーブルあたりに登録できるルート数に制限(デフォルトではVPCルートテーブルあたり50〜100ルート程度、上限緩和申請可能)があります。オンプレ側から過剰なルートがアドバタイズされると、伝播が途中でドロップすることがあります。

3. ブラックホールルートになっていないか?

  • 伝播元であるVGWやTGWが削除・デタッチされた場合、伝播ルートがどのように処理されるか意識していますか?基本的にはルートは削除されますが、整合性が崩れた場合は手動でのクリーンアップが必要です。

クラウドのネットワークは、目に見えないパケットが緻密なルールに従ってルーティングされています。「なぜこのパケットがそこに流れるのか」をルートテーブルのオリジンや優先順位のロジックから逆算できるようになると、ネットワークトラブルの解決スピードが劇的に向上します。

日々の運用に、ぜひこの知見を役立ててください。

コメント

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