午前2時のネットワーク危機:なぜトンネルが必要なのか
時刻は午前2時、監視アラートが鳴り響いています。プロバイダーがサイト間のレイヤー2隣接をサポートしていないため、セカンダリデータセンター内のデータベースクラスターノードの同期が途切れてしまいました。これらのサーバーを同じローカルスイッチ上にあるかのように動作させる必要がありますが、実際には3台のルーター and 不安定なパブリックインターネット接続によって隔てられています。ここでトンネルが威力を発揮します。
既存のレイヤー3インフラを跨いでネットワークを拡張することは、KubernetesやOpenStack、マルチサイトのディザスタリカバリにおいて一般的な要件です。私はこれまで、10Gbps以上のトラフィックを処理する本番環境でこれらのトンネルをデプロイしてきましたが、正しく設定すればその安定性は非常に強固です。2つのリモートオフィスをリンクする場合でも、大規模な仮想化オーバーレイを構築する場合でも、GREとVXLANをマスターすることはシニアLinuxエンジニアにとって不可欠なスキルです。
GRE (Generic Routing Encapsulation) は、ポイント・ツー・ポイントのレイヤー3リンクを実現する、信頼のおける古き良き実務家のような存在だと考えてください。一方、VXLAN (Virtual Extensible LAN) はその現代的な進化系です。レイヤー2のイーサネットフレームをUDPパケットで包み込み、バラバラなIPネットワークを実質的に一つの巨大な仮想スイッチへと変貌させます。
Linux環境の準備
すぐに設定に飛び込んではいけません。まず、カーネルがカプセル化を処理できる状態にあるかを確認しましょう。Ubuntu 22.04やRHEL 9のような現代的なディストリビューションでは通常これらのモジュールは有効になっていますが、緊急時に欠落に気づくのは避けたいものです。また、iproute2スイートが必要になります。もし未だにifconfigを使っているなら、そろそろ卒業する時です。
以下のコマンドでモジュールを確認します:
# GREサポートの確認
sudo modprobe ip_gre
lsmod | grep gre
# VXLANサポートの確認
sudo modprobe vxlan
lsmod | grep vxlan
再起動後もこれらを有効にするには、/etc/modules-load.d/tunnels.confに追加します。今10秒かけるだけで、後で10分間頭を抱えずに済みます。
ポイント・ツー・ポイント接続のためのGREトンネルの構築
実際のシナリオを見てみましょう。サイトA of IPは1.1.1.1、サイトBは2.2.2.2です。サイトAが10.0.0.1、サイトBが10.0.0.2(/30サブネット)を使用する、両拠点間のプライベートな「ケーブル」が必要です。
サイトA (1.1.1.1) での設定:
# トンネルインターフェースの作成
sudo ip tunnel add gre01 mode gre remote 2.2.2.2 local 1.1.1.1 ttl 255
# インターフェースの有効化
sudo ip link set gre01 up
# プライベートIPアドレスの割り当て
sudo ip addr add 10.0.0.1/30 dev gre01
サイトB (2.2.2.2) での設定:
# トンネルインターフェース의作成
sudo ip tunnel add gre01 mode gre remote 1.1.1.1 local 2.2.2.2 ttl 255
# インターフェース의有効化
sudo ip link set gre01 up
# プライベートIPアドレス의割り当て
sudo ip addr add 10.0.0.2/30 dev gre01
GREはシンプルですが、大きな制限が1つあります。それはレイヤー3トラフィックしか処理できないことです。ブロードキャストパケットや非IPフレームをネイティブに渡すことはできません。ルーター間でOSPFやBGPを実行するだけなら、GREは最適です。しかし、アプリケーションがレイヤー2隣接のためにサーバー同士のMACアドレスを「認識」する必要がある場合は、VXLANが必要になります。
VXLANによる拡張:L2オーバーレイネットワークの作成
VXLANはオーバーレイネットワークの業界標準です。24ビットの仮想ネットワーク識別子 (VNI) を使用し、1,600万個の独立したネットワークを作成できます。これにより、従来のVLANの4,096という制限を打ち破ります。2台のリモートサーバーをブリッジして、同じ192.168.100.xサブネット上にあるように見せます。
ホストA (1.1.1.1) での設定:
# VXLANインターフェース의作成
# VNI (id) 는42、標準ポート4789を使用
sudo ip link add vxlan42 type vxlan id 42 remote 2.2.2.2 local 1.1.1.1 dstport 4789
# インターフェース의有効化
sudo ip link set vxlan42 up
# 仮想L2ネットワーク上のIPを割り当て
sudo ip addr add 192.168.100.1/24 dev vxlan42
ホストB (2.2.2.2) での設定:
sudo ip link add vxlan42 type vxlan id 42 remote 1.1.1.1 local 2.2.2.2 dstport 4789
sudo ip link set vxlan42 up
sudo ip addr add 192.168.100.2/24 dev vxlan42
この段階で、ホストAは192.168.100.2にpingを打つことができます。arp -aを実行すると、リモートホストのMACアドレスが表示されます。レイヤー3の境界を越えてレイヤー2ネットワークを拡張することに成功しました。
静かなパフォーマンスキラー:MTUの断片化
ここで最もよくある間違いが、MTU (Maximum Transmission Unit) を無視することです。標準のイーサネットフレームは1500バイトです。そのフレームを50バイトのVXLANヘッダーで包むと、1550バイトに膨らみます。物理ネットワークが1500バイトを想定している場合、そのパケットは断片化されるか、単純に破棄されます。
pingは通るのに、大きなコマンドを実行した途端にSSHセッションがハングするのはこのためです。通信をスムーズに保つために、トンネルインターフェースのMTUは常に下げておきましょう:
# GREの場合
sudo ip link set dev gre01 mtu 1476
# VXLANの場合
sudo ip link set dev vxlan42 mtu 1450
MTUを下げることで、断片化によるパフォーマンス低下の悪夢を防ぎ、大容量のデータ転送が静かに失敗するのを避けることができます。
検証とモニタリング
検証はpingの成功だけで終わらせてはいけません。カプセル化がエラーなく実際に機能していることを確認する必要があります。
まず、インターフェースの統計情報を確認します:
ip -s link show vxlan42
ドロップされたパケットがないか注意してください。トラフィックが流れていない場合は、tcpdumpを使用して物理回線を調査します。VXLANの場合はポート4789のUDPパケット、GREの場合はプロトコル47が見えるはずです。
# 物理eth0インターフェース上のVXLANトラフィックを監視
sudo tcpdump -i eth0 port 4789 -n
ホストAからパケットが出ているのにホストBに届かない場合は、ファイアウォールを確認してください。VXLAN用の4789/UDPが開放されており、セキュリティグループでgreプロトコルが許可されていることを確認します。手動設定は基礎となります。確かに、500ノードの大規模なクラスターではAnsibleやBGP EVPNコントロールプレーンを使用するでしょう。しかし、午前3時に自動化が失敗したとき、自分の手でこれらのインターフェースを「配線」する方法を知っているかどうかが窮地を救うのです。

