VXLANの「黒魔術」を解剖する:パケットはどうやってL3の海を渡るのか?
クラウドネイティブなインフラを構築していると、必ずと言っていいほど直面するのが「ネットワークの分断」という壁です。特にKubernetesにおいて、Podがノードを跨いで通信する際、L2のブロードキャストドメインをどうやってL3ネットワーク上でエミュレートするか――そこで主役となるのが VXLAN (Virtual Extensible LAN) です。
「VXLANなんて、VTEPを立ててカプセル化するだけでしょ?」という認識で止まっていると、いざ本番環境でパケットロスが発生したとき、原因を突き止めるのに地獄を見ることになります。今日は、現場のSREが必ず押さえておくべき、VXLANの裏側にある「UDP 4789番」の役割とパケット構造について、泥臭い視点で深掘りしていきましょう。
—
1. なぜ「UDP 4789」なのか?:カプセル化のリアル
VXLANは、元のイーサネットフレームをそのまま「ペイロード」として包み込み、UDPパケットの中に閉じ込める技術です。これを担うのが VTEP (VXLAN Tunnel End Point) です。
パケット構造を覗く
VXLANのパケットは、外側から見るとこうなっています。
1. Outer Ethernet Header (宛先MACは次のルーター)
2. Outer IP Header (送信元/宛先はVTEPのIP)
3. Outer UDP Header (宛先ポートは 4789)
4. VXLAN Header (VNIが含まれる)
5. Original Ethernet Frame (ここが本来の通信データ)
なぜUDPを使うのか? それは、IPネットワーク上のECMP(等コストマルチパスルーティング)を活用するためです。送信元ポート番号をフローごとに変えることで、物理ネットワーク機器がパケットを複数の経路に分散させやすくなります。この「ポート4789」はIANAに割り当てられたVXLAN標準のポート番号であり、パケットが届いた瞬間に、スイッチやOSが「これはカプセル化されたVXLANパケットだ」と認識するためのスイッチとして機能します。
—
2. VNI:24ビットの魔法
VXLANの肝は VNI (VXLAN Network Identifier) です。VLAN IDが12ビット(4,096個)しかなかったのに対し、VNIは24ビット。つまり約1,600万個のネットワークを論理的に分離できます。
現場のトラブルシューティングで多いのが、このVNIの不一致です。「設定したはずなのに疎通がない」という場合、大抵は物理ネットワークのMTU設定か、VTEP間のVNIの不一致が原因です。
—
3. 実践:デバッグのためのツールとコード
論理を知るだけでは不十分です。実際にパケットをキャプチャし、中身を確認するスキルが不可欠です。
tcpdumpでVXLANを覗き見る
インフラエンジニアの必需品 tcpdump を使って、VXLANパケットを特定するコマンドを紹介します。
# 宛先ポート4789のパケットをキャプチャし、VXLANヘッダーの中身を表示する
# -vvで詳細を、-nでDNS解決を無効化して高速に表示
sudo tcpdump -i eth0 udp port 4789 -vv -n
Pythonでパケット構造をシミュレートする(概念コード)
VXLANパケットを自作するわけではありませんが、ヘッダーの構造を理解するために、scapyを用いたパケット構築のイメージを掴んでおきましょう。
from scapy.all import *
# VXLANヘッダーを構築(VNI=1001の場合)
# VNIは24ビットなので、3バイトで表現
vxlan_hdr = VXLAN(vni=1001)
# 全体のパケット構築
# OuterIP / UDP / VXLAN / InnerEther / InnerIP
packet = Ether()/IP(dst="192.168.1.10")/UDP(dport=4789)/vxlan_hdr/Ether()/IP(dst="10.0.0.5")
# パケットの概要を表示
packet.show()
—
4. 現場で生き残るための教訓:MTU問題
最後に、絶対に忘れてはならないのが MTU (Maximum Transmission Unit) です。
VXLANは元のフレームにヘッダー(合計50バイト程度)を追加するため、物理ネットワークのMTUが標準の 1500 のままだと、パケットがフラグメンテーションを起こし、パフォーマンスが急落、最悪の場合は接続が切れます。
解決策: 物理ネットワーク側で「ジャンボフレーム(MTU 9000など)」を許可するか、VTEP側でMSSクランプを行うのが定石です。
# LinuxでインターフェースのMTUを確認・設定する例
ip link show eth0
# カプセル化によるオーバーヘッドを考慮して、通常より50バイト程度大きく設定する
sudo ip link set dev eth0 mtu 1550
—
まとめ:ネットワークは「見えないもの」を可視化することから始まる
VXLANの UDP 4789 は、単なるポート番号ではありません。クラウドという巨大なインフラの上で、物理的な制約を飛び越えてレイヤー2を延長するための「鍵」です。
トラブルが起きたとき、パケットがどこでカプセル化され、どの経路を通り、どこでデカプセル化されるのか――このシーケンスが脳内で再生できるようになれば、あなたはもう一人前のクラウド・ネットワークエンジニアです。
次回のトラブル時には、ぜひ tcpdump を叩いて、VNIの中身を覗いてみてください。そこには、教科書には載っていない「通信のリアル」が詰まっています。
コメント