VXLANとは?
VXLANとはVirtual eXtensible LANの略称となる。もともとネットワーク仮想化といえば、昔からVLAN (Virtual LAN)が利用されていた。VLANはL2のイーサネットフレームで機能実装されており、物理的なネットワークケーブルが1本であったとしても、VLAN IDを付与することで、複数のネットワークセグメントの通信をできるようにする技術となる。VLANを使うことで、物理的なネットワーク機器やケーブル本数を削減し、用途別にネットワークの論理分割が実現できる。
VXLANはUDPパケットのデータ部以降で実装されており、実際の通信に用いるイーサネットフレームはカプセル化されている。VXLANを用いた際のイーサネットフレームの構造を以下に図示する。
カプセル化されているため、既存ネットワークへのVXLAN導入時の影響が非常に少ないという利点がある。また、本来は別のL2ネットワークセグメントであるサーバーであっても同一VXLANで通信させることで、あたかも同じセグメントでの通信をしているように振る舞うことができる。
他にもVLAN IDは12bit長であるため、0と4095の予約分を除く1~4094の範囲の4094個しか作ることができず、大規模なネットワークなどでは数が不足するという課題があった。VXLANではVNI (VXLAN Network Identifier)が24bit長となっており、1600万個ものネットワーク分割ができるようになっている。
今回は、異なるL2ネットワークセグメントに所属するCentOS 2台でVXLANを設定し、同一セグメントのサーバーとして通信できるよう設定を実施する。
構成と注意点
今回の構成は以下の通りとなる。途中に仮想ネットワーク機器のVyOSを挟み、L3ルーティングを行うネットワーク構成としている。ここにVXLANを導入し、同一セグメントとして通信できるように構成する。VXLANでは通信先サーバーを探す仕組みとして、ユニキャストモードとマルチキャストモードの2通りの設定がある。これはVXLANの通信の終端であるVTEP (VXLAN Tunnel End Point)が通信先のVTEPを探す際に、ユニキャストを使うかマルチキャストを使うかの違いとなる。今回の構成の場合、VTEPはCentOSのサーバーのNIC (ens160)となる。
ルーターはVyOSを利用したが、VyOSでは以下URLに記載の通り、現時点ではMulticast Routingに対応しておらず、L2セグメントを越えたマルチキャスト通信を実装することができない。
・VyOS - Multicast Routing
https://forum.vyos.net/showthread.php?tid=26935
したがって、今回の環境では、ユニキャストモードでVXLANを実装する必要がある。
設定手順
サーバーAとサーバーBの設定はほぼ同一となる。まずは、サーバーAから設定を行うこととする。サーバーA側の設定
設定はすべてipコマンドで行う。設定するVXLANの情報は以下の通り。------------------------------
◆サーバA VXLAN設定
・インターフェース名:vxlan0
・VNI:77
・ユニキャスト先VTEP:192.168.55.101
・VXLANで使用するUDPポート:4789
・VTEP:自身のNIC (ens160)
------------------------------
コマンドは以下の通りとなる。
dstportでポート番号4789で指定しているが、省略した場合、8472のポートが利用されてしまうので注意。これは、当初VXLANはUDP/8472を使用するように標準化が進められていたが、RFC 7348で規格化された際に、UDP/4789と変更となったことが原因のようだ。
# ip link add vxlan0 type vxlan id 77 group 239.0.0.1 dev ens160 dstport 4789
設定後、確認をしてみると、コマンドを実行した通りの設定が投入されていることがわかる。
# ip -d link show vxlan0
------------------------------
11: vxlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1000
link/ether 6a:2c:c1:bd:5a:2d brd ff:ff:ff:ff:ff:ff promiscuity 0
vxlan id 77 remote 192.168.55.101 dev ens160 srcport 0 0 dstport 4789 ageing 300 addrgenmode eui64
------------------------------
次にvxlan0のインターフェースをupさせ、IPアドレスを付与する。
# ip link set up vxlan0
# ip address add 172.24.77.101/24 dev vxlan0
再度、設定を確認してみる。
# ip addr show vxlan0
------------------------------
11: vxlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN qlen 1000
link/ether 6a:2c:c1:bd:5a:2d brd ff:ff:ff:ff:ff:ff
inet 172.24.77.101/24 scope global vxlan0
valid_lft forever preferred_lft forever
inet6 fe80::682c:c1ff:febd:5a2d/64 scope link
valid_lft forever preferred_lft forever
------------------------------
これでサーバーA側の設定は完了となる。
なお、ipコマンドではOSを再起動するとネットワーク設定が削除されてしまう。再起動しても設定が消えないようにする方法は残念ながら見つけることができなかったので、起動時に設定コマンドを実行するスクリプトなどを作って対応するしかなさそうだ。
サーバーB側の設定
設定するVXLANの情報は以下の通り。
------------------------------
◆サーバB VXLAN設定
・インターフェース名:vxlan0
・VNI:77
・ユニキャスト先VTEP:192.168.11.101
・VXLANで使用するUDPポート:4789
・VTEP:自身のNIC (ens160)
------------------------------
◆サーバB VXLAN設定
・インターフェース名:vxlan0
・VNI:77
・ユニキャスト先VTEP:192.168.11.101
・VXLANで使用するUDPポート:4789
・VTEP:自身のNIC (ens160)
------------------------------
手順はサーバーA側と同じなので、ひたすら設定を行う。
# ip -d link show vxlan0
------------------------------
7: vxlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1000
link/ether 9e:4a:3c:f4:55:2e brd ff:ff:ff:ff:ff:ff promiscuity 0
vxlan id 77 remote 192.168.11.101 dev ens160 srcport 0 0 dstport 4789 ageing 300 addrgenmode eui64# ip link set up vxlan0
------------------------------
# ip link set up vxlan0
# ip address add 172.24.77.102/24 dev vxlan0
# ip addr show vxlan0
------------------------------
7: vxlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN qlen 1000
link/ether 9e:4a:3c:f4:55:2e brd ff:ff:ff:ff:ff:ff
inet 172.24.77.102/24 scope global vxlan0
valid_lft forever preferred_lft forever
inet6 fe80::9c4a:3cff:fef4:552e/64 scope link
valid_lft forever preferred_lft forever
------------------------------
通信確認
設定が完了したので、サーバーBからpingを打ち、サーバAにてパケットを確認してみる。firewalldが動作しているとping疎通に失敗するようなので、事前に両方のサーバーでfirewalldを停止しておこう。
# systemctl stop firewalld
pingを実行すると、VXLANにて付与したIPアドレスで問題なく疎通ができた。
# systemctl stop firewalld
pingを実行すると、VXLANにて付与したIPアドレスで問題なく疎通ができた。
# ping 172.24.77.101
------------------------------
------------------------------
PING 172.24.77.101 (172.24.77.101) 56(84) bytes of data.
64 bytes from 172.24.77.101: icmp_seq=1 ttl=64 time=0.783 ms
64 bytes from 172.24.77.101: icmp_seq=2 ttl=64 time=0.387 ms
tcpdumpでパケットを確認してみる。tcpdumpではVXLANの中の通信内容も見ることができるが、そのまま貼り付けると見づらいので若干表示を整形しコメントを付与した。
# tcpdump -i ens160 src host 192.168.55.101 -n -v
------------------------------
tcpdump: listening on ens160, link-type EN10MB (Ethernet), capture size 65535 bytes
18:00:49.350813 IP (tos 0x0, ttl 63, id 16265, offset 0, flags [none], proto UDP (17), length 134)
192.168.55.101.40463 > 192.168.11.101.4789: VXLAN, flags [I] (0x08), vni 77
↑UDP/4789で通信
IP (tos 0x0, ttl 64, id 64215, offset 0, flags [DF], proto ICMP (1), length 84) 172.24.77.102 > 172.24.77.101: ICMP echo request, id 12775, seq 1, length 64
↑実際のVXLANの中の通信内容。pingのICMP通信(echo request)
18:00:50.351166 IP (tos 0x0, ttl 63, id 16621, offset 0, flags [none], proto UDP (17), length 134) 192.168.55.101.40463 > 192.168.11.101.4789: VXLAN, flags [I] (0x08), vni 77
IP (tos 0x0, ttl 64, id 64483, offset 0, flags [DF], proto ICMP (1), length 84) 172.24.77.102 > 172.24.77.101: ICMP echo request, id 12775, seq 2, length 64
------------------------------
(参考) VXLANインターフェース削除
VXLANインターフェースが不要となった場合の削除コマンドは以下の通りとなる。# ip link delete vxlan0