Cumulus VX で VXLAN+EVPN (original : 2017/03/22)
この記事は某所で 2017/03/22
に書いた記事のコピーです。
そのため 2017/05/11
時点ではやや古い情報も含まれています。(2017/05 に GNS3 v2.0.0 stable
や Cumulus Linux v3.3
がリリースされた)
- 最初に
- 構築
- 動作確認
- おしまい
最初に
本項でやること
以下をやります。
- Cumulus Linux の Early Access 版(
2017/03/21
時点)で限定的に VXLAN+EVPN 機能を試行できるので、仮想版である Cumulus VX でも動くか見る- 将来的に本実装された際には、設定方法や挙動は変わる筈
- 現在取得できる EA 版は Quagga daemon のみなので、EVPN機能周りの設定や参照は Quagga にて
- EVPN Multihoming を実装していない代わりに、MLAGでVTEPを冗長化する仕組みがあるようなので、その設定と挙動を見る
環境情報
Cumulus VX
Cumulus公式 / Download Cumulus VX で 2017/03/13
時点でダウンロード可能な最新版(Cumulus VX 3.2.1
)の KVM 版
アカウントを作れば、個人でも特に問題なくダウンロードできました。
kotetsu@kvm01:~/vm_images/qemu$ ls -al cumulus-linux-3.2.1-vx-amd64-1486153138.ac46c24zd00d13e.qcow2 -rw-r--r-- 1 kotetsu kotetsu 1232601088 Mar 7 22:11 cumulus-linux-3.2.1-vx-amd64-1486153138.ac46c24zd00d13e.qcow2 kotetsu@kvm01:~/vm_images/qemu$ sha1sum cumulus-linux-3.2.1-vx-amd64-1486153138.ac46c24zd00d13e.qcow2 3d782f2c450683b4da5ea2324c88f3dccb89b6c2 cumulus-linux-3.2.1-vx-amd64-1486153138.ac46c24zd00d13e.qcow2
kotetsu@bb03:~$ cat /etc/lsb-release DISTRIB_ID="Cumulus Linux" DISTRIB_RELEASE=3.2.1 DISTRIB_DESCRIPTION="Cumulus Linux 3.2.1" kotetsu@bb03:~$ uname -a Linux bb03 4.1.0-cl-4-amd64 #1 SMP Debian 4.1.33-1+cl3u7 (2017-01-26) x86_64 GNU/Linux
その他
$ uname -a Linux kvm01 4.4.0-57-generic #78-Ubuntu SMP Fri Dec 9 23:50:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS" $ virsh -v 1.3.1 $ qemu-system-x86_64 --version QEMU emulator version 2.5.0 (Debian 1:2.5+dfsg-5ubuntu10.6), Copyright (c) 2003-2008 Fabrice Bellard $ gns3 --version 1.5.2
参考資料
- Cumulus公式 / Using GNS3 with QEMU and KVM Virtual Machines
- これを見れば KVM + GNS3 で Cumulus VX を動かすところまでは問題ない筈
- Cumulus公式 / Download Cumulus VX
- イメージのダウンロードリンク
- Cumulus公式 / Cumulus Linux 3.2.1 Release Notes
- Early Access Features として EVPN が載っている
- Cumulus公式 / Ethernet Virtual Private Network - EVPN
- EVPN requires Cumulus Linux version 3.2.1 or newer.
- 現時点のEVPN回りのマニュアル
- 例示環境では BGP unnumbered を使っている
- Cumulus公式 / EVPN for controller-less VXLAN
- white paper
構築
以下のような環境を作ります。
GNS3 でデプロイ
以下の感じでデプロイしていきます。(陰っているところは、相互接続実験するための既存環境なので無視)
Cumulus VX に関しては、以下の公式docに従ってポチポチしとけばよいでしょー。
自分の環境では以下程度で十分でした。
kotetsu@kvm01:~$ ps aux | grep [C]umulus root 28241 2.5 1.3 1417576 445408 pts/12 Sl+ 20:32 0:20 /usr/bin/qemu-system-x86_64 -name CumulusVX_bb03 -m 512M -smp cpus=1 -enable-kvm -boot order=c -drive file=/home/kotetsu/GNS3/projects/vqfx/project-files/qemu/25f56fdc-48e7-4622-be73-bf98d5686e4e/hda_disk.qcow2,if=ide,index=0,media=disk -serial telnet:127.0.0.1:5018,server,nowait -monitor tcp:127.0.0.1:37529,server,nowait -net none -device virtio-net-pci,mac=00:37:c4:6e:4e:00,netdev=gns3-0 -netdev socket,id=gns3-0,udp=127.0.0.1:10102,localaddr=127.0.0.1:10103 -device virtio-net-pci,mac=00:37:c4:6e:4e:01,netdev=gns3-1 -netdev socket,id=gns3-1,udp=127.0.0.1:10125,localaddr=127.0.0.1:10124 -device virtio-net-pci,mac=00:37:c4:6e:4e:02,netdev=gns3-2 -netdev socket,id=gns3-2,udp=127.0.0.1:10129,localaddr=127.0.0.1:10128 -device virtio-net-pci,mac=00:37:c4:6e:4e:03,netdev=gns3-3 -netdev socket,id=gns3-3,udp=127.0.0.1:10133,localaddr=127.0.0.1:10132 -device virtio-net-pci,mac=00:37:c4:6e:4e:04,netdev=gns3-4 -netdev socket,id=gns3-4,udp=127.0.0.1:10137,localaddr=127.0.0.1:10136 -device virtio-net-pci,mac=00:37:c4:6e:4e:05
周辺機器設定
torSW[34]01a (Open vSwitch) 設定
Open vSwitch
の導入なんかは、適当に公式ドキュメントを見て進めて頂くとして。(雑)
以下のような設定をしておけば良いですよ。今回は Open vSwitch を使っていますが、ここに置くのは LACP と VLAN が動けばなんでもよいので、適当に各々が使いやすいやつを入れればよいかと。(勿論Cumulus VXでもok)
torSW[12]01a
共通
# ovs-vsctl --no-wait init # ovs-vsctl add-br br0 # ovs-vsctl set bridge br0 datapath_type=netdev # ovs-vsctl add-bond br0 bond0 ens4 ens5 lacp=active bond_mode=balance-slb other_config:lacp-time=fast # ovs-vsctl add-port br0 ens6 tag=100 # ovs-vsctl add-port br0 ens7 tag=200 # ip link set dev br0 up # ip link set dev ens4 up # ip link set dev ens5 up # ip link set dev ens6 up # ip link set dev ens7 up
通信確認用 node[34]1 設定
通信できりゃー何でもよいです。(雑)
kotetsu@node31:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:55:09:01 brd ff:ff:ff:ff:ff:ff inet 192.168.1.3/24 brd 192.168.1.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fe55:901/64 scope link valid_lft forever preferred_lft forever
kotetsu@node41:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:56:b4:01 brd ff:ff:ff:ff:ff:ff inet 192.168.1.4/24 brd 192.168.1.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fe56:b401/64 scope link valid_lft forever preferred_lft forever
Cumulus VX 初期設定
ログインアカウント/パスワードは Cumulus公式 / Using Cumulus VX with KVM に書いてある通り、ユーザ cumulus
パスワード CumulusLinux!
で
あとは
らへんを見ながら適当に...hostname、操作用ユーザ作成とssh鍵登録、syslog、timezone, ntp などの設定を環境に合わせた感じでどうぞ。
追加したユーザで net
コマンド各種を使いたい場合は /etc/netd.conf
で許可するユーザ、グループ設定を適宜編集して反映 (Cumulus公式 / Network Command Line Utility / Adding More NCLU Users or Groups)
Cumulus VX 物理IF/BGP設定
以下のような感じのを作っていきます。
物理IF
Cumulus公式 / Interface Configuration and Management あたりを参考に、まずはBGP構成をとるための物理IF設定を。
- bb03
net add interface swp1 alias DEV=spine31 IF=swp1 net add interface swp1 mtu 9216 net add interface swp1 ip address 192.0.2.8/31 net add interface swp2 alias DEV=spine32 IF=swp1 net add interface swp2 mtu 9216 net add interface swp2 ip address 192.0.2.10/31 net add interface swp3 alias DEV=spine41 IF=swp1 net add interface swp3 mtu 9216 net add interface swp3 ip address 192.0.2.12/31 net add interface swp4 alias DEV=spine42 IF=swp1 net add interface swp4 mtu 9216 net add interface swp4 ip address 192.0.2.14/31 net commit
kotetsu@bb03:~$ net show interface all Name Speed MTU Mode Summary ----- -------------------------- ------- ----- ------------- ------------------------ UP lo N/A 65536 Loopback IP: 127.0.0.1/8, ::1/128 UP eth0 1G 1500 Mgmt IP: 10.0.0.193/24 UP swp1 (DEV=spine31 IF=swp1) 1G 9216 Interface/L3 IP: 192.0.2.8/31 UP swp2 (DEV=spine32 IF=swp1) 1G 9216 Interface/L3 IP: 192.0.2.10/31 UP swp3 (DEV=spine41 IF=swp1) 1G 9216 Interface/L3 IP: 192.0.2.12/31 UP swp4 (DEV=spine42 IF=swp1) 1G 9216 Interface/L3 IP: 192.0.2.14/31 ADMDN swp5 0M 1500 NotConfigured
kotetsu@bb03:~$ cat /etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/*.intf # The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 address 10.0.0.193/24 gateway 10.0.0.254 auto swp1 iface swp1 address 192.0.2.8/31 alias DEV=spine31 IF=swp1 mtu 9216 auto swp2 iface swp2 address 192.0.2.10/31 alias DEV=spine32 IF=swp1 mtu 9216 auto swp3 iface swp3 address 192.0.2.12/31 alias DEV=spine41 IF=swp1 mtu 9216 auto swp4 iface swp4 address 192.0.2.14/31 alias DEV=spine42 IF=swp1 mtu 9216
- bb04
net add interface swp1 alias DEV=spine31 IF=swp2 net add interface swp1 mtu 9216 net add interface swp1 ip address 192.0.2.136/31 net add interface swp2 alias DEV=spine32 IF=swp2 net add interface swp2 mtu 9216 net add interface swp2 ip address 192.0.2.138/31 net add interface swp3 alias DEV=spine41 IF=swp2 net add interface swp3 mtu 9216 net add interface swp3 ip address 192.0.2.140/31 net add interface swp4 alias DEV=spine42 IF=swp2 net add interface swp4 mtu 9216 net add interface swp4 ip address 192.0.2.142/31 net commit
- spine31
net add interface swp1 alias DEV=bb03 IF=swp1 net add interface swp1 mtu 9216 net add interface swp1 ip address 192.0.2.9/31 net add interface swp2 alias DEV=bb04 IF=swp1 net add interface swp2 mtu 9216 net add interface swp2 ip address 192.0.2.137/31 net commit
- spine32
net add interface swp1 alias DEV=bb03 IF=swp2 net add interface swp1 mtu 9216 net add interface swp1 ip address 192.0.2.11/31 net add interface swp2 alias DEV=bb04 IF=swp2 net add interface swp2 mtu 9216 net add interface swp2 ip address 192.0.2.139/31 net commit
- spine41
net add interface swp1 alias DEV=bb03 IF=swp3 net add interface swp1 mtu 9216 net add interface swp1 ip address 192.0.2.13/31 net add interface swp2 alias DEV=bb04 IF=swp3 net add interface swp2 mtu 9216 net add interface swp2 ip address 192.0.2.141/31 net commit
- spine42
net add interface swp1 alias DEV=bb03 IF=swp4 net add interface swp1 mtu 9216 net add interface swp1 ip address 192.0.2.15/31 net add interface swp2 alias DEV=bb04 IF=swp4 net add interface swp2 mtu 9216 net add interface swp2 ip address 192.0.2.143/31 net commit
Early Access版Quagga導入
デフォルトは以下の感じなので Cumulus公式 / Ethernet Virtual Private Network - EVPN / Installing the EVPN Package に従い、Early Access版の Quagga を入れる。
kotetsu@bb03:~$ dpkg -l quagga Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) ||/ Name Version Architecture Description +++-=======================-================-================-==================================================== ii quagga 1.0.0+cl3u7 amd64 BGP/OSPF/RIP routing daemon
kotetsu@bb03:~$ grep -E "CumulusLinux-3-early-access" /etc/apt/sources.list #deb http://repo3.cumulusnetworks.com/repo CumulusLinux-3-early-access cumulus #deb-src http://repo3.cumulusnetworks.com/repo CumulusLinux-3-early-access cumulus
kotetsu@bb03:~$ sudo sed -i -e '/CumulusLinux-3-early-access/ s/^#//g' /etc/apt/sources.list
kotetsu@bb03:~$ sudo apt update kotetsu@bb03:~$ sudo apt install -y cumulus-evpn kotetsu@bb03:~$ sudo apt upgrade
kotetsu@bb03:~$ dpkg -l quagga Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) ||/ Name Version Architecture Description +++-=======================-================-================-==================================================== ii quagga 1.0.0+cl3eau8 amd64 BGP/OSPF/RIP routing daemon
Quagga起動設定
デフォルトは以下の感じなので Cumulus公式 / Configuring Cumulus Quagga あたりを参考に、全台で起動設定を。
kotetsu@bb03:~$ grep -Ev "^#" /etc/quagga/daemons zebra=no bgpd=no ospfd=no ospf6d=no ripd=no ripngd=no isisd=n
起動デーモン設定で zebra
と bgpd
を yes
に変えて
kotetsu@bb03:~$ sudo sed -r -i -e 's/(zebra|bgpd)=no/\1=yes/g' /etc/quagga/daemons
自動起動設定して起動
kotetsu@bb03:~$ sudo systemctl enable quagga.service kotetsu@bb03:~$ sudo systemctl start quagga.service
kotetsu@bb03:~$ sudo systemctl status quagga.service ... Active: active (running) since Mon 2017-03-20 10:52:25 JST; 4s ago Mar 20 10:52:24 spine41 quagga[30608]: Starting Quagga daemons (prio:10):. zebra. bgpd. Mar 20 10:52:24 spine41 bgpd[30631]: BGPd 1.0.0+cl3eau8 starting: vty@2605, bgp@<all>:179 Mar 20 10:52:24 spine41 zebra[30624]: client 12 says hello and bids fair to announce only bgp routes Mar 20 10:52:24 spine41 watchquagga[30638]: watchquagga 1.0.0+cl3eau8 watching [zebra bgpd], mode [phased zebra restart] Mar 20 10:52:24 spine41 watchquagga[30638]: bgpd state -> up : connect succeeded Mar 20 10:52:25 spine41 watchquagga[30638]: zebra state -> up : connect succeeded Mar 20 10:52:25 spine41 watchquagga[30638]: Watchquagga: Notifying Systemd we are up and running Mar 20 10:52:25 spine41 quagga[30608]: Starting Quagga monitor daemon: watchquagga. Mar 20 10:52:25 spine41 quagga[30608]: Exiting from the script Mar 20 10:52:25 spine41 systemd[1]: Started Cumulus Linux Quagga.
eBGP設定
bb03
net add loopback lo ip address 172.31.0.3/32 net add bgp autonomous-system 65000 net add bgp router-id 172.31.0.3 net add routing prefix-list ipv4 PL_LO_CLOS seq 10 permit 172.16.0.0/12 ge 32 le 32 net add routing prefix-list ipv4 PL_LO_CLOS seq 20 permit 192.0.2.0/24 ge 31 le 31 net add bgp redistribute connected net add bgp neighbor PEER_SPINE peer-group net add bgp neighbor PEER_SPINE prefix-list PL_LO_CLOS out net add bgp neighbor PEER_SPINE next-hop-self net add bgp neighbor 192.0.2.9 remote-as 65003 net add bgp neighbor 192.0.2.9 description spine31 net add bgp neighbor 192.0.2.9 peer-group PEER_SPINE net add bgp neighbor 192.0.2.11 remote-as 65003 net add bgp neighbor 192.0.2.11 description spine32 net add bgp neighbor 192.0.2.11 peer-group PEER_SPINE net add bgp neighbor 192.0.2.13 remote-as 65004 net add bgp neighbor 192.0.2.13 description spine41 net add bgp neighbor 192.0.2.13 peer-group PEER_SPINE net add bgp neighbor 192.0.2.15 remote-as 65004 net add bgp neighbor 192.0.2.15 description spine42 net add bgp neighbor 192.0.2.15 peer-group PEER_SPINE
bb04
net add loopback lo ip address 172.31.0.4/32 net add bgp autonomous-system 65000 net add bgp router-id 172.31.0.4 net add routing prefix-list ipv4 PL_LO_CLOS seq 10 permit 172.16.0.0/12 ge 32 le 32 net add routing prefix-list ipv4 PL_LO_CLOS seq 20 permit 192.0.2.0/24 ge 31 le 31 net add bgp redistribute connected net add bgp neighbor PEER_SPINE peer-group net add bgp neighbor PEER_SPINE prefix-list PL_LO_CLOS out net add bgp neighbor 192.0.2.137 remote-as 65003 net add bgp neighbor 192.0.2.137 description spine31 net add bgp neighbor 192.0.2.137 peer-group PEER_SPINE net add bgp neighbor 192.0.2.139 remote-as 65003 net add bgp neighbor 192.0.2.139 description spine32 net add bgp neighbor 192.0.2.139 peer-group PEER_SPINE net add bgp neighbor 192.0.2.141 remote-as 65004 net add bgp neighbor 192.0.2.141 description spine41 net add bgp neighbor 192.0.2.141 peer-group PEER_SPINE net add bgp neighbor 192.0.2.143 remote-as 65004 net add bgp neighbor 192.0.2.143 description spine42 net add bgp neighbor 192.0.2.143 peer-group PEER_SPINE
spine31
net add loopback lo ip address 172.16.3.1/32 net add bgp autonomous-system 65003 net add bgp router-id 172.16.3.1 net add routing prefix-list ipv4 PL_LO_CLOS seq 10 permit 172.16.0.0/12 ge 32 le 32 net add routing prefix-list ipv4 PL_LO_CLOS seq 20 permit 192.0.2.0/24 ge 31 le 31 net add bgp redistribute connected net add bgp neighbor PEER_BB peer-group net add bgp neighbor PEER_BB prefix-list PL_LO_CLOS out net add bgp neighbor 192.0.2.8 remote-as 65000 net add bgp neighbor 192.0.2.8 description bb03 net add bgp neighbor 192.0.2.8 peer-group PEER_BB net add bgp neighbor 192.0.2.136 remote-as 65000 net add bgp neighbor 192.0.2.136 description bb04 net add bgp neighbor 192.0.2.136 peer-group PEER_BB
spine32
net add loopback lo ip address 172.16.3.2/32 net add bgp autonomous-system 65003 net add bgp router-id 172.16.3.2 net add routing prefix-list ipv4 PL_LO_CLOS seq 10 permit 172.16.0.0/12 ge 32 le 32 net add routing prefix-list ipv4 PL_LO_CLOS seq 20 permit 192.0.2.0/24 ge 31 le 31 net add bgp redistribute connected net add bgp neighbor PEER_BB peer-group net add bgp neighbor PEER_BB prefix-list PL_LO_CLOS out net add bgp neighbor 192.0.2.10 remote-as 65000 net add bgp neighbor 192.0.2.10 description bb03 net add bgp neighbor 192.0.2.10 peer-group PEER_BB net add bgp neighbor 192.0.2.138 remote-as 65000 net add bgp neighbor 192.0.2.138 description bb04 net add bgp neighbor 192.0.2.138 peer-group PEER_BB
spine41
net add loopback lo ip address 172.16.4.1/32 net add bgp autonomous-system 65004 net add bgp router-id 172.16.4.1 net add routing prefix-list ipv4 PL_LO_CLOS seq 10 permit 172.16.0.0/12 ge 32 le 32 net add routing prefix-list ipv4 PL_LO_CLOS seq 20 permit 192.0.2.0/24 ge 31 le 31 net add bgp redistribute connected net add bgp neighbor PEER_BB peer-group net add bgp neighbor PEER_BB prefix-list PL_LO_CLOS out net add bgp neighbor 192.0.2.12 remote-as 65000 net add bgp neighbor 192.0.2.12 description bb03 net add bgp neighbor 192.0.2.12 peer-group PEER_BB net add bgp neighbor 192.0.2.140 remote-as 65000 net add bgp neighbor 192.0.2.140 description bb04 net add bgp neighbor 192.0.2.140 peer-group PEER_BB
spine42
net add loopback lo ip address 172.16.4.2/32 net add bgp autonomous-system 65004 net add bgp router-id 172.16.4.2 net add routing prefix-list ipv4 PL_LO_CLOS seq 10 permit 172.16.0.0/12 ge 32 le 32 net add routing prefix-list ipv4 PL_LO_CLOS seq 20 permit 192.0.2.0/24 ge 31 le 31 net add bgp redistribute connected net add bgp neighbor PEER_BB peer-group net add bgp neighbor PEER_BB prefix-list PL_LO_CLOS out net add bgp neighbor 192.0.2.14 remote-as 65000 net add bgp neighbor 192.0.2.14 description bb03 net add bgp neighbor 192.0.2.14 peer-group PEER_BB net add bgp neighbor 192.0.2.142 remote-as 65000 net add bgp neighbor 192.0.2.142 description bb04 net add bgp neighbor 192.0.2.142 peer-group PEER_BB
ちなみに...neighbor
設定をしようと何となく tab
を押したら、LLDPで得た隣接機器の情報と物理IFのマッピングが表示された...しゅごい...。
kotetsu@bb03:~$ net add bgp neighbor <bgppeer> : BGP neighbor or peer-group <interface> : An interface name "swp1" or glob "swp1-4,6,10-12" <ip> : An IPv4 or IPv6 Address <text-peer-group> : A BGP peer-group name eth0 : LLDP peer spine41 lo : interface swp1 : LLDP peer spine31 swp2 : LLDP peer spine32 swp3 : LLDP peer spine41 swp4 : LLDP peer spine42 swp5 : interface
Cumulus VX MLAG 設定
Cumulus公式 / Multi-Chassis Link Aggregation - MLAG あたりを参考に
MLAG Interlink 設定
まずは MLAG 用の LAG 設定を Cumulus公式 / Bonding - Link Aggregation あたりを参考に設定していきます。 組める最低限の設定だけ...。
spine31
net add bond bond0 bond slaves swp3-4 net add bond bond0 alias DEV=spine32 IF=bond0 net add interface bond0.4094 alias MLAG DEDICATED net add interface bond0.4094 ip address 198.51.100.1/30 net add interface bond0.4094 clag peer-ip 198.51.100.2 net add interface bond0.4094 clag sys-mac 44:38:39:FF:40:94
spine32
net add bond bond0 bond slaves swp3-4 net add bond bond0 alias DEV=spine31 IF=bond0 net add interface bond0.4094 alias MLAG DEDICATED net add interface bond0.4094 ip address 198.51.100.2/30 net add interface bond0.4094 clag peer-ip 198.51.100.1 net add interface bond0.4094 clag sys-mac 44:38:39:FF:40:94
spine41
net add bond bond0 bond slaves swp3-4 net add bond bond0 alias DEV=spine42 IF=bond0 net add interface bond0.4094 alias MLAG DEDICATED net add interface bond0.4094 ip address 198.51.100.1/30 net add interface bond0.4094 clag peer-ip 198.51.100.2 net add interface bond0.4094 clag sys-mac 44:38:39:FF:40:94
spine42
net add bond bond0 bond slaves swp3-4 net add bond bond0 alias DEV=spine41 IF=bond0 net add interface bond0.4094 alias MLAG DEDICATED net add interface bond0.4094 ip address 198.51.100.2/30 net add interface bond0.4094 clag peer-ip 198.51.100.1 net add interface bond0.4094 clag sys-mac 44:38:39:FF:40:94
こんな感じで MLAG が組めている筈。
kotetsu@spine31:~$ net show clag status The peer is alive Peer Priority, ID, and Role: 32768 00:37:c4:a9:0f:03 primary Our Priority, ID, and Role: 32768 00:37:c4:f8:17:03 secondary Peer Interface and IP: bond0.4094 198.51.100.2 Backup IP: (inactive) System MAC: 44:38:39:ff:40:94
kotetsu@spine32:~$ net show clag status The peer is alive Our Priority, ID, and Role: 32768 00:37:c4:a9:0f:03 primary Peer Priority, ID, and Role: 32768 00:37:c4:f8:17:03 secondary Peer Interface and IP: bond0.4094 198.51.100.1 Backup IP: (inactive) System MAC: 44:38:39:ff:40:94
MLAG DownLink 設定
spine3[12]
net add bond bond1 bond slaves swp5 net add bond bond1 alias DEV=torSW301a IF=bond0 net add bond bond1 mtu 9000 net add bond bond1 clag id 1
spine4[12]
net add bond bond1 bond slaves swp5 net add bond bond1 alias DEV=torSW401a IF=bond0 net add bond bond1 mtu 9000 net add bond bond1 clag id 1
bridge 設定
spine[34][12]
全台で
例によって Cumulus公式 / VLAN-aware Bridge Mode for Large-scale Layer 2 Environments を参考にして
net add bridge bridge ports bond0 net add bridge bridge ports bond1 net add bridge bridge vids 2-4093
torSW での LACP 状態確認
root@torSW301a:~# ovs-appctl lacp/show bond0 ---- bond0 ---- status: active negotiated sys_id: 00:37:c4:7e:e0:01 sys_priority: 65534 aggregation key: 1 lacp_time: fast slave: ens4: current attached port_id: 2 port_priority: 65535 may_enable: true actor sys_id: 00:37:c4:7e:e0:01 actor sys_priority: 65534 actor port_id: 2 actor port_priority: 65535 actor key: 1 actor state: activity timeout aggregation synchronized collecting distributing partner sys_id: 44:38:39:ff:40:94 partner sys_priority: 65535 partner port_id: 1 partner port_priority: 255 partner key: 9 partner state: activity timeout aggregation synchronized collecting distributing slave: ens5: current attached port_id: 1 port_priority: 65535 may_enable: true actor sys_id: 00:37:c4:7e:e0:01 actor sys_priority: 65534 actor port_id: 1 actor port_priority: 65535 actor key: 1 actor state: activity timeout aggregation synchronized collecting distributing partner sys_id: 44:38:39:ff:40:94 partner sys_priority: 65535 partner port_id: 1 partner port_priority: 255 partner key: 9 partner state: activity timeout aggregation synchronized collecting distributing
root@torSW401a:~# ovs-appctl lacp/show bond0 ---- bond0 ---- status: active negotiated sys_id: 00:37:c4:2c:e5:01 sys_priority: 65534 aggregation key: 1 lacp_time: fast slave: ens4: current attached port_id: 1 port_priority: 65535 may_enable: true actor sys_id: 00:37:c4:2c:e5:01 actor sys_priority: 65534 actor port_id: 1 actor port_priority: 65535 actor key: 1 actor state: activity timeout aggregation synchronized collecting distributing partner sys_id: 44:38:39:ff:40:94 partner sys_priority: 65535 partner port_id: 1 partner port_priority: 255 partner key: 9 partner state: activity timeout aggregation synchronized collecting distributing slave: ens5: current attached port_id: 2 port_priority: 65535 may_enable: true actor sys_id: 00:37:c4:2c:e5:01 actor sys_priority: 65534 actor port_id: 2 actor port_priority: 65535 actor key: 1 actor state: activity timeout aggregation synchronized collecting distributing partner sys_id: 44:38:39:ff:40:94 partner sys_priority: 65535 partner port_id: 1 partner port_priority: 255 partner key: 9 partner state: activity timeout aggregation synchronized collecting distributing
Cumulus VX VXLAN+EVPN 設定
仮想VTEPごとの仮想IPアドレス設定
spine3[12]
net add loopback lo clag vxlan-anycast-ip 172.16.3.100
spine4[12]
net add loopback lo clag vxlan-anycast-ip 172.16.4.100
本環境では redistribute connected
で BGP ipv4 に流していて out
でかけている prefix-list
にもマッチする設定にしたので、これでこの仮想IPアドレスも広告される筈
kotetsu@bb03:~$ net show route show ip route ============= Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, P - PIM, T - Table, v - VNC, V - VPN, > - selected route, * - FIB route K>* 0.0.0.0/0 via 10.0.0.254, eth0 C>* 10.0.0.0/24 is directly connected, eth0 B>* 172.16.3.1/32 [20/0] via 192.0.2.9, swp1, 08:58:27 B>* 172.16.3.2/32 [20/0] via 192.0.2.11, swp2, 08:57:25 B>* 172.16.3.100/32 [20/0] via 192.0.2.9, swp1, 00:28:29 * via 192.0.2.11, swp2, 00:28:29 B>* 172.16.4.1/32 [20/0] via 192.0.2.13, swp3, 08:56:25 B>* 172.16.4.2/32 [20/0] via 192.0.2.15, swp4, 08:56:10 B>* 172.16.4.100/32 [20/0] via 192.0.2.15, swp4, 00:27:45 * via 192.0.2.13, swp3, 00:27:45 C>* 172.31.0.3/32 is directly connected, lo C>* 192.0.2.8/31 is directly connected, swp1 C>* 192.0.2.10/31 is directly connected, swp2 C>* 192.0.2.12/31 is directly connected, swp3 C>* 192.0.2.14/31 is directly connected, swp4 B>* 192.0.2.136/31 [20/0] via 192.0.2.9, swp1, 08:58:27 B>* 192.0.2.138/31 [20/0] via 192.0.2.11, swp2, 08:57:25 B>* 192.0.2.140/31 [20/0] via 192.0.2.13, swp3, 08:56:25 B>* 192.0.2.142/31 [20/0] via 192.0.2.15, swp4, 08:56:10
spine全台にVXLAN VNI設定
spine[34][12]
net add vxlan vxlan010100 vxlan id 10100 net add vxlan vxlan010100 bridge access 100 net add vxlan vxlan010200 vxlan id 10200 net add vxlan vxlan010200 bridge access 200
これで net commit
すると、この vxlan インターフェース群は自動的に bridge にくっついてくる
kotetsu@spine42:~$ net commit --- /etc/network/interfaces 2017-03-20 22:07:22.297455993 +0900 +++ /var/run/nclu/iface/interfaces.tmp 2017-03-20 22:17:54.341064283 +0900 ... iface bridge - bridge-ports bond0 bond1 + bridge-ports bond0 bond1 vxlan010100 vxlan010200 ...
全台にVXLAN Tunnel IPアドレスを付与
spine31
net add vxlan vxlan010100 vxlan local-tunnelip 172.16.3.1 net add vxlan vxlan010200 vxlan local-tunnelip 172.16.3.1
spine32
net add vxlan vxlan010100 vxlan local-tunnelip 172.16.3.2 net add vxlan vxlan010200 vxlan local-tunnelip 172.16.3.2
spine41
net add vxlan vxlan010100 vxlan local-tunnelip 172.16.4.1 net add vxlan vxlan010200 vxlan local-tunnelip 172.16.4.1
spine42
net add vxlan vxlan010100 vxlan local-tunnelip 172.16.4.2 net add vxlan vxlan010200 vxlan local-tunnelip 172.16.4.2
EVPN 有効化~設定
Cumulus公式 / Ethernet Virtual Private Network - EVPN / Configuring EVPN に従って設定していきます。
Early Access 版の機能(quagga限定でCLIまでは)どうも探した感じでは net
コマンドはまだ用意されていないようなので、従来の Quagga 設定で
kotetsu@spine41:~$ sudo vtysh Hello, this is Quagga (version 1.0.0+cl3eau8). Copyright 1996-2005 Kunihiro Ishiguro, et al. spine41# spine41# configure terminal spine41(config)# router bgp 65004 spine41(config-router)# address-family evpn spine41(config-router-af)# neighbor PEER_BB activate spine41(config-router-af)# advertise-all-vni spine41(config-router-af)# end spine41# write memory Note: this version of vtysh never writes vtysh.conf Building Configuration... Integrated configuration saved to /etc/quagga/Quagga.conf [OK] spine41# spine41# exit kotetsu@spine41:~$
以下のような設定を
bb0[34]
router bgp 65000 address-family evpn neighbor PEER_SPINE activate
spine3[12]
router bgp 65003 address-family evpn neighbor PEER_BB activate advertise-all-vni
spine4[12]
router bgp 65004 address-family evpn neighbor PEER_BB activate advertise-all-vni
Disabling Data Plane MAC Learning over VXLAN Tunnels
spine[34][12]
にて /etc/network/interfaces
を編集して、全vxlanインターフェースに bridge-learning off
を追記しておきます。
kotetsu@spine31:~$ diff -u /var/tmp/etc_network_interfaces /etc/network/interfaces --- /var/tmp/etc_network_interfaces 2017-03-20 23:19:45.046311072 +0900 +++ /etc/network/interfaces 2017-03-20 23:20:33.701311345 +0900 @@ -64,6 +64,7 @@ auto vxlan010100 iface vxlan010100 bridge-access 100 + bridge-learning off mstpctl-bpduguard yes mstpctl-portbpdufilter yes vxlan-id 10100 @@ -72,6 +73,7 @@ auto vxlan010200 iface vxlan010200 bridge-access 200 + bridge-learning off mstpctl-bpduguard yes mstpctl-portbpdufilter yes vxlan-id 10200
動作確認
通信確認
End End での通信確認(L2 over L3)
kotetsu@node31:~$ ping 192.168.1.4 PING 192.168.1.4 (192.168.1.4) 56(84) bytes of data. 64 bytes from 192.168.1.4: icmp_seq=1 ttl=64 time=4.67 ms 64 bytes from 192.168.1.4: icmp_seq=2 ttl=64 time=1.86 ms 64 bytes from 192.168.1.4: icmp_seq=3 ttl=64 time=1.81 ms 64 bytes from 192.168.1.4: icmp_seq=4 ttl=64 time=1.94 ms 64 bytes from 192.168.1.4: icmp_seq=5 ttl=64 time=2.07 ms 64 bytes from 192.168.1.4: icmp_seq=6 ttl=64 time=1.24 ms 64 bytes from 192.168.1.4: icmp_seq=7 ttl=64 time=1.78 ms ^C --- 192.168.1.4 ping statistics --- 7 packets transmitted, 7 received, 0% packet loss, time 6009ms rtt min/avg/max/mdev = 1.241/2.199/4.677/1.041 ms
kotetsu@node31:~$ ip n show 192.168.1.4 dev ens4 lladdr 00:37:c4:56:b4:01 STALE
kotetsu@node41:~$ ip n show 192.168.1.3 dev ens4 lladdr 00:37:c4:55:09:01 STALE
Cumulus VX 各種テーブル確認
Cumulus公式 / Ethernet Virtual Private Network - EVPN / Output Commands に参照系のコマンドが色々と提示されているので、それを見ながら。
spine MAC アドレステーブル
まずは VTEP, EVPN PE として動作している spine 群の MAC アドレステーブルを。
TunnelDest
列で対向 VTEP の共有loopback IPアドレスを使っていることが伺えるMAC
列で00:00:00:00:00:00
と表示されているのはBUM traffic replication
らしい(公式の記載より)
kotetsu@spine31:~$ net show bridge macs VLAN Master Interface MAC TunnelDest State Flags LastSeen -------- -------- ----------- ----------------- ------------ --------- ------- ---------- 100 bridge bond1 00:37:c4:55:09:01 00:01:43 100 bridge vxlan010100 00:37:c4:56:b4:01 00:03:52 untagged vxlan010100 00:00:00:00:00:00 172.16.4.100 permanent self 01:08:33 untagged vxlan010100 00:37:c4:56:b4:01 172.16.4.100 self 00:03:58 untagged vxlan010200 00:00:00:00:00:00 172.16.4.100 permanent self 01:08:33 untagged bridge bond0 00:37:c4:f8:17:03 permanent 05:38:27 untagged bridge bond1 00:37:c4:f8:17:05 permanent 03:42:10 untagged bridge vxlan010100 a6:21:d1:0c:20:a8 permanent 02:20:01 untagged bridge vxlan010200 de:8e:ed:62:05:12 permanent 02:20:01
kotetsu@spine32:~$ net show bridge macs VLAN Master Interface MAC TunnelDest State Flags LastSeen -------- -------- ----------- ----------------- ------------ --------- ------- ---------- 100 bridge bond1 00:37:c4:55:09:01 00:04:45 100 bridge vxlan010100 00:37:c4:56:b4:01 00:04:51 untagged vxlan010100 00:00:00:00:00:00 172.16.4.100 permanent self 01:09:25 untagged vxlan010100 00:37:c4:56:b4:01 172.16.4.100 self 00:04:51 untagged vxlan010200 00:00:00:00:00:00 172.16.4.100 permanent self 01:09:25 untagged bridge bond0 00:37:c4:a9:0f:03 permanent 05:38:42 untagged bridge bond1 00:37:c4:a9:0f:05 permanent 03:42:00 untagged bridge vxlan010100 ea:60:31:c9:77:63 permanent 02:18:00 untagged bridge vxlan010200 06:f9:9e:92:a4:c0 permanent 02:18:00
kotetsu@spine41:~$ net show bridge macs VLAN Master Interface MAC TunnelDest State Flags LastSeen -------- -------- ----------- ----------------- ------------ --------- ------- ---------- 100 bridge bond1 00:37:c4:56:b4:01 00:01:43 100 bridge vxlan010100 00:37:c4:55:09:01 00:01:49 untagged vxlan010100 00:00:00:00:00:00 172.16.3.100 permanent self 01:06:24 untagged vxlan010100 00:37:c4:55:09:01 172.16.3.100 self 00:01:49 untagged vxlan010200 00:00:00:00:00:00 172.16.3.100 permanent self 01:06:24 untagged bridge bond0 00:37:c4:fe:34:03 permanent 05:34:25 untagged bridge bond1 00:37:c4:fe:34:05 permanent 03:35:31 untagged bridge vxlan010100 46:bf:75:c3:83:e3 permanent 02:14:34 untagged bridge vxlan010200 ca:4e:29:fd:d9:8e permanent 02:14:34
kotetsu@spine42:~$ net show bridge macs VLAN Master Interface MAC TunnelDest State Flags LastSeen -------- -------- ----------- ----------------- ------------ --------- ------- ---------- 100 bridge bond1 00:37:c4:56:b4:01 00:00:46 100 bridge vxlan010100 00:37:c4:55:09:01 00:02:49 untagged vxlan010100 00:00:00:00:00:00 172.16.3.100 permanent self 01:07:29 untagged vxlan010100 00:37:c4:55:09:01 172.16.3.100 self 00:02:55 untagged vxlan010200 00:00:00:00:00:00 172.16.3.100 permanent self 01:07:29 untagged bridge bond0 00:37:c4:32:db:03 permanent 05:35:24 untagged bridge bond1 00:37:c4:32:db:05 permanent 03:36:18 untagged bridge vxlan010100 9e:e4:df:d2:a9:3a permanent 02:15:20 untagged bridge vxlan010200 6a:3a:0d:08:fb:9e permanent 02:15:20
広告している VNI や VTEP 情報
sudo vtysh
から
spine31# show bgp evpn vni Advertise All VNI flag: Enabled Number of VNIs: 2 Flags: * - Kernel VNI Orig IP RD Import RT Export RT * 10200 172.16.3.100 172.16.3.1:10200 65003:10200 65003:10200 * 10100 172.16.3.100 172.16.3.1:10100 65003:10100 65003:10100 spine31# show evpn vni Number of VNIs: 2 VNI VxLAN IF VTEP IP # MACs Remote VTEPs 10200 vxlan010200 172.16.3.100 0 172.16.4.100 10100 vxlan010100 172.16.3.100 2 172.16.4.100
spine32# show bgp evpn vni Advertise All VNI flag: Enabled Number of VNIs: 2 Flags: * - Kernel VNI Orig IP RD Import RT Export RT * 10200 172.16.3.100 172.16.3.2:10200 65003:10200 65003:10200 * 10100 172.16.3.100 172.16.3.2:10100 65003:10100 65003:10100 spine32# show evpn vni Number of VNIs: 2 VNI VxLAN IF VTEP IP # MACs Remote VTEPs 10200 vxlan010200 172.16.3.100 0 172.16.4.100 10100 vxlan010100 172.16.3.100 2 172.16.4.100
spine41# show bgp evpn vni Advertise All VNI flag: Enabled Number of VNIs: 2 Flags: * - Kernel VNI Orig IP RD Import RT Export RT * 10200 172.16.4.100 172.16.4.1:10200 65004:10200 65004:10200 * 10100 172.16.4.100 172.16.4.1:10100 65004:10100 65004:10100 spine41# show evpn vni Number of VNIs: 2 VNI VxLAN IF VTEP IP # MACs Remote VTEPs 10200 vxlan010200 172.16.4.100 0 172.16.3.100 10100 vxlan010100 172.16.4.100 2 172.16.3.100
spine42# show bgp evpn vni Advertise All VNI flag: Enabled Number of VNIs: 2 Flags: * - Kernel VNI Orig IP RD Import RT Export RT * 10200 172.16.4.100 172.16.4.2:10200 65004:10200 65004:10200 * 10100 172.16.4.100 172.16.4.2:10100 65004:10100 65004:10100 spine42# show evpn vni Number of VNIs: 2 VNI VxLAN IF VTEP IP # MACs Remote VTEPs 10200 vxlan010200 172.16.4.100 0 172.16.3.100 10100 vxlan010100 172.16.4.100 2 172.16.3.100
EVPN 学習経路
自ASの別 spine
からの経路を bb
経由で受け取るように設定してはいないので、RDとしても登場しないです。
自ASのMAC学習同期は、MLAGで良きようにやってくれる筈だから、それで良いかと。
また EVPN Multihoming を使った際には必要になる Type 1,4 に関しても一切情報が登場しません。
suto vtysh
から
spine31# show bgp evpn route BGP table version is 0, local router ID is 172.16.3.1 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal Origin codes: i - IGP, e - EGP, ? - incomplete EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC] EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP] Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 172.16.3.1:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 32768 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 32768 i Route Distinguisher: 172.16.3.1:10200 *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 32768 i Route Distinguisher: 172.16.4.1:10100 * [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65000 65004 i *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65000 65004 i * [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i Route Distinguisher: 172.16.4.1:10200 * [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i Route Distinguisher: 172.16.4.2:10100 * [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65000 65004 i *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65000 65004 i * [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i Route Distinguisher: 172.16.4.2:10200 * [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i Displayed 9 prefixes (15 paths)
spine32# show bgp evpn route BGP table version is 0, local router ID is 172.16.3.2 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal Origin codes: i - IGP, e - EGP, ? - incomplete EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC] EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP] Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 172.16.3.2:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 32768 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 32768 i Route Distinguisher: 172.16.3.2:10200 *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 32768 i Route Distinguisher: 172.16.4.1:10100 * [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65000 65004 i *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65000 65004 i * [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i Route Distinguisher: 172.16.4.1:10200 * [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i Route Distinguisher: 172.16.4.2:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65000 65004 i * [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65000 65004 i * [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i Route Distinguisher: 172.16.4.2:10200 * [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65000 65004 i Displayed 9 prefixes (15 paths)
spine41# show bgp evpn route BGP table version is 0, local router ID is 172.16.4.1 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal Origin codes: i - IGP, e - EGP, ? - incomplete EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC] EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP] Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 172.16.3.1:10100 * [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65000 65003 i *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65000 65003 i * [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i Route Distinguisher: 172.16.3.1:10200 * [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i Route Distinguisher: 172.16.3.2:10100 * [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65000 65003 i *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65000 65003 i * [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i Route Distinguisher: 172.16.3.2:10200 * [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i Route Distinguisher: 172.16.4.1:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 32768 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 32768 i Route Distinguisher: 172.16.4.1:10200 *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 32768 i Displayed 9 prefixes (15 paths)
spine42# show bgp evpn route BGP table version is 0, local router ID is 172.16.4.2 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal Origin codes: i - IGP, e - EGP, ? - incomplete EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC] EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP] Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 172.16.3.1:10100 * [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65000 65003 i *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65000 65003 i * [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i Route Distinguisher: 172.16.3.1:10200 * [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i Route Distinguisher: 172.16.3.2:10100 * [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65000 65003 i *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65000 65003 i * [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i Route Distinguisher: 172.16.3.2:10200 * [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65000 65003 i Route Distinguisher: 172.16.4.2:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 32768 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 32768 i Route Distinguisher: 172.16.4.2:10200 *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 32768 i Displayed 9 prefixes (15 paths)
VXLAN関係にはノータッチで転送土管に徹する bb
も、EVPN signaling 用のMP-BGPには参加します。
bb03# show bgp evpn route BGP table version is 0, local router ID is 172.31.0.3 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal Origin codes: i - IGP, e - EGP, ? - incomplete EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC] EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP] Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 172.16.3.1:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65003 i Route Distinguisher: 172.16.3.1:10200 *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65003 i Route Distinguisher: 172.16.3.2:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65003 i Route Distinguisher: 172.16.3.2:10200 *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65003 i Route Distinguisher: 172.16.4.1:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65004 i Route Distinguisher: 172.16.4.1:10200 *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65004 i Route Distinguisher: 172.16.4.2:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65004 i Route Distinguisher: 172.16.4.2:10200 *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65004 i Displayed 12 prefixes (12 paths)
bb04# show bgp evpn route BGP table version is 0, local router ID is 172.31.0.4 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal Origin codes: i - IGP, e - EGP, ? - incomplete EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC] EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP] Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 172.16.3.1:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65003 i Route Distinguisher: 172.16.3.1:10200 *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65003 i Route Distinguisher: 172.16.3.2:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] 172.16.3.100 0 65003 i *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65003 i Route Distinguisher: 172.16.3.2:10200 *> [3]:[0]:[32]:[172.16.3.100] 172.16.3.100 0 65003 i Route Distinguisher: 172.16.4.1:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65004 i Route Distinguisher: 172.16.4.1:10200 *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65004 i Route Distinguisher: 172.16.4.2:10100 *> [2]:[0]:[0]:[48]:[00:37:c4:56:b4:01] 172.16.4.100 0 65004 i *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65004 i Route Distinguisher: 172.16.4.2:10200 *> [3]:[0]:[32]:[172.16.4.100] 172.16.4.100 0 65004 i Displayed 12 prefixes (12 paths)
EVPN 学習経路(特定RDをドリルダウンして)
sudo vtysh
から
bb03# show bgp evpn route rd 172.16.3.2:10100 EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC] EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP] BGP routing table entry for 172.16.3.2:10100:[2]:[0]:[0]:[48]:[00:37:c4:55:09:01] Paths: (1 available, best #1) Advertised to non peer-group peers: spine31(192.0.2.9) spine32(192.0.2.11) spine41(192.0.2.13) spine42(192.0.2.15) Route [2]:[0]:[0]:[48]:[00:37:c4:55:09:01] VNI 10100 65003 172.16.3.100 from spine32(192.0.2.11) (172.16.3.2) Origin IGP, localpref 100, valid, external, bestpath-from-AS 65003, best Extended Community: RT:65003:10100 ET:8 AddPath ID: RX 0, TX 138 Last update: Tue Mar 21 21:51:06 2017 BGP routing table entry for 172.16.3.2:10100:[3]:[0]:[32]:[172.16.3.100] Paths: (1 available, best #1) Advertised to non peer-group peers: spine31(192.0.2.9) spine32(192.0.2.11) spine41(192.0.2.13) spine42(192.0.2.15) Route [3]:[0]:[32]:[172.16.3.100] 65003 172.16.3.100 from spine32(192.0.2.11) (172.16.3.2) Origin IGP, localpref 100, valid, external, bestpath-from-AS 65003, best Extended Community: RT:65003:10100 ET:8 AddPath ID: RX 0, TX 110 Last update: Tue Mar 21 20:57:31 2017
パケットを眺める
ControlPlane
EVPN NLRI Type3(Inclusive Multicast Ethernet Tag route)
spine41
が bb03
と eBGP OPEN 直後に送信している UPDATE です。
(EVPN Multihoming との比較という意味で)注目すべきは Originating Router's IP Address
として spine4[12]
で組んでいる共有?loopback IPアドレス(172.16.4.100
)が入っていることでしょう。
また Cumulus公式 / Ethernet Virtual Private Network - EVPN / Enabling EVPN with Route Distinguishers (RDs) and Route Targets (RTs)andRouteTargets(RTs)) に記載がある通り、RD
や RT
は明示的に設定せずとも自動付与された情報が入っています。
EVPN NLRI Type2(MAC/IP Advertisement route)
spine41
が bb03
に node41(at VLAN100:VNI10100)
の MAC アドレスを広告する図です。
DataPlane
BUM
node31
からの ARP Request は spine31
から bb03
に送信されています。
VXLANカプセル外側の IP ヘッダを見ると、Src が 172.16.3.100 (spine3[12] の共有lo IPaddr)
で Dst が 172.16.4.100(spine4[12] の共有loopback IPアドレス)
になっており、各ペアが2台で共有?loopback IPアドレスを使った論理?VTEPを構成していることが分かります。
VXLAN 的には HER(Head End Replication) 動作。
なお、2017/03/21
時点で公式ページのHERに関する注意書きを読むと、HER で構成可能な VTEP 数は 128 だそうです。
Cumulus Linux verified support for up to 128 VTEPs with head end replication.
Unicast
spine41
から bb04
方面に送信される node41
から node31
への ICMP Echo Reply の様子。
ただのVXLANカプセル化されたパケットですが、外側のIPヘッダを見ると共有loopback同士での通信になっています。
MLAG 動作
単なる MLAG の切り替わりでしかなく、仮想環境での障害試験なので、超簡単に...。
トラフィック が bb03 -> spine41 -> torSW401a -> node41
という経路で流れている状態で spine41
の downlink を sudo ifdown swp5
で down させると、即時
bb03 -> spine41 -> spine42 -> torSW401a -> node41
という経路に切り替わりました。
spine4[12]
で torSW401a
に組んでいる LAG や仮想loopbackは up したままなので、特に EVPN 的な WithDrawn なども発生せずです。
おしまい
以下、所感です。
- Cumulus Linux
- VX の軽さが良い
- Network Command Line Utility(NCLU) というラッパの使い勝手が良い
- ドキュメントがちゃんと揃っているのが良い (今回とりあげたのは EA 版機能なのに)
- だから僕の説明が雑なのは仕方ない
vQFX10000 で VXLAN+EVPN (Multihoming 編) (original : 2017/02/28)
この記事は某所で 2017/02/28
に書いたもののコピーです。
そのため 2017/05/13
時点ではやや古い情報も含まれています。
201705
にGNS3 ver2.0 stable
が出たので
.
- 最初に
- 構築~動作確認
- おしまい
最初に
本項でやること
以下をやります。
- 先日「vQFX10000 で VXLAN+EVPN (L2 over L3 編)」で動かした構成を冗長化する
- RFC7432(BGP MPLS-Based Ethernet VPN)に書かれた Multihoming を動かして様子を見る
- 構成図でいう spine 群(VTEP と EVI の役割を担う)の下側
- これがメイン
- マルチパスBGPもついでに組んでおく
- 構成図でいう spine 群(VTEP と EVI の役割を担う)の上側
- 単にマルチパスなBGP構成にしただけで、サラリと流す
- ここ数年、あちこちのデータセンタ事業者とかメーカとかが IP CLOS Network として提示しているアレ
- RFC7432(BGP MPLS-Based Ethernet VPN)に書かれた Multihoming を動かして様子を見る
個人的には、2014/12 時点で物理スイッチでの VXLAN 実装を確認した時 (VyOS と Arista で VXLAN 相互接続)に、VTEPの冗長化手法が分からなかった(配下のノードで bonding なり VRRP なりで制御せざるを得ないと考えていた)ので、それを標準化技術で実現する手法として期待を持っていたりします。
概要構成図 / 構成簡易解説 / 環境情報
下図のようなものを作っていきます。
bb0[12]
spien[12]{2}
- DataPlane としては VTEP 動作
- ControlPlane としては EVPN の PE 動作
torSW[12]01a
- VLAN tag 処理をする単純なL2SW
冗長化の方式としては、構成図の下線で書いた通りで、以下の感じ。
bb0[12]
-spien[12]{2}
- Underlay の eBGP では PerPacket の ECMP を動かす
- Overlay の iBGP では
bb0[12]
が RouteReflector となる 1 クラスタにする
spine[12]{2}
-torSW[12]01a
spine[12]{2}
は 2台1組でtorSW[12]01a
に対して LAG を組むspine1[12]
とtorSW101a
spine2[12]
とtorSW201a
spine[12]{2}
の EVPN 動作としては- その LAG を EthernetSegment(ES) として扱う
- その LAG に EVPN 世界内で一意になるように EthernetSegmentID(ESI) を付与して識別する
- 今回の構成例だと、
spine1[12]
のae0
とspine2[12]
のae0
が重複してはいけない
- 今回の構成例だと、
- ESI を EVPN NLRI Type4(Ethernet Segment route) で広告しあうことで、相互に誰とLAGを組んでいるかを識別したり・誰が各 ES の Designated Forwarder(DF)になるかの Election をしたりできる
- 各 LAG で DF になっている PE だけが EVPN/VXLAN 側(=図中の上側)から来た BUM トラフィックを VLAN 側(=図中の下側)にフォワードする
torSW[12]01a
- 対向が2台いるとか Multihoming してるとか一切気にする必要なく、単に LACP で LAG 組めば OK
そんなわけで、今までは VLAN Tag の処理だけしていれば良かった torSW[12]01a
に新たに「LACP を使えること」という要件が出てきたので、今回は GNS3 の EthernetSwitch ではなく Open vSwitch
を使います。
環境情報は最初から変わらずです。
今回新たに登場した torSW[12]01a
は(詳細は後述しますが)、 Ubuntu16.04.1-server-amd64
+ ovs_version: "2.5.0"
です。
参考資料
- 前回の参考資料 全般
- Juniper での EVPN Multihoming 実装周り
- Juniper公式 / MC-LAG is dead, Long live EVPN Multi-homing
- タイトルは若干釣り気味だけど「MC-LAG と比べて EVPN Multihoming はこう凄いよ(MC-LAGだって十分すげーけどな!)」的な概念説明記事
- Juniper公式 / EVPN Multihoming Overview
- EVPN Multihoming マニュアル
- Juniper公式 / MC-LAG is dead, Long live EVPN Multi-homing
- Underlay の Clos Network 周り
- O'Reilly Juniper QFX10000 Series
- Juniper QFX10000 の独自プロセッサ開発経緯や特徴・Architecture(HW/SW) の結構詳しい説明・MPLS/VXLAN+EVPNの設計ポイント解説などが纏まった非常に良い本
Juniper QFX10000 Series: A Comprehensive Guide to Building Next-Generation Data Centers
- 作者: Douglas Richard, Jr. Hanks
- 出版社/メーカー: O'Reilly Media
- 発売日: 2016/08/11
- メディア: ペーパーバック
- この商品を含むブログを見る
- Juniper QFX10000 の独自プロセッサ開発経緯や特徴・Architecture(HW/SW) の結構詳しい説明・MPLS/VXLAN+EVPNの設計ポイント解説などが纏まった非常に良い本
構築~動作確認
GNS3 でデプロイ
前回の環境を引き続き使っていますが、ポチポチとvQFX のデプロイと、Open vSwitch
を動かす Ubuntu のデプロイをしていきます。
以下の感じで。
例によって、GNS3
のバージョンは 1.5.2
を使っているので、パケットキャプチャ用に EthernetSwitch(図中の cap
ではじまるやつら) を挟んでますよ。
余談。
最初、Open vSwitch
は手軽に docker で動かしたんですよ。(以下、参考リンク)
- GNS3 公式フォーラム / New appliance supported: Open vSwitch
- github / Docker Open vSwitch for GNS3
- Docker 公式 / Install Docker on Ubuntu
そうしたら VLAN trunk port で VLAN tag が取り除かれて出てきたんですよ。つーわけで docker OVS は止め。諦めて各々の OVS 用に Ubuntu 仮想マシンを立てることにしましたとさ。
詳細は以下のリンク先を参照ください。例によって GNS 2.0
では、docker でもちゃんと VLAN tag 取り除かずに動くようになっていました(2017/05
確認済)。
- GNS3 github issue / Docker strips VLAN tag
- GNS3 公式forum / Open vSwitch docker appliance 802.1q not working
torSW[12]01a (Open vSwitch) 設定
Open vSwitch
の導入なんかは、適当に公式ドキュメントを見て進めて頂くとして。(雑)
以下のような設定で。このスイッチは LACP と VLAN が動けばなんでもよいので、適当に各々が使いやすいやつを入れればよいかと。
torSW[12]01a
共通
# ovs-vsctl --no-wait init # ovs-vsctl add-br br0 # ovs-vsctl set bridge br0 datapath_type=netdev # ovs-vsctl add-bond br0 bond0 ens4 ens5 lacp=active bond_mode=balance-slb other_config:lacp-time=fast # ovs-vsctl add-port br0 ens6 tag=100 # ovs-vsctl add-port br0 ens7 tag=200 # ip link set dev br0 up # ip link set dev ens4 up # ip link set dev ens5 up # ip link set dev ens6 up # ip link set dev ens7 up # ovs-vsctl show 79e38752-1ada-4e44-9da2-f457504b149a Bridge "br0" Port "ens7" tag: 200 Interface "ens7" Port "bond0" Interface "ens5" Interface "ens4" Port "ens6" tag: 100 Interface "ens6" Port "br0" Interface "br0" type: internal ovs_version: "2.5.0" # ovs-vsctl list port bond0 _uuid : 8e767f1a-6a08-411f-9b86-407922a7565c bond_active_slave : "00:37:c4:9e:d1:01" bond_downdelay : 0 bond_fake_iface : false bond_mode : balance-slb bond_updelay : 0 external_ids : {} fake_bridge : false interfaces : [470f05cf-c3db-423d-abd5-4a6c45c9a581, 97fb2fa2-5074-455a-8b58-04ec746ea0a6] lacp : active mac : [] name : "bond0" other_config : {lacp-time=fast} qos : [] rstp_statistics : {} rstp_status : {} statistics : {} status : {} tag : [] trunks : [] vlan_mode : []
以下出力は spine1[12]
の設定とかも終わった後で LAG が組めている状態のものですが...。
root@torSW101a:~# ovs-appctl bond/show bond0 ---- bond0 ---- bond_mode: balance-slb bond may use recirculation: no, Recirc-ID : -1 bond-hash-basis: 0 updelay: 0 ms downdelay: 0 ms next rebalance: 7123 ms lacp_status: negotiated active slave mac: 00:37:c4:9e:d1:01(ens4) slave ens4: enabled active slave may_enable: true slave ens5: enabled may_enable: true root@torSW101a:~# ovs-appctl lacp/show bond0 ---- bond0 ---- status: active negotiated sys_id: 00:37:c4:9e:d1:01 sys_priority: 65534 aggregation key: 1 lacp_time: fast slave: ens4: current attached port_id: 2 port_priority: 65535 may_enable: true actor sys_id: 00:37:c4:9e:d1:01 actor sys_priority: 65534 actor port_id: 2 actor port_priority: 65535 actor key: 1 actor state: activity timeout aggregation synchronized collecting distributing partner sys_id: 00:00:00:01:01:01 partner sys_priority: 127 partner port_id: 1 partner port_priority: 127 partner key: 1 partner state: activity timeout aggregation synchronized collecting distributing slave: ens5: current attached port_id: 1 port_priority: 65535 may_enable: true actor sys_id: 00:37:c4:9e:d1:01 actor sys_priority: 65534 actor port_id: 1 actor port_priority: 65535 actor key: 1 actor state: activity timeout aggregation synchronized collecting distributing partner sys_id: 00:00:00:01:01:01 partner sys_priority: 127 partner port_id: 1 partner port_priority: 127 partner key: 1 partner state: activity timeout aggregation synchronized collecting distributing
疎通確認用 node 設定
今まで通りなのですが、適当に node 群を用意しておきます。疎通確認にしか使わないので、何を使ってもいいです。
node11
spine1[12]
配下 VLAN 100
kotetsu@node11:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:e2:60:01 brd ff:ff:ff:ff:ff:ff inet 192.168.1.1/24 brd 192.168.1.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fee2:6001/64 scope link valid_lft forever preferred_lft forever
node21
spine2[12]
配下 VLAN 100
kotetsu@node21:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:46:d8:01 brd ff:ff:ff:ff:ff:ff inet 192.168.1.2/24 brd 192.168.1.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fe46:d801/64 scope link valid_lft forever preferred_lft forever
node12
spine1[12]
配下 VLAN 200
kotetsu@node12:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:9c:dd:01 brd ff:ff:ff:ff:ff:ff inet 192.168.2.1/24 brd 192.168.2.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fe9c:dd01/64 scope link valid_lft forever preferred_lft forever
node22
spine2[12]
配下 VLAN 200
kotetsu@node22:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:3d:e0:01 brd ff:ff:ff:ff:ff:ff inet 192.168.2.2/24 brd 192.168.2.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fe3d:e001/64 scope link valid_lft forever preferred_lft forever
vQFX 設定~確認
まずは Underlay の設定(物理IF~eBGP)を。長くなってしまいますが、下図のような感じで作っていきます。
Underlay 物理IF設定
vQFX でも RFC3021 Using 31-Bit Prefixes on IPv4 Point-to-Point Links をサポートしているので、使っていくです。
6台分をペタペタ貼っていきますが、まあ物理インターフェース番号やIPアドレスのパラメータが個々に異なるくらい。
bb01
set interfaces xe-0/0/0 description "DEV=spine11 IF=xe-0/0/0" set interfaces xe-0/0/0 mtu 9192 set interfaces xe-0/0/0 unit 0 family inet address 192.0.2.0/31 set interfaces xe-0/0/0 unit 0 family inet mtu 9000 delete interfaces xe-0/0/1 unit 0 family inet dhcp set interfaces xe-0/0/1 description "DEV=spine12 IF=xe-0/0/0" set interfaces xe-0/0/1 mtu 9192 set interfaces xe-0/0/1 unit 0 family inet address 192.0.2.2/31 set interfaces xe-0/0/1 unit 0 family inet mtu 9000 delete interfaces xe-0/0/2 unit 0 family inet dhcp set interfaces xe-0/0/2 description "DEV=spine21 IF=xe-0/0/0" set interfaces xe-0/0/2 mtu 9192 set interfaces xe-0/0/2 unit 0 family inet address 192.0.2.4/31 set interfaces xe-0/0/2 unit 0 family inet mtu 9000 delete interfaces xe-0/0/3 unit 0 family inet dhcp set interfaces xe-0/0/3 description "DEV=spine22 IF=xe-0/0/0" set interfaces xe-0/0/3 mtu 9192 set interfaces xe-0/0/3 unit 0 family inet address 192.0.2.6/31 set interfaces xe-0/0/3 unit 0 family inet mtu 9000 set protocols lldp port-id-subtype interface-name set protocols lldp interface xe-0/0/0 set protocols lldp interface xe-0/0/1 set protocols lldp interface xe-0/0/2 set protocols lldp interface xe-0/0/3
bb02
delete interfaces xe-0/0/0 unit 0 family inet dhcp set interfaces xe-0/0/0 description "DEV=spine11 IF=xe-0/0/1" set interfaces xe-0/0/0 mtu 9192 set interfaces xe-0/0/0 unit 0 family inet address 192.0.2.128/31 set interfaces xe-0/0/0 unit 0 family inet mtu 9000 delete interfaces xe-0/0/1 unit 0 family inet dhcp set interfaces xe-0/0/1 description "DEV=spine12 IF=xe-0/0/1" set interfaces xe-0/0/1 mtu 9192 set interfaces xe-0/0/1 unit 0 family inet address 192.0.2.130/31 set interfaces xe-0/0/1 unit 0 family inet mtu 9000 delete interfaces xe-0/0/2 unit 0 family inet dhcp set interfaces xe-0/0/2 description "DEV=spine21 IF=xe-0/0/1" set interfaces xe-0/0/2 mtu 9192 set interfaces xe-0/0/2 unit 0 family inet address 192.0.2.132/31 set interfaces xe-0/0/2 unit 0 family inet mtu 9000 delete interfaces xe-0/0/3 unit 0 family inet dhcp set interfaces xe-0/0/3 description "DEV=spine22 IF=xe-0/0/1" set interfaces xe-0/0/3 mtu 9192 set interfaces xe-0/0/3 unit 0 family inet address 192.0.2.134/31 set interfaces xe-0/0/3 unit 0 family inet mtu 9000 set protocols lldp port-id-subtype interface-name set protocols lldp interface xe-0/0/0 set protocols lldp interface xe-0/0/1 set protocols lldp interface xe-0/0/2 set protocols lldp interface xe-0/0/3
spine11
delete interfaces xe-0/0/0 unit 0 family inet dhcp set interfaces xe-0/0/0 description "DEV=bb01 IF=xe-0/0/0" set interfaces xe-0/0/0 mtu 9192 set interfaces xe-0/0/0 unit 0 family inet address 192.0.2.1/31 set interfaces xe-0/0/0 unit 0 family inet mtu 9000 delete interfaces xe-0/0/1 unit 0 family inet dhcp set interfaces xe-0/0/1 description "DEV=bb02 IF=xe-0/0/0" set interfaces xe-0/0/1 mtu 9192 set interfaces xe-0/0/1 unit 0 family inet address 192.0.2.129/31 set interfaces xe-0/0/1 unit 0 family inet mtu 9000 delete interfaces xe-0/0/2 unit 0 family inet dhcp set interfaces xe-0/0/2 description "DEV=torSW101a IF=eth0" set protocols lldp port-id-subtype interface-name set protocols lldp interface xe-0/0/0 set protocols lldp interface xe-0/0/1
spine12
delete interfaces xe-0/0/0 unit 0 family inet dhcp set interfaces xe-0/0/0 description "DEV=bb01 IF=xe-0/0/1" set interfaces xe-0/0/0 mtu 9192 set interfaces xe-0/0/0 unit 0 family inet address 192.0.2.3/31 set interfaces xe-0/0/0 unit 0 family inet mtu 9000 delete interfaces xe-0/0/1 unit 0 family inet dhcp set interfaces xe-0/0/1 description "DEV=bb02 IF=xe-0/0/1" set interfaces xe-0/0/1 mtu 9192 set interfaces xe-0/0/1 unit 0 family inet address 192.0.2.131/31 set interfaces xe-0/0/1 unit 0 family inet mtu 9000 delete interfaces xe-0/0/2 unit 0 family inet dhcp set interfaces xe-0/0/2 description "DEV=torSW101a IF=eth1" set protocols lldp port-id-subtype interface-name set protocols lldp interface xe-0/0/0 set protocols lldp interface xe-0/0/1
spine21
delete interfaces xe-0/0/0 unit 0 family inet dhcp set interfaces xe-0/0/0 description "DEV=bb01 IF=xe-0/0/2" set interfaces xe-0/0/0 mtu 9192 set interfaces xe-0/0/0 unit 0 family inet address 192.0.2.5/31 set interfaces xe-0/0/0 unit 0 family inet mtu 9000 delete interfaces xe-0/0/1 unit 0 family inet dhcp set interfaces xe-0/0/1 description "DEV=bb02 IF=xe-0/0/2" set interfaces xe-0/0/1 mtu 9192 set interfaces xe-0/0/1 unit 0 family inet address 192.0.2.133/31 set interfaces xe-0/0/1 unit 0 family inet mtu 9000 delete interfaces xe-0/0/2 unit 0 family inet dhcp set interfaces xe-0/0/2 description "DEV=torSW201a IF=eth0" set protocols lldp port-id-subtype interface-name set protocols lldp interface xe-0/0/0 set protocols lldp interface xe-0/0/1
spine22
delete interfaces xe-0/0/0 unit 0 family inet dhcp set interfaces xe-0/0/0 description "DEV=bb01 IF=xe-0/0/3" set interfaces xe-0/0/0 mtu 9192 set interfaces xe-0/0/0 unit 0 family inet address 192.0.2.7/31 set interfaces xe-0/0/0 unit 0 family inet mtu 9000 delete interfaces xe-0/0/1 unit 0 family inet dhcp set interfaces xe-0/0/1 description "DEV=bb02 IF=xe-0/0/3" set interfaces xe-0/0/1 mtu 9192 set interfaces xe-0/0/1 unit 0 family inet address 192.0.2.135/31 set interfaces xe-0/0/1 unit 0 family inet mtu 9000 delete interfaces xe-0/0/2 unit 0 family inet dhcp set interfaces xe-0/0/2 description "DEV=torSW201a IF=eth1" set protocols lldp port-id-subtype interface-name set protocols lldp interface xe-0/0/0 set protocols lldp interface xe-0/0/1
Underlay eBGP 設定~簡易動作確認
これを設定すれば eBGP で各々の lo0
IPアドレスを相互学習できるようになる筈。
全台共通設定
ここでは6台の vQFX 全台共通の設定を。
ともあれまずは eBGP を動かします。
set protocols bgp group BGP_UNDERLAY type external set protocols bgp group BGP_UNDERLAY mtu-discovery
広告対象は自身の lo0
のみとします。共通のポリシを全台で流用しました。この辺は今まで通りです。
set policy-options policy-statement POLICY_EXPORT_LO0 from family inet set policy-options policy-statement POLICY_EXPORT_LO0 from protocol direct set policy-options policy-statement POLICY_EXPORT_LO0 from route-filter 0.0.0.0/0 prefix-length-range /32-/32 set policy-options policy-statement POLICY_EXPORT_LO0 then accept set protocols bgp group BGP_UNDERLAY export POLICY_EXPORT_LO0
このあたりは Underlay 設計にもよるのですが...。
今回は IGP を一切使わずに、eBGP のみで組んでいます。(今回のような環境を作るのに、モノの本には IGP が推奨されていたりもしますが。)
また、2台をペアとして同じ AS に所属させています。(6台を各々別 AS に所属させる選択肢もあって、システムの拡張性と利用可能な AS 番号の数、2byte ASN か 4byte ASN か...など考慮して、選択すればよいのでは。)
なので、spine
4 台の lo0
同士でフルメッシュに到達性を持たせるためには、以下を実現する必要があります。
AS 65000
のbb0[12]
は、AS 65001
のspine11
から受信した経路(spine11
のlo0
IP アドレス)を、AS 65001
のspine12
に広告する必要があるAS 65002
から来る経路に関しても同様
AS 65001
のspine11
は、AS PATH が65000 65001
となるspine12
への経路を学習しないといけない
というわけで、以下の設定を入れておきます。
set protocols bgp group BGP_UNDERLAY advertise-peer-as set protocols bgp group BGP_UNDERLAY family inet unicast loops 2
今回冗長化しますので spine
同士の通信が Per Packet で ECMP されるポリシを適用して、マルチパスを動かします。
VXLANカプセル化したパケットの通信は全て SrcIP も DstIP も spine
(の lo0
)の通信になるわけで、spine[12]{2}
にさえ入れておけば良い設定の筈ですが。
set policy-options policy-statement POLICY_ECMP then load-balance per-packet set routing-options forwarding-table export POLICY_ECMP set routing-options forwarding-table ecmp-fast-reroute set protocols bgp group BGP_UNDERLAY multipath
折角だから BFD
も動かしてみようと欲張ったのですが、別に必須ではないし環境が弱いと邪魔になりかねないので、お好みでどうぞ。
set protocols bgp group BGP_UNDERLAY bfd-liveness-detection minimum-interval 350 set protocols bgp group BGP_UNDERLAY bfd-liveness-detection multiplier 3 set protocols bgp group BGP_UNDERLAY bfd-liveness-detection session-mode automatic
ログファイルを /var/log/bgp.log
に仕分けたりの細々した設定なのでお好みでどうぞ。
set protocols bgp traceoptions file bgp.log set protocols bgp traceoptions file size 10k set protocols bgp traceoptions file files 30 set protocols bgp traceoptions flag normal set protocols bgp log-updown
仮想環境でどんだけ意味があるかっつーと...ですけど、あーコマンドは入るのねーくらいの感じで投入しただけです。まー今回の箱庭検証では不要でしょう。
set protocols bgp graceful-restart
個別設定
ここから先は個別パラメータの設定です。
lo0
の IPアドレス、AS番号、neighbor 設定くらいすね。
bb01
set interfaces lo0 unit 0 family inet address 172.31.0.1/32 set routing-options router-id 172.31.0.1 set routing-options autonomous-system 65000 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.1 description spine11 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.1 peer-as 65001 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.3 description spine12 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.3 peer-as 65001 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.5 description spine21 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.5 peer-as 65002 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.7 description spine22 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.7 peer-as 65002
bb02
set interfaces lo0 unit 0 family inet address 172.31.0.2/32 set routing-options router-id 172.31.0.2 set routing-options autonomous-system 65000 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.129 description spine11 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.129 peer-as 65001 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.131 description spine12 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.131 peer-as 65001 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.133 description spine21 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.133 peer-as 65002 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.135 description spine22 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.135 peer-as 65002
spine11
set interfaces lo0 unit 0 family inet address 172.16.1.1/32 set routing-options router-id 172.16.1.1 set routing-options autonomous-system 65001 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.0 description bb01 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.0 peer-as 65000 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.128 description bb02 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.128 peer-as 65000
spine12
set interfaces lo0 unit 0 family inet address 172.16.1.2/32 set routing-options router-id 172.16.1.2 set routing-options autonomous-system 65001 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.2 description bb01 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.2 peer-as 65000 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.130 description bb02 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.130 peer-as 65000
spine21
set interfaces lo0 unit 0 family inet address 172.16.2.1/32 set routing-options router-id 172.16.2.1 set routing-options autonomous-system 65002 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.4 description bb01 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.4 peer-as 65000 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.132 description bb02 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.132 peer-as 65000
spine22
set interfaces lo0 unit 0 family inet address 172.16.2.2/32 set routing-options router-id 172.16.2.2 set routing-options autonomous-system 65002 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.6 description bb01 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.6 peer-as 65000 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.134 description bb02 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.134 peer-as 65000
Underlay eBGP ECMP 動作確認
これで BGP ステータスやテーブルを確認・フルメッシュでの lo0
間疎通ができるようになります。
では ECMP の挙動を軽く確認しておきます。
例えば spine11
と spine21
は互いに相手の lo0
への経路を 2 パス(bb01
経由と bb02
経由)持っています。
{master:0} kotetsu@spine11> show route 172.16.2.1 inet.0: 14 destinations, 17 routes (14 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.2.1/32 *[BGP/170] 00:20:02, localpref 100 AS path: 65000 65002 I, validation-state: unverified to 192.0.2.0 via xe-0/0/0.0 > to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 00:02:45, localpref 100 AS path: 65000 65002 I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0
{master:0} kotetsu@spine21> show route 172.16.1.1 inet.0: 14 destinations, 19 routes (14 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.1.1/32 *[BGP/170] 00:19:54, localpref 100 AS path: 65000 65001 I, validation-state: unverified to 192.0.2.4 via xe-0/0/0.0 > to 192.0.2.132 via xe-0/0/1.0 [BGP/170] 00:03:23, localpref 100 AS path: 65000 65001 I, validation-state: unverified > to 192.0.2.4 via xe-0/0/0.0
ここで spine11
から spine21
に対して(双方 lo0
) ping を実行しつつ
{master:0} kotetsu@spine11> ping source 172.16.1.1 172.16.2.1 PING 172.16.2.1 (172.16.2.1): 56 data bytes 64 bytes from 172.16.2.1: icmp_seq=0 ttl=63 time=28.369 ms 64 bytes from 172.16.2.1: icmp_seq=1 ttl=63 time=37.308 ms ... --- 172.16.2.1 ping statistics --- 21 packets transmitted, 21 packets received, 0% packet loss round-trip min/avg/max/stddev = 18.653/29.917/45.982/7.670 ms
spine11
と spine21
から bb01
と bb02
へのリンクをパケットキャプチャすると、分散していることが分かります。
あと一応、AS65001 に所属している spine12
へのパスが AS65001 に所属している spine11
で AS-PATH 65000 65001 で学習できていることも確認しておきます。
各 spine の unicast loops
設定と、各 bb の advertise-peer-as
設定が働いて、狙い通り学習できています。
{master:0} kotetsu@spine11> show route 172.16.1.2 inet.0: 14 destinations, 17 routes (14 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.1.2/32 *[BGP/170] 00:29:19, localpref 100 AS path: 65000 65001 I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 00:29:15, localpref 100 AS path: 65000 65001 I, validation-state: unverified > to 192.0.2.128 via xe-0/0/1.0
Overlay 設定(MP-BGP)
Underlay eBGP で経路交換した各 lo0
同士で iBGP を組みます。
これで EVPN NLRI をやりとりする MP-BGP が組める筈。
設定は長々となってしまいますが、絵にすると単純で以下のような感じです。
全台共通設定
前回と同様の設定です。
set protocols bgp group BGP_OVERLAY type internal set protocols bgp group BGP_OVERLAY family evpn signaling set protocols bgp group BGP_OVERLAY local-as 64512
個別設定
bb0[12]
が共に RouteReflector になる構成をとるので、同じクラスタIDを設定します。
場合によっては RouteReflector 使わずにフルメッシュにするなり、お好きなようにどうぞ。(なんか、今回こればっかり言ってる気がする...。)
bb01
set protocols bgp group BGP_OVERLAY local-address 172.31.0.1 set protocols bgp group BGP_OVERLAY cluster 172.31.0.0 set protocols bgp group BGP_OVERLAY neighbor 172.16.1.1 description spine11 set protocols bgp group BGP_OVERLAY neighbor 172.16.1.2 description spine12 set protocols bgp group BGP_OVERLAY neighbor 172.16.2.1 description spine21 set protocols bgp group BGP_OVERLAY neighbor 172.16.2.2 description spine22
bb02
set protocols bgp group BGP_OVERLAY local-address 172.31.0.2 set protocols bgp group BGP_OVERLAY cluster 172.31.0.0 set protocols bgp group BGP_OVERLAY neighbor 172.16.1.1 description spine11 set protocols bgp group BGP_OVERLAY neighbor 172.16.1.2 description spine12 set protocols bgp group BGP_OVERLAY neighbor 172.16.2.1 description spine21 set protocols bgp group BGP_OVERLAY neighbor 172.16.2.2 description spine22
spine11
set protocols bgp group BGP_OVERLAY local-address 172.16.1.1 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.1 description bb01 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.2 description bb02
spine12
set protocols bgp group BGP_OVERLAY local-address 172.16.1.2 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.1 description bb01 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.2 description bb02
spine21
set protocols bgp group BGP_OVERLAY local-address 172.16.2.1 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.1 description bb01 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.2 description bb02
spine22
set protocols bgp group BGP_OVERLAY local-address 172.16.2.2 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.1 description bb01 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.2 description bb02
Overlay設定~確認(EVPN+VXLAN)
EVPN の設定と、その Dataplane として使う VXLAN 周りの設定をしていきます。前回のシングル構成版と全く一緒です。
bb0[12]
はこの辺の挙動に関しては土管に徹しているので登場しません。
spine[12]{2} 4台共通設定
set vlans VLAN0100 vlan-id 100 set vlans VLAN0100 vxlan vni 10100 set vlans VLAN0200 vlan-id 200 set vlans VLAN0200 vxlan vni 10200 set protocols evpn encapsulation vxlan set protocols evpn extended-vni-list all set protocols evpn multicast-mode ingress-replication set protocols evpn vni-options vni 10100 vrf-target export target:1:10100 set protocols evpn vni-options vni 10200 vrf-target export target:1:10200 set policy-options community COM_10100 members target:1:10100 set policy-options community COM_10200 members target:1:10200 set policy-options community COM_LEAF_ESI members target:9999:9999 set policy-options policy-statement POLICY_VRF_IMPORT term T_10100 from community COM_10100 set policy-options policy-statement POLICY_VRF_IMPORT term T_10100 then accept set policy-options policy-statement POLICY_VRF_IMPORT term T_10200 from community COM_10200 set policy-options policy-statement POLICY_VRF_IMPORT term T_10200 then accept set policy-options policy-statement POLICY_VRF_IMPORT term T_99900 from community COM_LEAF_ESI set policy-options policy-statement POLICY_VRF_IMPORT term T_99900 then accept set policy-options policy-statement POLICY_VRF_IMPORT term T_99999 then reject set switch-options vtep-source-interface lo0.0 set switch-options vrf-import POLICY_VRF_IMPORT set switch-options vrf-target target:9999:9999 set switch-options vrf-target auto
個別設定
つっても RD
だけですね。
spine11
set switch-options route-distinguisher 64512:11
spine12
set switch-options route-distinguisher 64512:12
spine21
set switch-options route-distinguisher 64512:21
spine22
set switch-options route-distinguisher 64512:22
EVPN Multihoming 設定
ようやく本題ですね!(息切れ)
spine1[12]
は torSW101a
に、spine2[12]
は torSW201a
に、それぞれペアで ae0
を提供し、それを EVPN 的には Ethernet Segmeent(ES)
として扱い、その識別子として Ethernet Segment Identifier(ESI)
を付与します。
spine[12]{2} 4台共通設定
まずは普通の AE 設定です。
ethernet device-count
を 448 なんて値にしているのは、単に?
で出てきたヘルプに書いてあった最大値を入れただけ。足りないより良かろうガハハ!くらいのノリです。torSW[12]01a
向けの物理インターフェース(4台共にxe-0/0/2
)をae0
に所属させae0
はvlan trunk
で(自身の DB にある)全 VLAN 食うようにしておき- LACP は
- default の
interval fast
(1s間隔)で良いので特に設定せず spine[12]{2}
の別筐体にまたがる LAG をtorSW[12]01a
側では同じものと見做せる必要があるので、各ペアで同じsystem-id
を付与- それぞれ 3 台(spine 2 台と torSW 1 台)で閉じる部分だし、
spine[12]{2}
で同じ値を使ってしまっているが、本来は一意になるようにしておいた方が無難かと
- それぞれ 3 台(spine 2 台と torSW 1 台)で閉じる部分だし、
system-priority
値はデフォルトの 127 のまま
- default の
EVPN Multihoming Mode
としてはactive-active
を使う
set chassis aggregated-devices ethernet device-count 448 set interfaces xe-0/0/2 ether-options 802.3ad ae0 delete interfaces xe-0/0/2 unit 0 set interfaces ae0 unit 0 family ethernet-switching interface-mode trunk set interfaces ae0 unit 0 family ethernet-switching vlan members all set interfaces ae0 aggregated-ether-options lacp active set interfaces ae0 aggregated-ether-options lacp system-id 00:00:00:01:01:01 set interfaces ae0 esi all-active
個別設定
ペア単位で個別な設定を見ていきましょうか。って、ESI
だけですが。
2017/02/26
時点で Juniper公式 / Supported EVPN Standardsを見ると
RFC 7432, BGP MPLS-Based Ethernet VPN The following features are not supported: - Automatic derivation of Ethernet segment (ES) values. Only static ES configurations are supported.
となっていますので、巧いこと EVPN の世界で一意になるように手動で付与してやりましょう。
RFC74322 / Ethernet Segment あたりを参照して、1octet 目は ESI Type
を 0x00
とし、あとは適当に。
今回は 9octet 目で spine のペアを、10octet 目で ae 番号を、それぞれ識別できるように付与しました。
spine1[12]
set interfaces ae0 esi 00:01:01:01:01:01:01:01:01:00
spine2[12]
set interfaces ae0 esi 00:01:01:01:01:01:01:01:02:00
ちなみにですが、自分の環境起因か手順の不備か仕様か分かりませんが、この ESI
値を変更した時、古い ESI
が(巧いこと WithDrawn されなかったのかも知れないですが)残ってしまうことがありました。
spine1[12]
ae0
用の ESI
を変更したら、spine2[12]
側に新旧両方の経路が残ってしまったんですよね。
何でかは追ってません。もし、そんな状況が再現できた & 原因が分かったりしたら & それが公開可能な情報なら、教えてください。
動作確認
node間の疎通確認
node11
と node21
で $ sudo ip n flush dev ens4
して node11
から ping 192.168.1.2
で L2 over L3 通信できることを確認できます。
kotetsu@node11:~$ ping 192.168.1.2 PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=181 ms 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=61.4 ms 64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=35.1 ms 64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=42.7 ms 64 bytes from 192.168.1.2: icmp_seq=5 ttl=64 time=53.8 ms 64 bytes from 192.168.1.2: icmp_seq=6 ttl=64 time=78.2 ms 64 bytes from 192.168.1.2: icmp_seq=7 ttl=64 time=33.6 ms 64 bytes from 192.168.1.2: icmp_seq=8 ttl=64 time=35.1 ms 64 bytes from 192.168.1.2: icmp_seq=9 ttl=64 time=33.4 ms 64 bytes from 192.168.1.2: icmp_seq=10 ttl=64 time=61.7 ms ^C --- 192.168.1.2 ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time 9013ms rtt min/avg/max/mdev = 33.471/61.687/181.628/42.518 ms
ここで気になったのは EVPN Multihoming の aliasing 動作に沿うならば、Request パケットは spine21
宛と spine22
宛にロードバランスされて、Reply パケットは spine11
と spine12
にロードバランスされる、って動きになる筈なんですが、そうはならなかった(どちらもその時点での Type2 のみに従って、寄っていた)です。
何らかの環境起因(サポートされないHW or SW)なのか、設定不足なのか...。何かわかったら追記しておきます(2017/02/27
)。
vQFX のテーブル確認
EVPN Multihoming の Designated Forwarder 状態
spine1[12]
で組んでいる ae0 ESI= 00:01:01:01:01:01:01:01:01:00
においては 172.16.1.1 = spine11
が DF として選出されていることが見えます。
一方で、自身が関与していない spine2[12]
で組んでいる ae0 ESI= 00:01:01:01:01:01:01:01:02:00
においては No local attachment to ethernet segment
として何も情報出さないようです。
{master:0} kotetsu@spine11> show evpn instance designated-forwarder Instance: default-switch Number of ethernet segments: 2 ESI: 00:01:01:01:01:01:01:01:01:00 Designated forwarder: 172.16.1.1 ESI: 00:01:01:01:01:01:01:01:02:00 Designated forwarder: No local attachment to ethernet segment
{master:0} kotetsu@spine12> show evpn instance designated-forwarder Instance: default-switch Number of ethernet segments: 2 ESI: 00:01:01:01:01:01:01:01:01:00 Designated forwarder: 172.16.1.1 ESI: 00:01:01:01:01:01:01:01:02:00 Designated forwarder: No local attachment to ethernet segment
spine2[12]
で組んでいる ae0 ESI= 00:01:01:01:01:01:01:01:02:00
においては 172.16.2.1 = spine21
が DF として選出されていることが見えます。
一方で、自身が関与していない spine1[12]
で組んでいる ae0 ESI= 00:01:01:01:01:01:01:01:01:00
においては No local attachment to ethernet segment
として何も情報出さないようです。
{master:0} kotetsu@spine21> show evpn instance designated-forwarder Instance: default-switch Number of ethernet segments: 2 ESI: 00:01:01:01:01:01:01:01:01:00 Designated forwarder: No local attachment to ethernet segment ESI: 00:01:01:01:01:01:01:01:02:00 Designated forwarder: 172.16.2.1
kotetsu@spine22> show evpn instance designated-forwarder Instance: default-switch Number of ethernet segments: 2 ESI: 00:01:01:01:01:01:01:01:01:00 Designated forwarder: No local attachment to ethernet segment ESI: 00:01:01:01:01:01:01:01:02:00 Designated forwarder: 172.16.2.1
なお、選出の流れは Juniper公式 / Designated Forwarder Election あたりに書いてあります。
本環境では単純にIPアドレスが小さいやつがそれぞれ DF に選出されたっぽいです。
以下のコマンドで、下の方 Number of ethernet segments
でやや詳しい情報が見られるようです。
{master:0} kotetsu@spine11> show evpn instance extensive Instance: __default_evpn__ Route Distinguisher: 172.16.1.1:0 Number of bridge domains: 0 Number of neighbors: 1 172.16.1.2 Received routes Ethernet Segment: 1 Instance: default-switch Route Distinguisher: 64512:11 Encapsulation type: VXLAN MAC database status Local Remote MAC advertisements: 1 1 MAC+IP advertisements: 0 0 Default gateway MAC advertisements: 0 0 Number of local interfaces: 1 (1 up) Interface name ESI Mode Status ae0.0 00:01:01:01:01:01:01:01:01:00 all-active Up Number of IRB interfaces: 0 (0 up) Number of bridge domains: 3 VLAN VNI Intfs / up IRB intf Mode MAC sync IM route label 100 10100 1 1 Extended Enabled 10100 200 10200 1 1 Extended Enabled 10200 300 10300 1 1 Extended Enabled 10300 Number of neighbors: 3 172.16.1.2 Received routes MAC address advertisement: 0 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 172.16.2.1 Received routes MAC address advertisement: 0 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 172.16.2.2 Received routes MAC address advertisement: 1 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 Number of ethernet segments: 2 ESI: 00:01:01:01:01:01:01:01:01:00 Status: Resolved by IFL ae0.0 Local interface: ae0.0, Status: Up/Forwarding Number of remote PEs connected: 1 Remote PE MAC label Aliasing label Mode 172.16.1.2 0 0 all-active Designated forwarder: 172.16.1.1 Backup forwarder: 172.16.1.2 ESI: 00:01:01:01:01:01:01:01:02:00 Status: Resolved Number of remote PEs connected: 2 Remote PE MAC label Aliasing label Mode 172.16.2.1 0 0 all-active 172.16.2.2 10100 0 all-active Router-ID: 172.16.1.1 Source VTEP interface IP: 172.16.1.1
{master:0} kotetsu@spine12> show evpn instance extensive Instance: __default_evpn__ Route Distinguisher: 172.16.1.2:0 Number of bridge domains: 0 Number of neighbors: 1 172.16.1.1 Received routes Ethernet Segment: 1 Instance: default-switch Route Distinguisher: 64512:12 Encapsulation type: VXLAN MAC database status Local Remote MAC advertisements: 0 2 MAC+IP advertisements: 0 0 Default gateway MAC advertisements: 0 0 Number of local interfaces: 1 (1 up) Interface name ESI Mode Status ae0.0 00:01:01:01:01:01:01:01:01:00 all-active Up Number of IRB interfaces: 0 (0 up) Number of bridge domains: 2 VLAN VNI Intfs / up IRB intf Mode MAC sync IM route label 100 10100 1 1 Extended Enabled 10100 200 10200 1 1 Extended Enabled 10200 Number of neighbors: 3 172.16.1.1 Received routes MAC address advertisement: 1 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 172.16.2.1 Received routes MAC address advertisement: 0 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 172.16.2.2 Received routes MAC address advertisement: 1 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 Number of ethernet segments: 2 ESI: 00:01:01:01:01:01:01:01:01:00 Status: Resolved by IFL ae0.0 Local interface: ae0.0, Status: Up/Forwarding Number of remote PEs connected: 1 Remote PE MAC label Aliasing label Mode 172.16.1.1 10100 0 all-active Designated forwarder: 172.16.1.1 Backup forwarder: 172.16.1.2 ESI: 00:01:01:01:01:01:01:01:02:00 Status: Resolved Number of remote PEs connected: 2 Remote PE MAC label Aliasing label Mode 172.16.2.2 10100 0 all-active 172.16.2.1 0 0 all-active Router-ID: 172.16.1.2 Source VTEP interface IP: 172.16.1.2
{master:0} kotetsu@spine21> show evpn instance extensive Instance: __default_evpn__ Route Distinguisher: 172.16.2.1:0 Number of bridge domains: 0 Number of neighbors: 1 172.16.2.2 Received routes Ethernet Segment: 1 Instance: default-switch Route Distinguisher: 64512:21 Encapsulation type: VXLAN MAC database status Local Remote MAC advertisements: 0 2 MAC+IP advertisements: 0 0 Default gateway MAC advertisements: 0 0 Number of local interfaces: 1 (1 up) Interface name ESI Mode Status ae0.0 00:01:01:01:01:01:01:01:02:00 all-active Up Number of IRB interfaces: 0 (0 up) Number of bridge domains: 2 VLAN VNI Intfs / up IRB intf Mode MAC sync IM route label 100 10100 1 1 Extended Enabled 10100 200 10200 1 1 Extended Enabled 10200 Number of neighbors: 3 172.16.1.1 Received routes MAC address advertisement: 1 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 172.16.1.2 Received routes MAC address advertisement: 0 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 172.16.2.2 Received routes MAC address advertisement: 1 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 Number of ethernet segments: 2 ESI: 00:01:01:01:01:01:01:01:01:00 Status: Resolved Number of remote PEs connected: 2 Remote PE MAC label Aliasing label Mode 172.16.1.1 10100 0 all-active 172.16.1.2 0 0 all-active ESI: 00:01:01:01:01:01:01:01:02:00 Status: Resolved by IFL ae0.0 Local interface: ae0.0, Status: Up/Forwarding Number of remote PEs connected: 1 Remote PE MAC label Aliasing label Mode 172.16.2.2 10100 0 all-active Designated forwarder: 172.16.2.1 Backup forwarder: 172.16.2.2 Router-ID: 172.16.2.1 Source VTEP interface IP: 172.16.2.1
{master:0} kotetsu@spine22> show evpn instance extensive Instance: __default_evpn__ Route Distinguisher: 172.16.2.2:0 Number of bridge domains: 0 Number of neighbors: 1 172.16.2.1 Received routes Ethernet Segment: 1 Instance: default-switch Route Distinguisher: 64512:22 Encapsulation type: VXLAN MAC database status Local Remote MAC advertisements: 1 1 MAC+IP advertisements: 0 0 Default gateway MAC advertisements: 0 0 Number of local interfaces: 1 (1 up) Interface name ESI Mode Status ae0.0 00:01:01:01:01:01:01:01:02:00 all-active Up Number of IRB interfaces: 0 (0 up) Number of bridge domains: 2 VLAN VNI Intfs / up IRB intf Mode MAC sync IM route label 100 10100 1 1 Extended Enabled 10100 200 10200 1 1 Extended Enabled 10200 Number of neighbors: 3 172.16.1.1 Received routes MAC address advertisement: 1 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 172.16.1.2 Received routes MAC address advertisement: 0 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 172.16.2.1 Received routes MAC address advertisement: 0 MAC+IP address advertisement: 0 Inclusive multicast: 2 Ethernet auto-discovery: 2 Number of ethernet segments: 2 ESI: 00:01:01:01:01:01:01:01:01:00 Status: Resolved Number of remote PEs connected: 2 Remote PE MAC label Aliasing label Mode 172.16.1.1 10100 0 all-active 172.16.1.2 0 0 all-active ESI: 00:01:01:01:01:01:01:01:02:00 Status: Resolved by IFL ae0.0 Local interface: ae0.0, Status: Up/Forwarding Number of remote PEs connected: 1 Remote PE MAC label Aliasing label Mode 172.16.2.1 0 0 all-active Designated forwarder: 172.16.2.1 Backup forwarder: 172.16.2.2 Router-ID: 172.16.2.2 Source VTEP interface IP: 172.16.2.2
MACアドレステーブル
EVPN Multihoming
を設定したことで
MAC flags
の項目にL - locally learned
やR - remote PE MAC
が現れたLogical interface
の項目は- 自身・Multihomingペアで学習したものは local の AE インターフェース名
- Remote の Multihoming ペアで学習したものは
ESI
インターフェース名
Active source
として Remote VTEP の IPアドレスの代わりにESI
が表示されるようになった
例えば spine1[12]
の Multihoming ペアを起点として見た時、以下のようになっています。
node11
の MAC アドレス00:37:c4:e2:60:01
はspine11
側が学習したのでspine11
ではL
Flag がたったspine12
ではR
Flag がたった
node21
の MAC アドレス00:37:c4:46:d8:01
はspine2[12]
が持つ ESI00:01:01:01:01:01:01:01:02:00
から学習したのでspine1[12]
共にR
Flag がたった -spine1[12]
共にActive source
としてspine2[12]
で設定した ESI00:01:01:01:01:01:01:01:02:00
が見える
{master:0} kotetsu@spine11> show ethernet-switching table MAC flags (S - static MAC, D - dynamic MAC, L - locally learned, P - Persistent static SE - statistics enabled, NM - non configured MAC, R - remote PE MAC, O - ovsdb MAC) Ethernet switching table : 2 entries, 2 learned Routing instance : default-switch Vlan MAC MAC Logical Active name address flags interface source VLAN0100 00:37:c4:46:d8:01 DR esi.1739 00:01:01:01:01:01:01:01:02:00 VLAN0100 00:37:c4:e2:60:01 DL ae0.0
{master:0} kotetsu@spine12> show ethernet-switching table MAC flags (S - static MAC, D - dynamic MAC, L - locally learned, P - Persistent static SE - statistics enabled, NM - non configured MAC, R - remote PE MAC, O - ovsdb MAC) Ethernet switching table : 2 entries, 2 learned Routing instance : default-switch Vlan MAC MAC Logical Active name address flags interface source VLAN0100 00:37:c4:46:d8:01 DR esi.1736 00:01:01:01:01:01:01:01:02:00 VLAN0100 00:37:c4:e2:60:01 DR ae0.0
spine2[12]
の Multihoming ペアを起点として見た時も同様。
{master:0} kotetsu@spine21> show ethernet-switching table MAC flags (S - static MAC, D - dynamic MAC, L - locally learned, P - Persistent static SE - statistics enabled, NM - non configured MAC, R - remote PE MAC, O - ovsdb MAC) Ethernet switching table : 2 entries, 2 learned Routing instance : default-switch Vlan MAC MAC Logical Active name address flags interface source VLAN0100 00:37:c4:46:d8:01 DR ae0.0 VLAN0100 00:37:c4:e2:60:01 DR esi.1742 00:01:01:01:01:01:01:01:01:00
{master:0} kotetsu@spine22> show ethernet-switching table MAC flags (S - static MAC, D - dynamic MAC, L - locally learned, P - Persistent static SE - statistics enabled, NM - non configured MAC, R - remote PE MAC, O - ovsdb MAC) Ethernet switching table : 2 entries, 2 learned Routing instance : default-switch Vlan MAC MAC Logical Active name address flags interface source VLAN0100 00:37:c4:46:d8:01 DL ae0.0 VLAN0100 00:37:c4:e2:60:01 DR esi.1742 00:01:01:01:01:01:01:01:01:00
Multihoming で使われる EVPN NLRI
4台全部のテーブルを並べても見難い & そこまで有意な差もないので、代表として spine11
で見ていきます。
Juniper公式 / EVPN Multihoming Overview - New BGP NLRIs あたりと見比べながらテーブルを眺めるのが良いでしょう。
まずシングル構成の時には登場しなかった Type 1(Ethernet Auto-Discovery (A-D) route)
が登場します。
まずは Autodiscovery route per EVPN instance (EVI)
を各 PE から学習している状況。こいつはどうも active-active
モードでのみ登場するやつ。
{master:0} kotetsu@spine11> show route table default-switch.evpn.0 default-switch.evpn.0: 18 destinations, 32 routes (18 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 1:64512:11::010101010101010100::0/304 *[EVPN/170] 6d 13:23:27 Indirect 1:64512:12::010101010101010100::0/304 *[BGP/170] 12:29:57, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified to 192.0.2.0 via xe-0/0/0.0 > to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 03:36:07, localpref 100, from 172.31.0.2 AS path: I, validation-state: unverified to 192.0.2.0 via xe-0/0/0.0 > to 192.0.2.128 via xe-0/0/1.0 1:64512:21::010101010101010200::0/304 *[BGP/170] 2d 17:29:38, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 22:46:20, localpref 100, from 172.31.0.2 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 1:64512:22::010101010101010200::0/304 *[BGP/170] 05:04:07, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 1d 00:56:03, localpref 100, from 172.31.0.2 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0
同様に Type 1(Ethernet Auto-Discovery (A-D) route)
で今度は Autodiscovery route per Ethernet segment
なやつ。
{master:0} kotetsu@spine11> show route table default-switch.evpn.0 default-switch.evpn.0: 18 destinations, 32 routes (18 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both ... 1:172.16.1.2:0::010101010101010100::FFFF:FFFF/304 *[BGP/170] 12:29:57, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 03:36:07, localpref 100, from 172.31.0.2 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 1:172.16.2.1:0::010101010101010200::FFFF:FFFF/304 *[BGP/170] 2d 17:29:38, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 22:46:20, localpref 100, from 172.31.0.2 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 1:172.16.2.2:0::010101010101010200::FFFF:FFFF/304 *[BGP/170] 05:04:05, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 1d 00:56:03, localpref 100, from 172.31.0.2 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0
次、Type 4(Ethernet Segment route)
で、こいつを使って同じ ESI
を持つ PE を識別するそうですよ。
{master:0} kotetsu@spine11> show route table __default_evpn__.evpn.0 __default_evpn__.evpn.0: 5 destinations, 8 routes (5 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 1:172.16.1.1:0::010101010101010100::FFFF:FFFF/304 *[EVPN/170] 6d 13:58:52 Indirect 4:172.16.1.1:0::010101010101010100:172.16.1.1/304 *[EVPN/170] 6d 13:58:52 Indirect 4:172.16.1.2:0::010101010101010100:172.16.1.2/304 *[BGP/170] 13:05:22, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 04:11:32, localpref 100, from 172.31.0.2 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 4:172.16.2.1:0::010101010101010200:172.16.2.1/304 *[BGP/170] 2d 18:05:03, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 23:21:45, localpref 100, from 172.31.0.2 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 4:172.16.2.2:0::010101010101010200:172.16.2.2/304 *[BGP/170] 05:39:30, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0 [BGP/170] 1d 01:31:28, localpref 100, from 172.31.0.2 AS path: I, validation-state: unverified > to 192.0.2.0 via xe-0/0/0.0 to 192.0.2.128 via xe-0/0/1.0
BUM トラフィックフロー確認
Ethernet Segment(ES)
で選出された Designated Forwarder(DF)
のみが BUM トラフィックを CE 方面に転送する、という動きをパケットキャプチャしてみました。
つって、ここで各リンクのパケットキャプチャを並べてもアレなので、キャプチャから動作を纏めた簡易図のみを...。
EthernetSegment リンク障害時動作確認(簡易)
仮想環境で真面目に障害試験をやるつもりはサラサラないので、何となく「あー Multihoming を組んでいる単一リンクを落としても経路が切り替わるね」とか「あー、想定通りの経路広告がされるね」くらいの緩いやつです。
今回の環境だと spine
と torSW
の間に全部パケットキャプチャ用の Ethernet Switch を挟んでいて、対向のリンクダウン検知なんてできず、単に torSW
側では LACP で検知して切り替わっているだけですし...。
node11
から node21
に ping 撃ちながら spine11
の xe-0/0/2
(to torSW101a) を disable
{master:0}[edit] kotetsu@spine11# show | compare [edit interfaces xe-0/0/2] + disable;
切り替わり時間とかは、環境に左右されるので参考にしないでください。あくまで「ホントに切り替わったね」を見ただけですので。
kotetsu@node11:~$ ping 192.168.1.2 PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=49.3 ms 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=60.0 ms ... 64 bytes from 192.168.1.2: icmp_seq=59 ttl=64 time=58.4 ms 64 bytes from 192.168.1.2: icmp_seq=60 ttl=64 time=75.0 ms 64 bytes from 192.168.1.2: icmp_seq=64 ttl=64 time=64.3 ms 64 bytes from 192.168.1.2: icmp_seq=65 ttl=64 time=70.8 ms 64 bytes from 192.168.1.2: icmp_seq=66 ttl=64 time=44.2 ms ... --- 192.168.1.2 ping statistics --- 68 packets transmitted, 65 received, 4% packet loss, time 67123ms rtt min/avg/max/mdev = 27.724/44.214/92.524/13.438 ms
リンク復旧
--- 192.168.1.2 ping statistics --- 60 packets transmitted, 60 received, 0% packet loss, time 59093ms rtt min/avg/max/mdev = 28.324/45.522/79.932/12.499 ms
この一連の障害で spine11
からの UPDATE/Withdrawn も拾ったので貼っておきます。
まずリンク disabled 時の WithDrawn
Type1~4~3と2が順次 WithDrawn されていく様です。(リンク障害時に Type 2,3 が全部 WithDrawn される前に、まずはザクッと ES 死んだことを別 PE に広告することで、少しでも早く自分宛に送ってこなくなるようにする = 高速な切り替えを促すために Type1 を最初に...という動き)
次にリンク復旧時の UPDATE
Type1~4~3が順次 UPDATE される様です。
動作確認(トラフィック バイバイ~ン 問題~~~(ドラ声で))
4台の spine
で clear ethernet-switching table
して、node[12]1
は双方の MAC アドレスが ARP テーブルに載っている状態で
kotetsu@node11:~$ ip n show 10.0.0.254 dev ens3 lladdr 00:a0:de:c0:55:80 REACHABLE 192.168.1.2 dev ens4 lladdr 00:37:c4:46:d8:01 STALE 10.0.0.65 dev ens3 lladdr 52:54:00:07:30:c0 DELAY
kotetsu@node21:~$ ip n show 192.168.1.1 dev ens4 lladdr 00:37:c4:e2:60:01 STALE 10.0.0.254 dev ens3 lladdr 00:a0:de:c0:55:80 STALE 10.0.0.65 dev ens3 lladdr 52:54:00:07:30:c0 DELAY
DUP る。
kotetsu@node11:~$ ping 192.168.1.2 PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=85.3 ms 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=88.3 ms 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=101 ms (DUP!) 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=103 ms (DUP!) 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=130 ms (DUP!) 64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=78.4 ms 64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=81.7 ms (DUP!) 64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=128 ms (DUP!) 64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=43.2 ms 64 bytes from 192.168.1.2: icmp_seq=5 ttl=64 time=51.9 ms 64 bytes from 192.168.1.2: icmp_seq=6 ttl=64 time=46.1 ms 64 bytes from 192.168.1.2: icmp_seq=7 ttl=64 time=37.7 ms ^C --- 192.168.1.2 ping statistics --- 7 packets transmitted, 7 received, +5 duplicates, 0% packet loss, time 6009ms rtt min/avg/max/mdev = 37.764/81.372/130.159/30.336 ms
パケットを拾って、一番酷い ICMP Echo (Request|Reply) Sequence No.2
の状況を追ってみると
node21
- Sequence No.2 の ICMP Echo Request を2個受信している
node11
- Sequence No.2 の ICMP Echo Request を1個しか送信していない
- Sequence No.2 の ICMP Echo Reply を4個受信している
torSW101a
- Sequence No.2 の ICMP Echo Request を
spine12
に転送している
- Sequence No.2 の ICMP Echo Request を
spine12
bb01
- Sequence No.2 の ICMP Echo Request をそのまま
spine11
,spine21
,spine22
に転送
- Sequence No.2 の ICMP Echo Request をそのまま
spine21
,spine22
- Sequence No.2 の ICMP Echo Request のカプセルの中身は DstMAC が
node21
で、自分の ES 配下にいるやつへの Unicast Traffic なので、そのままtorSw201a
に転送(もしかしたら、spine21
はこの時点でnode21
の MACアドレスを学習しておらず、Unknown Unicast として Multihoming の DF 動作を果たした、という可能性も) - EVPN Multihoming の挙動としては正しい
- Sequence No.2 の ICMP Echo Request のカプセルの中身は DstMAC が
という感じでして。
現状の実装だと仕方ない挙動と言わざるをえない...でしょうかね。そもそもあまり起こりえないシナリオですかね。僕はノリで clear ethernet-switching table
とかよく叩くんすが(そりゃ検証環境だからだ)。
EVPN Multihoming Mode
を active-standby
にしても、前述の spine2[12]
の挙動は変わらず、Remote VTEP 側(spine12
)が DF にのみ送信してくることを期待しているように見えますし...。
なんかこの辺の問題提起やら解決案やらが RFC, draft であったりするんでしょうか。もしくは各メーカの実装で何か回避できているんでしょうか。追っている人がいたら是非教えてください...。
一応、以下は spine12
と bb01
間のパケットキャプチャですが、Sequence No.2 の ICMP Echo Request を Ingress Replication した直後に spine21
から EVPN NLRI Type2
で node21
の MAC アドレス advertise を受けているの図です。
おしまい
まとめ
EVPN Multihoming
の触りを試して、最低限の正常動作が確認できました- RFC7432(BGP MPLS-Based Ethernet VPN) Multihoming に書かれている内容(で実装されているもの)は、今回試した範囲には収まりきらんので色々やってみましょう
所感
- VTEP を冗長化する手法として考えると、EVPN Multihoming は各 PE がそれなりに独立して動いてくれるのが嬉しいです。変に独自機構を使うと「その冗長化プロトコルを形成できるバージョンの組み合わせ」でバージョンアップとかが苦しくなりそうなので...。
- 偏見かも知らんけど L2, L4 の世界はその辺で結構苦しむような...。
- 例えば、同じ Juniper でいうと
MC-LAG
とかはどうなんでしょうね。組めるバージョンの組み合わせとか気にして運用するもんでしょうか。
vQFX
いいすね...100万回言ってますけど、この辺の調査/検証をお家で好きにできると、色々と敷居が下がるので。- こうなってくると、本記事の
torSW[12]01a
にあたるところに、QFX5110
とかQFX5200
とかの仮想版も欲しくなってきますね
- こうなってくると、本記事の
- この辺のニッチな話に興味がある人、冒頭で紹介した oreilly の「Juniper QFX10000 Series」もオススメですよ!
- 独自プロセッサ開発経緯や特徴・Architecture(HW/SW) の結構詳しい説明・MPLS/VXLAN+EVPNの設計ポイント とか、箱を持っていなくても読んでいて楽しいです
- Juniper QFX10000 最高!みんな買おうぜ!!(買えない)
vQFX10000 で VXLAN+EVPN (evpn-inter-subnet-forwarding(Symmetric) 編) (original : 2017/01/09)
この記事は某所で 2017/01/09
に書いたもののコピーです。
そのため 2017/05/13
時点ではやや古い情報も含まれています。(以下一例)
- 201705 に
GNS3 ver2.0 stable
が出た
.
最初に
先日(vQFX10000 を KVM+GNS3 で動かす)、Juniper vQFX10000(以降 vQFX) の DL 権限を個人で得て GNS3 で軽く動作確認をとり、前回(vQFX10000 で VXLAN+EVPN (L2 over L3 編))、仮想版でも L2VPN 機能が動くことを確認しました。
QFX10000系では EVPN NLRI Type5 Route (参考資料の draft 参照)で Symmetric な evpn-inter-subnet-forwarding ができるようなので、今回は vQFX でそれを試します。(あらすじが長い...)
本項でやること
- vQFX で VXLAN の Control Plane として EVPN を動かす
- EVPN NLRI Type5(EVPN Prefix Advertisement) を使って evpn-inter-subnet-forwarding (Symmetric)を動かす
- 前回の NLRI Type2+3 を使った L2 over L3 も併用できるか確認する
- 下図の赤い点線部分
- Type5 を使って VRFtoVRF しているドキュメントでは「セグメントが単一サイト(/部屋)に閉じる場合には」という文言があったりするけれど
概要構成図
前回に引き続き、下図の感じで。
余談。
本環境の GNS3 1.5.2
でパケットキャプチャするために、qemu 同士を直結せずに、間に GNS3 の Ethernet Switch を挟む構成にしてます。が、「pelican@ainoniwa.net / GNS3 2.0からはKVM間のパケットキャプチャも取れるようになるぞい」のように GNS3 2.0
(2017/01/04 時点では beta 版, 2017/05/13時点ではstable版公開済)を使えば、これが不要になります。やったぜ!
参考資料
- 前回の参考資料 全般
- EVPN 標準
- draft-ietf-bess-evpn-prefix-advertisement-03 (IP Prefix Advertisement in EVPN)
- EVPN NLRI Type5 を使って IP-VRF to IP-VRF で IP Prefix Advertise しようというお話
- draft-ietf-bess-evpn-inter-subnet-forwarding-01 (Integrated Routing and Bridging in EVPN)
- L3 全般
Asymmetric
とSymmetric
に関する話はこれを読むとわかる
- draft-ietf-bess-evpn-prefix-advertisement-03 (IP Prefix Advertisement in EVPN)
- JUNOS での VXLAN+EVPN inter-subnet-forwarding 実装・設定周り
- Juniper公式 / ip-prefix-routes コマンド at JUNOS15.1
Statement introduced in Junos OS Release 15.1x53-D60 for QFX10000 Series switches.
だそうな- んで vQFX(
15.1X53-D60.4
)でも設定可能
- 少し前の実装
- Juniper公式 / ip-prefix-support コマンド at JUNOS15.1
Statement introduced in Junos OS Release 15.1x53-D30 on QFX10002 switches.
だそうでThis statement is deprecated starting with Junos OS Release 15.1x53-D60 and has been replaced with ip-prefix-routes.
ってことらしく、バージョンをあげると自動的にip-prefix-routes
になるらしいので- vQFX(
15.1X53-D60.4
)では設定不可
- Juniper公式 / Configuring EVPN Type 5 for QFX10000 Series Switches / Configuration Example
- 上記を用いた分かりやすいサンプル
- Juniper公式 / ip-prefix-support コマンド at JUNOS15.1
- NetOne コラム / EVPN で変わる・変えられるデータセンターネットワーク1
- Juniper MX を使った L2 + L3 の具体的な例(2016/03 時点のものみたい)
- 多分これは
Asymmetric
なやつ - 日本語で嚙み砕いた説明
- Juniper公式 / ip-prefix-routes コマンド at JUNOS15.1
- その他
- Cisco 発表資料(20160120) / VXLANチュートリアル
- スライド 16-25 に
Asymmetric
とSymmetric
の噛み砕いだ日本語図解あり - この時点では「Juniper のは
Asymmetric
実装・Cisco のはSymmetric
実装」と紹介されているが - 2017/01現在は Juniper にも
Symmetric
実装があるよ、というのを本項で扱う
- スライド 16-25 に
- Cisco 発表資料(20160120) / VXLANチュートリアル
- O'Reilly Juniper QFX10000 Series
- Juniper QFX10000 の独自プロセッサ開発経緯や特徴・Architecture(HW/SW) の結構詳しい説明・MPLS/VXLAN+EVPNの設計ポイント解説などが纏まった非常に良い本
Juniper QFX10000 Series: A Comprehensive Guide to Building Next-Generation Data Centers
- 作者: Douglas Richard, Jr. Hanks
- 出版社/メーカー: O'Reilly Media
- 発売日: 2016/08/11
- メディア: ペーパーバック
- この商品を含むブログを見る
- Juniper QFX10000 の独自プロセッサ開発経緯や特徴・Architecture(HW/SW) の結構詳しい説明・MPLS/VXLAN+EVPNの設計ポイント解説などが纏まった非常に良い本
構築~動作確認
GNS3 でデプロイ
前回の環境を引き続き使います。先にあげた概要構成図の通り。
疎通確認用 node 設定
以下のような感じで
kotetsu@node11:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:e2:60:01 brd ff:ff:ff:ff:ff:ff inet 192.168.1.1/24 brd 192.168.1.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fee2:6001/64 scope link valid_lft forever preferred_lft forever kotetsu@node11:~$ ip route show dev ens4 192.168.0.0/16 via 192.168.1.254 192.168.1.0/24 proto kernel scope link src 192.168.1.1
kotetsu@node21:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:46:d8:01 brd ff:ff:ff:ff:ff:ff inet 192.168.1.2/24 brd 192.168.1.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fe46:d801/64 scope link valid_lft forever preferred_lft forever kotetsu@node21:~$ ip route show dev ens4 192.168.0.0/16 via 192.168.1.254 192.168.1.0/24 proto kernel scope link src 192.168.1.2
kotetsu@node22:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:3d:e0:01 brd ff:ff:ff:ff:ff:ff inet 192.168.2.2/24 brd 192.168.2.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fe3d:e001/64 scope link valid_lft forever preferred_lft forever kotetsu@node22:~$ ip route show dev ens4 192.168.0.0/16 via 192.168.2.254 192.168.2.0/24 proto kernel scope link src 192.168.2.2
kotetsu@node13:~$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:37:c4:0d:a8:01 brd ff:ff:ff:ff:ff:ff inet 192.168.3.1/24 brd 192.168.3.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::237:c4ff:fe0d:a801/64 scope link valid_lft forever preferred_lft forever kotetsu@node13:~$ ip route show dev ens4 192.168.0.0/16 via 192.168.3.254 192.168.3.0/24 proto kernel scope link src 192.168.3.1
vQFX 基本設定ちょいたし
EVPN にこんな設定をして /var/log/evpn.log
で追えるようにしときました。flag all
にしたらちょっと追いきれない情報量になったので、そこはお好みで...。
set protocols evpn traceoptions file evpn.log set protocols evpn traceoptions file size 10k set protocols evpn traceoptions file files 30 set protocols evpn traceoptions flag all
vQFX Inter Subnet Forwarding 設定~確認
Inter Subnet Forwarding 設定
spine11
前回こんな感じの設定を入れてあったので
{master:0}[edit] kotetsu@spine11# show vlans | display set set vlans VLAN0100 vlan-id 100 set vlans VLAN0100 vxlan vni 10100 set vlans VLAN0100 vxlan ingress-node-replication set vlans VLAN0300 vlan-id 300 set vlans VLAN0300 vxlan vni 10300 set vlans VLAN0300 vxlan ingress-node-replication set vlans default vlan-id 1
以下で IRB 作成 ~ VRF 作成
set interfaces irb unit 100 family inet address 192.168.1.254/24 set interfaces irb unit 100 proxy-macip-advertisement set interfaces irb unit 300 family inet address 192.168.3.254/24 set interfaces irb unit 300 proxy-macip-advertisement set vlans VLAN0100 l3-interface irb.100 set vlans VLAN0300 l3-interface irb.300 set interfaces lo0 unit 1 family inet address 198.18.1.11/32 set routing-instances VRF001 instance-type vrf set routing-instances VRF001 interface irb.100 set routing-instances VRF001 interface irb.300 set routing-instances VRF001 interface lo0.1 set routing-instances VRF001 route-distinguisher 50001:11 set routing-instances VRF001 vrf-target target:64512:50001 set routing-instances VRF001 protocols evpn ip-prefix-routes advertise direct-nexthop set routing-instances VRF001 protocols evpn ip-prefix-routes encapsulation vxlan set routing-instances VRF001 protocols evpn ip-prefix-routes vni 50001
ポイントは protocols evpn ip-prefix-routes
周りの設定ですね。
これで VRF to VRF で EVPN NLRI Type5 で IP Prefix や自分の MAC アドレス(Router's MAC) を送信できるようになるはず。
Juniper公式 / ReleaseNotes Junos 15.1X53-D60 for QFX10000 Switches の 19 ページによると
Best practice for EVPN-VXLAN configuration (QFX10000 switches)—Starting with Junos OS Release 15.1X53-D60, in an EVPN-VXLAN configuration on QFX10000 switches, you no longer need to configure vxlan ingress-node-replication.
だそうな。なんでだろ。とにかく Best Practice なら従っておくのがよかろうということで。
delete vlans VLAN0100 vxlan ingress-node-replication delete vlans VLAN0300 vxlan ingress-node-replication
これを消さずにテストしていた時、なんか EVPN NLRI Type3 を送ってきていない Remote VTEP と VNI の組み合わせに対して BUM を ingress replication 転送してたんだよな...ということで消すのが正解と思います。
あと自分の環境起因かもですが、この辺の設定追加・変更して commit した時に、bb01 と spine[12]1 の間で LLDP や BGP がフラッピングし始めることがありました。ちゃんと追ってないですが、そんな時にはおとなしく request system reboot
して落ち着かせました。(雑)
spine21
spine11 とほとんど一緒です。
前回こんな感じの設定を入れてあったので
{master:0}[edit] kotetsu@spine21# show vlans | display set set vlans VLAN0100 vlan-id 100 set vlans VLAN0100 vxlan vni 10100 set vlans VLAN0100 vxlan ingress-node-replication set vlans VLAN0200 vlan-id 200 set vlans VLAN0200 vxlan vni 10200 set vlans VLAN0200 vxlan ingress-node-replication set vlans default vlan-id 1
以下で IRB 作成 ~ VRF 作成
set interfaces irb unit 100 family inet address 192.168.1.254/24 set interfaces irb unit 100 proxy-macip-advertisement set interfaces irb unit 200 family inet address 192.168.2.254/24 set interfaces irb unit 200 proxy-macip-advertisement set vlans VLAN0100 l3-interface irb.100 set vlans VLAN0200 l3-interface irb.200 set interfaces lo0 unit 1 family inet address 198.18.1.21/32 set routing-instances VRF001 instance-type vrf set routing-instances VRF001 interface irb.100 set routing-instances VRF001 interface irb.200 set routing-instances VRF001 interface lo0.1 set routing-instances VRF001 route-distinguisher 50001:21 set routing-instances VRF001 vrf-target target:64512:50001 set routing-instances VRF001 protocols evpn ip-prefix-routes advertise direct-nexthop set routing-instances VRF001 protocols evpn ip-prefix-routes encapsulation vxlan set routing-instances VRF001 protocols evpn ip-prefix-routes vni 50001
前述の通り Best Practice に従っておく。
delete vlans VLAN0100 vxlan ingress-node-replication delete vlans VLAN0200 vxlan ingress-node-replication
動作確認
IPアドレス・MACアドレス情報 整理
ちょっとノード数が増えてきたので、まとめときます。
VLAN | IPアドレス | MACアドレス | ノード | インターフェース | 備考 |
---|---|---|---|---|---|
100 | 192.168.1.1/24 |
00:37:c4:e2:60:01 |
node11 |
ens4 |
spine11 配下 |
100 | 192.168.1.2/24 |
00:37:c4:46:d8:01 |
node21 |
ens4 |
spine21 配下 |
100 | 192.168.1.254/24 |
02:05:86:71:3c:00 |
spine11 |
irb |
|
100 | 192.168.1.254/24 |
02:05:86:71:d8:00 |
spine21 |
irb |
|
200 | 192.168.2.2/24 |
00:37:c4:3d:e0:01 |
node22 |
ens4 |
spine21 配下 |
200 | 192.168.2.254/24 |
02:05:86:71:d8:00 |
spine21 |
irb |
|
300 | 192.168.3.1/24 |
00:37:c4:0d:a8:01 |
node13 |
ens4 |
spine11 配下 |
300 | 192.168.3.254/24 |
02:05:86:71:3c:00 |
spine11 |
irb |
|
- | 192.0.2.1/30 |
02:05:86:71:21:03 |
bb01 |
xe-0/0/0 |
spine21 側 |
- | 192.0.2.2/30 |
02:05:86:71:3c:03 |
spine11 |
xe-0/0/0 |
bb01 側 |
- | 192.0.2.5/30 |
02:05:86:71:21:07 |
bb01 |
xe-0/0/1 |
spine21 側 |
- | 192.0.2.6/30 |
02:05:86:71:d8:03 |
spine21 |
xe-0/0/0 |
bb01 側 |
spine11 と spine21 の IRB MAC アドレス at VLAN100 は各物理のものになっていて、共有用の仮想 MAC を設定したりはしていないです。
spine11 配下の node11 は spine11 の IRB MACアドレスをゲートウェイとして使い、spine21 配下の node21 は spine21 の IRB MACアドレスをゲートウェイとして使う...ってな動きになるのか、を見ようという主旨。
node間疎通確認~ARPテーブル確認
4 台の node 間をフルメッシュに ping 簡易疎通確認、とりあえず疎通オールおっけー。
直後 ARP テーブル確認
- node11(192.168.1.1/24)
kotetsu@node11:~$ ip n show dev ens4 192.168.1.254 lladdr 02:05:86:71:3c:00 REACHABLE ## spine11 IRB の MACaddr 192.168.1.2 lladdr 00:37:c4:46:d8:01 STALE
- node21(192.168.1.2/24)
kotetsu@node21:~$ ip n show dev ens4 192.168.1.254 lladdr 02:05:86:71:d8:00 REACHABLE ## spine21 IRB の MACaddr 192.168.1.1 lladdr 00:37:c4:e2:60:01 REACHABLE
- node13(192.168.3.1/24)
kotetsu@node13:~$ ip n show dev ens4 192.168.3.254 lladdr 02:05:86:71:3c:00 STALE ## spine11 IRB の MACaddr
- node22(192.168.2.2/24)
kotetsu@node22:~$ ip n show dev ens4 192.168.2.254 lladdr 02:05:86:71:d8:00 REACHABLE ## spine21 IRB の MACaddr
ちなみに spine11 や spine12 から ping を実行しようとしたら、自発パケットを EVPN 方面には流られないっぽいです。そりゃあそうか。
{master:0} kotetsu@spine21> ping routing-instance VRF001 192.168.1.2 PING 192.168.1.2 (192.168.1.2): 56 data bytes 64 bytes from 192.168.1.2: icmp_seq=0 ttl=64 time=6.448 ms 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=5.700 ms {master:0} kotetsu@spine21> ping routing-instance VRF001 192.168.3.1 PING 192.168.3.1 (192.168.3.1): 56 data bytes ping: sendto: Operation not supported ping: sendto: Operation not supported {master:0} kotetsu@spine21> show route table VRF001.inet.0 192.168.3.0/24 VRF001.inet.0: 8 destinations, 9 routes (8 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 192.168.3.0/24 *[EVPN/170] 20:55:03 > to 192.0.2.5 via xe-0/0/0.0
パッと見は巧いこと通信できているようですが...ちょっと中身を追っていきます。
vQFXテーブル確認
EVPN
両方の spine につくっている VLAN100(VNI 10100)の MAC 情報だけが Remote から学習したものに含まれ...ってやはり Router's MAC
として 192.168.1.254
の実 MAC 2 台分を学習している。
{master:0} kotetsu@spine11> show evpn database Instance: default-switch VLAN VNI MAC address Active source Timestamp IP address 10100 00:37:c4:46:d8:01 172.16.2.1 Jan 08 21:35:56 10100 00:37:c4:e2:60:01 xe-0/0/1.0 Jan 08 01:30:42 192.168.1.1 10100 02:05:86:71:3c:00 irb.100 Jan 08 12:50:23 192.168.1.254 10100 02:05:86:71:d8:00 172.16.2.1 Jan 08 12:50:38 192.168.1.254 10300 00:37:c4:0d:a8:01 xe-0/0/1.0 Jan 08 01:30:41 192.168.3.1 10300 02:05:86:71:3c:00 irb.300 Jan 08 01:27:27 192.168.3.254
{master:0} kotetsu@spine21> show evpn database Instance: default-switch VLAN VNI MAC address Active source Timestamp IP address 10100 00:37:c4:46:d8:01 xe-0/0/1.0 Jan 08 01:30:41 192.168.1.2 10100 00:37:c4:e2:60:01 172.16.1.1 Jan 08 21:42:10 192.168.1.1 10100 02:05:86:71:3c:00 172.16.1.1 Jan 08 12:53:48 192.168.1.254 10100 02:05:86:71:d8:00 irb.100 Jan 08 12:54:02 192.168.1.254 10200 00:37:c4:3d:e0:01 xe-0/0/1.0 Jan 08 01:30:41 192.168.2.2 10200 02:05:86:71:d8:00 irb.200 Jan 08 01:16:21 192.168.2.254
自分が吐いている Type5 情報サマリ
{master:0} kotetsu@spine11> show evpn l3-context L3 context Type Adv Encap VNI/Label Router MAC/GW intf VRF001 Cfg Direct VXLAN 50001 02:05:86:71:3c:00
{master:0} kotetsu@spine21> show evpn l3-context L3 context Type Adv Encap VNI/Label Router MAC/GW intf VRF001 Cfg Direct VXLAN 50001 02:05:86:71:d8:00
Remote から Type 5 で学習した Router's MAC を確認して
{master:0} kotetsu@spine11> show evpn ip-prefix-database L3 context: VRF001 IPv4->EVPN Exported Prefixes Prefix EVPN route status 192.168.1.0/24 Created 192.168.3.0/24 Created EVPN->IPv4 Imported Prefixes Prefix Etag IP route status 192.168.1.0/24 0 Created Route distinguisher St VNI/Label Router MAC Nexthop/Overlay GW/ESI 50001:21 A 50001 02:05:86:71:d8:00 172.16.2.1 192.168.2.0/24 0 Created Route distinguisher St VNI/Label Router MAC Nexthop/Overlay GW/ESI 50001:21 A 50001 02:05:86:71:d8:00 172.16.2.1
{master:0} kotetsu@spine21> show evpn ip-prefix-database L3 context: VRF001 IPv4->EVPN Exported Prefixes Prefix EVPN route status 192.168.1.0/24 Created 192.168.2.0/24 Created EVPN->IPv4 Imported Prefixes Prefix Etag IP route status 192.168.1.0/24 0 Created Route distinguisher St VNI/Label Router MAC Nexthop/Overlay GW/ESI 50001:11 A 50001 02:05:86:71:3c:00 172.16.1.1 192.168.3.0/24 0 Created Route distinguisher St VNI/Label Router MAC Nexthop/Overlay GW/ESI 50001:11 A 50001 02:05:86:71:3c:00 172.16.1.1
Routing Table
当該 VRF の Routing Table サマリーを見て
{master:0} kotetsu@spine11> show route instance VRF001 extensive VRF001: Router ID: 198.18.1.11 Type: vrf State: Active Interfaces: irb.100 irb.300 lo0.1 Route-distinguisher: 50001:11 Vrf-import: [ __vrf-import-VRF001-internal__ ] Vrf-export: [ __vrf-export-VRF001-internal__ ] Vrf-import-target: [ target:64512:50001 ] Vrf-export-target: [ target:64512:50001 ] Fast-reroute-priority: low Tables: VRF001.inet.0 : 9 routes (8 active, 0 holddown, 0 hidden) VRF001.inet.3 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.iso.0 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.inet6.0 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.inet6.3 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.mdt.0 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.evpn.0 : 4 routes (4 active, 0 holddown, 0 hidden)
{master:0} kotetsu@spine21> show route instance VRF001 extensive VRF001: Router ID: 198.18.1.21 Type: vrf State: Active Interfaces: irb.100 irb.200 lo0.1 Route-distinguisher: 50001:21 Vrf-import: [ __vrf-import-VRF001-internal__ ] Vrf-export: [ __vrf-export-VRF001-internal__ ] Vrf-import-target: [ target:64512:50001 ] Vrf-export-target: [ target:64512:50001 ] Fast-reroute-priority: low Tables: VRF001.inet.0 : 9 routes (8 active, 0 holddown, 0 hidden) VRF001.inet.3 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.iso.0 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.inet6.0 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.inet6.3 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.mdt.0 : 0 routes (0 active, 0 holddown, 0 hidden) VRF001.evpn.0 : 4 routes (4 active, 0 holddown, 0 hidden)
中身のサマリをみる。まずは「bgp.evpn.0 = Junos OS ルーティング プロトコル プロセス(RPD)内のグローバル EVPN ルーティング テーブル」を
{master:0} kotetsu@spine11> show route table bgp.evpn.0 bgp.evpn.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 1:172.16.2.1:0::050000fdea0000277400::FFFF:FFFF/304 *[BGP/170] 21:18:16, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 1:172.16.2.1:0::050000fdea000027d800::FFFF:FFFF/304 *[BGP/170] 21:18:16, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 2:64512:21::10100::00:37:c4:46:d8:01/304 *[BGP/170] 19:24:02, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 2:64512:21::10100::02:05:86:71:d8:00/304 *[BGP/170] 09:57:37, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 2:64512:21::10100::00:37:c4:46:d8:01::192.168.1.2/304 *[BGP/170] 09:36:35, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 2:64512:21::10100::00:37:c4:46:d8:01::192.168.1.2/304 *[BGP/170] 09:36:35, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 2:64512:21::10100::02:05:86:71:d8:00::192.168.1.254/304 *[BGP/170] 09:57:37, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 3:64512:21::10100::172.16.2.1/304 *[BGP/170] 19:24:02, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 5:50001:21::0::192.168.1.0::24/304 *[BGP/170] 21:18:16, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 5:50001:21::0::192.168.2.0::24/304 *[BGP/170] 21:18:16, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0
{master:0} kotetsu@spine21> show route table bgp.evpn.0 bgp.evpn.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 1:172.16.1.1:0::050000fde90000277400::FFFF:FFFF/304 *[BGP/170] 10:02:28, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 1:172.16.1.1:0::050000fde90000283c00::FFFF:FFFF/304 *[BGP/170] 21:26:18, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 2:64512:11::10100::00:37:c4:e2:60:01/304 *[BGP/170] 19:32:22, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 2:64512:11::10100::02:05:86:71:3c:00/304 *[BGP/170] 10:02:28, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 2:64512:11::10100::00:37:c4:e2:60:01::192.168.1.1/304 *[BGP/170] 10:01:04, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 2:64512:11::10100::02:05:86:71:3c:00::192.168.1.254/304 *[BGP/170] 10:02:28, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 3:64512:11::10100::172.16.1.1/304 *[BGP/170] 19:32:21, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 5:50001:11::0::192.168.1.0::24/304 *[BGP/170] 10:02:29, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 5:50001:11::0::192.168.3.0::24/304 *[BGP/170] 21:26:18, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0
次に当該 VRF のさまりー
{master:0} kotetsu@spine11> show route table VRF001.evpn.0 VRF001.evpn.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 5:50001:11::0::192.168.1.0::24/304 *[EVPN/170] 10:15:34 Indirect 5:50001:11::0::192.168.3.0::24/304 *[EVPN/170] 21:36:19 Indirect 5:50001:21::0::192.168.1.0::24/304 *[BGP/170] 21:35:58, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 5:50001:21::0::192.168.2.0::24/304 *[BGP/170] 21:35:58, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 {master:0} kotetsu@spine11> show route table VRF001.inet.0 VRF001.inet.0: 8 destinations, 9 routes (8 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 192.168.1.0/24 *[Direct/0] 10:11:26 > via irb.100 [EVPN/170] 21:31:50 > to 192.0.2.1 via xe-0/0/0.0 192.168.1.1/32 *[EVPN/7] 10:10:01 > via irb.100 192.168.1.254/32 *[Local/0] 10:11:27 Local via irb.100 192.168.2.0/24 *[EVPN/170] 21:31:50 > to 192.0.2.1 via xe-0/0/0.0 192.168.3.0/24 *[Direct/0] 21:32:11 > via irb.300 192.168.3.1/32 *[EVPN/7] 21:31:06 > via irb.300 192.168.3.254/32 *[Local/0] 21:34:23 Local via irb.300 198.18.1.11/32 *[Direct/0] 21:34:23 > via lo0.1
{master:0} kotetsu@spine21> show route table VRF001.evpn.0 VRF001.evpn.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 5:50001:11::0::192.168.1.0::24/304 *[BGP/170] 10:19:12, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 5:50001:11::0::192.168.3.0::24/304 *[BGP/170] 21:43:01, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 5:50001:21::0::192.168.1.0::24/304 *[EVPN/170] 10:18:58 Indirect 5:50001:21::0::192.168.2.0::24/304 *[EVPN/170] 21:54:15 Indirect {master:0} kotetsu@spine21> show route table VRF001.inet.0 VRF001.inet.0: 8 destinations, 9 routes (8 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 192.168.1.0/24 *[Direct/0] 10:16:27 > via irb.100 [EVPN/170] 10:16:41 > to 192.0.2.5 via xe-0/0/0.0 192.168.1.2/32 *[EVPN/7] 10:16:10 > via irb.100 192.168.1.254/32 *[Local/0] 10:16:27 Local via irb.100 192.168.2.0/24 *[Direct/0] 21:51:44 > via irb.200 192.168.2.2/32 *[EVPN/7] 21:39:37 > via irb.200 192.168.2.254/32 *[Local/0] 21:54:08 Local via irb.200 192.168.3.0/24 *[EVPN/170] 21:40:30 > to 192.0.2.5 via xe-0/0/0.0 198.18.1.21/32 *[Direct/0] 21:54:08 > via lo0.1
最後に Type 5 route の詳細を見ておく。こいつらは VRF001.evpn.0
にもロードされている。
{master:0} kotetsu@spine11> show route table bgp.evpn.0 extensive ... 5:50001:21::0::192.168.1.0::24/304 (1 entry, 0 announced) *BGP Preference: 170/-101 Route Distinguisher: 50001:21 Next hop type: Indirect, Next hop index: 0 Address: 0xaa605f0 Next-hop reference count: 18 Source: 172.31.0.1 Protocol next hop: 172.16.2.1 Indirect next hop: 0x2 no-forward INH Session ID: 0x0 State: <Active Int Ext> Local AS: 65001 Peer AS: 64512 Age: 21:25:33 Metric2: 0 Validation State: unverified Task: BGP_64512_64512.172.31.0.1 AS path: I (Originator) Cluster list: 172.31.0.1 Originator ID: 172.16.2.1 Communities: target:64512:50001 encapsulation0:0:0:0:vxlan router-mac:02:05:86:71:d8:00 Import Accepted Route Label: 50001 Overlay gateway address: 0.0.0.0 ESI 00:00:00:00:00:00:00:00:00:00 Localpref: 100 Router ID: 172.31.0.1 Secondary Tables: VRF001.evpn.0 Indirect next hops: 1 Protocol next hop: 172.16.2.1 Indirect next hop: 0x2 no-forward INH Session ID: 0x0 Indirect path forwarding next hops: 1 Next hop type: Router Next hop: 192.0.2.1 via xe-0/0/0.0 Session Id: 0x0 172.16.2.1/32 Originating RIB: inet.0 Node path count: 1 Forwarding nexthops: 1 Nexthop: 192.0.2.1 via xe-0/0/0.0 5:50001:21::0::192.168.2.0::24/304 (1 entry, 0 announced) *BGP Preference: 170/-101 Route Distinguisher: 50001:21 Next hop type: Indirect, Next hop index: 0 Address: 0xaa605f0 Next-hop reference count: 18 Source: 172.31.0.1 Protocol next hop: 172.16.2.1 Indirect next hop: 0x2 no-forward INH Session ID: 0x0 State: <Active Int Ext> Local AS: 65001 Peer AS: 64512 Age: 21:25:33 Metric2: 0 Validation State: unverified Task: BGP_64512_64512.172.31.0.1 AS path: I (Originator) Cluster list: 172.31.0.1 Originator ID: 172.16.2.1 Communities: target:64512:50001 encapsulation0:0:0:0:vxlan router-mac:02:05:86:71:d8:00 Import Accepted Route Label: 50001 Overlay gateway address: 0.0.0.0 ESI 00:00:00:00:00:00:00:00:00:00 Localpref: 100 Router ID: 172.31.0.1 Secondary Tables: VRF001.evpn.0 Indirect next hops: 1 Protocol next hop: 172.16.2.1 Indirect next hop: 0x2 no-forward INH Session ID: 0x0 Indirect path forwarding next hops: 1 Next hop type: Router Next hop: 192.0.2.1 via xe-0/0/0.0 Session Id: 0x0 172.16.2.1/32 Originating RIB: inet.0 Node path count: 1 Forwarding nexthops: 1 Nexthop: 192.0.2.1 via xe-0/0/0.0
{master:0} kotetsu@spine21> show route table bgp.evpn.0 extensive ... 5:50001:11::0::192.168.1.0::24/304 (1 entry, 0 announced) *BGP Preference: 170/-101 Route Distinguisher: 50001:11 Next hop type: Indirect, Next hop index: 0 Address: 0xaa60170 Next-hop reference count: 18 Source: 172.31.0.1 Protocol next hop: 172.16.1.1 Indirect next hop: 0x2 no-forward INH Session ID: 0x0 State: <Active Int Ext> Local AS: 65002 Peer AS: 64512 Age: 10:04:02 Metric2: 0 Validation State: unverified Task: BGP_64512_64512.172.31.0.1 AS path: I (Originator) Cluster list: 172.31.0.1 Originator ID: 172.16.1.1 Communities: target:64512:50001 encapsulation0:0:0:0:vxlan router-mac:02:05:86:71:3c:00 Import Accepted Route Label: 50001 Overlay gateway address: 0.0.0.0 ESI 00:00:00:00:00:00:00:00:00:00 Localpref: 100 Router ID: 172.31.0.1 Secondary Tables: VRF001.evpn.0 Indirect next hops: 1 Protocol next hop: 172.16.1.1 Indirect next hop: 0x2 no-forward INH Session ID: 0x0 Indirect path forwarding next hops: 1 Next hop type: Router Next hop: 192.0.2.5 via xe-0/0/0.0 Session Id: 0x0 172.16.1.1/32 Originating RIB: inet.0 Node path count: 1 Forwarding nexthops: 1 Nexthop: 192.0.2.5 via xe-0/0/0.0 5:50001:11::0::192.168.3.0::24/304 (1 entry, 0 announced) *BGP Preference: 170/-101 Route Distinguisher: 50001:11 Next hop type: Indirect, Next hop index: 0 Address: 0xaa60170 Next-hop reference count: 18 Source: 172.31.0.1 Protocol next hop: 172.16.1.1 Indirect next hop: 0x2 no-forward INH Session ID: 0x0 State: <Active Int Ext> Local AS: 65002 Peer AS: 64512 Age: 21:27:51 Metric2: 0 Validation State: unverified Task: BGP_64512_64512.172.31.0.1 AS path: I (Originator) Cluster list: 172.31.0.1 Originator ID: 172.16.1.1 Communities: target:64512:50001 encapsulation0:0:0:0:vxlan router-mac:02:05:86:71:3c:00 Import Accepted Route Label: 50001 Overlay gateway address: 0.0.0.0 ESI 00:00:00:00:00:00:00:00:00:00 Localpref: 100 Router ID: 172.31.0.1 Secondary Tables: VRF001.evpn.0 Indirect next hops: 1 Protocol next hop: 172.16.1.1 Indirect next hop: 0x2 no-forward INH Session ID: 0x0 Indirect path forwarding next hops: 1 Next hop type: Router Next hop: 192.0.2.5 via xe-0/0/0.0 Session Id: 0x0 172.16.1.1/32 Originating RIB: inet.0 Node path count: 1 Forwarding nexthops: 1 Nexthop: 192.0.2.5 via xe-0/0/0.0
MAC アドレステーブル
Type 2 から学習しているのは、両方の VTEP にくっつけている VLAN 100 = VNI 10100 のみ
{master:0} kotetsu@spine11> show ethernet-switching table MAC flags (S - static MAC, D - dynamic MAC, L - locally learned, P - Persistent static SE - statistics enabled, NM - non configured MAC, R - remote PE MAC, O - ovsdb MAC) Ethernet switching table : 4 entries, 4 learned Routing instance : default-switch Vlan MAC MAC Logical Active name address flags interface source VLAN0100 00:37:c4:46:d8:01 D vtep.32769 172.16.2.1 VLAN0100 00:37:c4:e2:60:01 D xe-0/0/1.0 VLAN0100 02:05:86:71:d8:00 D vtep.32769 172.16.2.1 VLAN0300 00:37:c4:0d:a8:01 D xe-0/0/1.0
{master:0} kotetsu@spine21> show ethernet-switching table MAC flags (S - static MAC, D - dynamic MAC, L - locally learned, P - Persistent static SE - statistics enabled, NM - non configured MAC, R - remote PE MAC, O - ovsdb MAC) Ethernet switching table : 4 entries, 4 learned Routing instance : default-switch Vlan MAC MAC Logical Active name address flags interface source VLAN0100 00:37:c4:46:d8:01 D xe-0/0/1.0 VLAN0100 00:37:c4:e2:60:01 D vtep.32769 172.16.1.1 VLAN0100 02:05:86:71:3c:00 D vtep.32769 172.16.1.1 VLAN0200 00:37:c4:3d:e0:01 D xe-0/0/1.0
通信確認詳細(DataPlane)
各通信の様子を見ていきます。それぞれ、実行前に sudo ip n flush dev ens4
とかしてます。
L3 Symmetric
node22(192.168.2.2/24) から node13(192.168.3.1/24) へ ping
以下、ICMP Echo request を spine21 と bb01 間で拾ったもの。
VXLANカプセル内の Eth ヘッダを見ると、Type5で学習した spine11 の irb MAC アドレスを Dst に指定されています。
なお、ICMP Echo Reply も同じ感じです。
L2 over L3
node21(192.168.1.2/24) から node11(192.168.1.1/24) へ ping
これは前回と同様に、単純に VNI 10100 でカプセル化されて通信しているだけ。
L3 往路 Symmetric 復路 Asymmetric
node11(192.168.1.1/24) から node22(192.168.2.2/24) へ ping
このケースが、どう動くのかイマイチ予測できなかったところです。
- 往路 node11 がゲートウェイIPアドレス(192.168.1.254) ARP 解決を試みる
- 往路 spine11 が node11 に 自身の irb MAC アドレスを答える (この時「自分が応答したので ARP request を VNI 10100 方面には転送しない」という動作になってくれるのか否かが予想できなかった & 確認したかった)
- 往路 spine11 は node11 からの Dst IP(192.168.2.2/24) な ICMP Echo request パケットを受信し、Type5 で得た情報に従い VNI 50001 でカプセル化して spine21 に投げる (Symmetric)
- 往路 spine21 は自分の irb direct 配下にいる node22 にフォワードするだけ
- 復路 node22 はゲートウェイIPアドレス(192.168.2.254)の ARP 解決をして、spine21 の irb MAC に ICMP Echo Reply 投げる
- 復路 spine21 は node22 からの Dst IP(192.168.1.1/24) な ICMP Echo Reply パケットを受信し、Type2 で得た情報に従い VNI 10100 でカプセル化して spine11 に投げる (Asymmetric)
- 復路 spine11 は自分の irb direct 配下にいる node11 にフォワードするだけ
という感じに予測して、行きと戻りの VNI が異なる論理的に非対称な通信でちゃんと成り立っているのか、っていうのと太字箇所を見ていきます。いやまあ疎通は確認済なんですが。
まず node11 で拾ったパケットを見ると...はい、上記の太字箇所は期待した動作になっていないですね。
spine11 と spine21 双方の irb から ARP Reply が来ていて(パケットNo.2と4)、たまたま node の仕様的に先に返ってきた spine11 側の MAC アドレスを使っていたに過ぎないようです。
上記の動作を、今度は spine11 と bb01 間で拾ったパケットで追ってみます。
このパケットNo.16 が「自分が node11 に ARP Reply した直後、ARP Request を VNI 10100 で spine21 方面に Ingress Replication している」やつです。
当然、spine21 側は通常通り ARP Reply を返してくれるし、それは先ほど node11 側で見た通り node11 にも伝搬されます。
ということで、ARP Request に対する Reply の動作確認は、自分が期待していたのと違う動きのようです。
構成や設定でどうにか巧いことならないか...ってところは深追いしていません。
(試しに spine[12]1 双方で set interfaces irb unit 100 mac 00:00:5e:00:53:99
とか virtual-gateway-address
とか設定して同じ MAC アドレスを持たせてみたりはしましたが...それでも通信は可能だけれど、特に代表動作とかをしないIP/MAC重複状態なので、健全な状態とは言えないかと。)
あ、往路 VNI 50001, 復路 VNI 10100 に関しては、想定通りの動きでした。
パケットキャプチャ(ControlPlane)
EVPN NLRI Type5 の UPDATE と WithDrawn を軽く見ておきます。
まずは WithDrawn を spine21 から吐かせた時(雑に deactivate routing-instance VRF001
とかで)
UPDATE を spine21 から吐かせた時(雑に rollback 1
とかで)
おしまい
- Juniper vQFX10000 でも EVPN NLRI Type5 が動くことを確認できました
- VRF to VRF 動作と L2VPN を併用する場合、何らかの工夫が必要そうだということは分かりました
- 「L3 往路 Symmetric 復路 Asymmetric」の項でウダウダ書いた通り
- そもそも MX を使って MAC VRF 使う、のが常道なのかもしれませんが
vQFX10000 で VXLAN+EVPN (L2 over L3 編) (original : 2017/01/02)
この記事は某所で 2017/01/02
に書いた記事のコピーです。
そのため 2017/05/11
時点ではやや古い情報も含まれています。(以下一例)
- Juniper さんの vQFX ダウンロード規約が変わっていそう (詳細は未確認)
- 201705 に
GNS3 ver2.0 stable
が出たので KVM 間のパケットキャプチャ用に GNS3 のハブを挟む必要がなくなった
.
- 最初に
- 構築~動作確認
- おしまい
最初に
前回(vQFX10000 を KVM+GNS3 で動かす)、Juniper vQFX10000(以降 vQFX) の DL 権限を個人で得て GNS3 で軽く動作確認がとれました。 今回は「仮想版って L2全般/L2VPN 系機能が動かなかったりするけど、vQFX はどうなんだ?...お、EVPN もちゃんと動くやんけ!」ってところまでを見ていきます。
本項でやること
以下をやります。
- vQFX で VXLAN の Control Plane として EVPN を動かす
- 仮想版だと L2VPN 系機能が動かないアプライアンスもあるので
- EVPN の適用範囲は L2 シングル構成のみで、DataPlane としては VXLAN を使う
- L2VPN への L3 統合周り(inter-subnet-forwarding 周り)やマルチホーミングなどの機能は、今回の範囲外
- Dataplane としては VXLAN を使い、MPLS は取り扱わない
- Juniper公式 | ジュニパーネットワークス EVPN 次世代データセンター アーキテクチャの実装 で MX と QFX5100 でやっていることの一部を vQFX10000 で試す
- 各要素技術の詳細な解説は行わない
個人的には、2014/12 時点で VXLAN のマルチキャスト実装を確認した時 (VyOS と Arista で VXLAN 相互接続)に微妙だと思った点にも着目しておきたいです。今回、データプレーン周りはほぼ同じ構成を組んでますので。
- 上の記事の〆が「マルチキャストルーティングを勉強しよう。」だったのですが、この2年間以下のようにウダウダやっていて、特に進捗はありませんでした。
- 上の記事では VTEP 間の到達性をもたせるのに「VyOS が認識しないといけない Arista 側の VTEP IP アドレスは、Arista の Loopback アドレスになるので、StaticRoute を追加しておきます。#これだと拡張が面倒なので、実環境では DefaultRoute か動的ルーティングを使うことが多い気がします。」とか書いてますが、今回は実環境をある程度想定した例示ができそうです。
概要構成図 / 環境
以下のような構成を組んでいきます。node11 と node21 が L2overL3 で通信するやつです。
環境は、いずれも前回の通りです。
参考資料
前述の通り、各要素技術の詳細な解説は放棄していますが...こんなニッチな記事を読む人向けなので、まあね?
- EVPN 標準
- RFC7432 (BGP MPLS-Based Ethernet VPN)
- Alcatel-Lucent 発表資料 | ETHERNET VPN Standardization and Status
- 2015/11 時点のもの
- スライド9あたりが標準化動向の最新に近いかな...
- VXLAN 標準
- JUNOS での VXLAN+EVPN 実装・設定周り
- Juniper公式 | ジュニパーネットワークス EVPN 次世代データセンター アーキテクチャの実装
- MX と QFX5100 で EVPN の設定サンプルを step by step で解説
- 日本語版
- Juniper公式 | Junos OS for the QFX Series, Release 15.1X53 (for QFX10000 Switches) / EVPN Control Plane and VXLAN Data Plane Feature Guide for QFX Series Switches
- vQFX を動かす
15.1X53
での EVPN + VxLAN 全般
- vQFX を動かす
- Juniper公式 github | JNPRAutomate/ansible-junos-evpn-vxlan
- MX, QFX5100, QFX10000 の EVPN/VXLAN サンプルコンフィグを含む
- Juniper公式 | ジュニパーネットワークス EVPN 次世代データセンター アーキテクチャの実装
- O'Reilly Juniper QFX10000 Series
- Juniper QFX10000 の独自プロセッサ開発経緯や特徴・Architecture(HW/SW) の結構詳しい説明・MPLS/VXLAN+EVPNの設計ポイント解説など、非常に良い本
Juniper QFX10000 Series: A Comprehensive Guide to Building Next-Generation Data Centers
- 作者: Douglas Richard, Jr. Hanks
- 出版社/メーカー: O'Reilly Media
- 発売日: 2016/08/11
- メディア: ペーパーバック
- この商品を含むブログを見る
- Juniper QFX10000 の独自プロセッサ開発経緯や特徴・Architecture(HW/SW) の結構詳しい説明・MPLS/VXLAN+EVPNの設計ポイント解説など、非常に良い本
構築~動作確認
GNS3 で仮想マシンのデプロイ ~ 結線 ~ 起動
前回の通りに、3ペアの vQFX をデプロイして接続していきます。 以下の感じで。
torSW101a
と torSW201a
というのは、GNS3
の Ethernet Switch
を使っていますが、各環境に合わせて適当な dot1Q 食えるスイッチ置けば良いです。
設定はそれぞれ以下の感じです。(今回は Port 3-4
は使いませんが)
node11
と node21
は、インターフェースに IP アドレス付与するだけなので、適当な疎通確認用ノードなので好きなのをどうぞ。(node12
と node22
は今回使わないです)
あと captureSW
というのは GNS3 1.5.2
では github gns3-gui issues | QEMU link Packet Captures の通り、qemu 同士の結線をパケットキャプチャできないので、「bb01
でポートミラーリング」する手法をとっているために置いているものです。
未試行ですが、RE 同士の結線をしている箇所(bb01
と spine[12]1
)に全て Ethernet Switch
を挟めば、ポートミラーリング不要でパケットキャプチャできると思います。(そちらの方がやりやすい筈)
できたら起動して待ちます。
基本設定
各環境に合わせて syslog なり NTP なり ssh key 登録なりしておいて下さい。
あ、今回は BGP のログを /var/log/bgp.log
に残すために、以下をやっておくと良いですよ。
set protocols bgp traceoptions file bgp.log set protocols bgp traceoptions file size 10k set protocols bgp traceoptions file files 30 set protocols bgp traceoptions flag normal
Underlay 設定~確認 (物理IF と eBGP)
まずは物理 Interface と eBGP 周りを設定して、各 lo0
の IP アドレスを経路交換できたことを確認します。
まあ、長々となってしまいますが、絵にすると単純で以下のような感じです。
物理IF設定
bb01
set interfaces xe-0/0/0 description "DEV=spine11 IF=xe-0/0/0" set interfaces xe-0/0/0 unit 0 family inet address 192.0.2.1/30 delete interfaces xe-0/0/0 unit 0 family inet dhcp set interfaces xe-0/0/1 description "DEV=spine21 IF=xe-0/0/0" set interfaces xe-0/0/1 unit 0 family inet address 192.0.2.5/30 delete interfaces xe-0/0/1 unit 0 family inet dhcp set protocols lldp port-id-subtype interface-name set protocols lldp interface xe-0/0/0 set protocols lldp interface xe-0/0/1
spine11
set interfaces xe-0/0/0 description "DEV=bb01 IF=xe-0/0/0" set interfaces xe-0/0/0 unit 0 family inet address 192.0.2.2/30 delete interfaces xe-0/0/0 unit 0 family inet dhcp set protocols lldp port-id-subtype interface-name set protocols lldp interface xe-0/0/0
spine21
set interfaces xe-0/0/0 description "DEV=bb01 IF=xe-0/0/1" set interfaces xe-0/0/0 unit 0 family inet address 192.0.2.6/30 delete interfaces xe-0/0/0 unit 0 family inet dhcp set protocols lldp port-id-subtype interface-name set protocols lldp interface xe-0/0/0
物理IF疎通確認
リソースをケチったからか RTT
長すぎですね...。
bb01
kotetsu@bb01> show lldp neighbors Local Interface Parent Interface Chassis Id Port info System Name xe-0/0/0 - 02:05:86:71:84:00 DEV=bb01 IF=xe-0/0/0 spine11 xe-0/0/1 - 02:05:86:71:ff:00 DEV=bb01 IF=xe-0/0/1 spine21 kotetsu@bb01> show route inet.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 10.0.0.0/24 *[Direct/0] 19:47:39 > via em0.0 10.0.0.191/32 *[Local/0] 19:47:39 Local via em0.0 169.254.0.0/24 *[Direct/0] 19:57:21 > via em1.0 169.254.0.2/32 *[Local/0] 19:57:21 Local via em1.0 192.0.2.0/30 *[Direct/0] 00:17:12 > via xe-0/0/0.0 192.0.2.1/32 *[Local/0] 00:17:12 Local via xe-0/0/0.0 192.0.2.4/30 *[Direct/0] 00:07:04 > via xe-0/0/1.0 192.0.2.5/32 *[Local/0] 00:07:04 Local via xe-0/0/1.0 inet6.0: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both fe80::286:2b0f:fc44:ab00/128 *[Direct/0] 19:56:54 > via lo0.0 {master:0} kotetsu@bb01> ping 192.0.2.2 PING 192.0.2.2 (192.0.2.2): 56 data bytes 64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=2420.112 ms 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=1027.245 ms 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=1525.667 ms ^C --- 192.0.2.2 ping statistics --- 5 packets transmitted, 3 packets received, 40% packet loss round-trip min/avg/max/stddev = 1027.245/1657.675/2420.112/576.246 ms {master:0} kotetsu@bb01> ping 192.0.2.6 PING 192.0.2.6 (192.0.2.6): 56 data bytes 64 bytes from 192.0.2.6: icmp_seq=0 ttl=64 time=3378.582 ms 64 bytes from 192.0.2.6: icmp_seq=1 ttl=64 time=1374.159 ms 64 bytes from 192.0.2.6: icmp_seq=2 ttl=64 time=1474.743 ms ^C --- 192.0.2.6 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 1374.159/2075.828/3378.582/922.101 ms
spine11
{master:0} kotetsu@spine11> show lldp neighbors Local Interface Parent Interface Chassis Id Port info System Name xe-0/0/0 - 02:05:86:71:55:00 DEV=spine11 IF=xe-0/0/0 bb01 {master:0} kotetsu@spine11> show route inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 10.0.0.0/24 *[Direct/0] 19:23:06 > via em0.0 10.0.0.201/32 *[Local/0] 19:23:06 Local via em0.0 169.254.0.0/24 *[Direct/0] 19:22:26 > via em1.0 169.254.0.2/32 *[Local/0] 19:22:26 Local via em1.0 192.0.2.0/30 *[Direct/0] 00:16:05 > via xe-0/0/0.0 192.0.2.2/32 *[Local/0] 00:16:05 Local via xe-0/0/0.0 inet6.0: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both fe80::286:2b0f:fca1:f500/128 *[Direct/0] 19:22:25 > via lo0.0 {master:0} kotetsu@spine11> ping 192.0.2.1 PING 192.0.2.1 (192.0.2.1): 56 data bytes 64 bytes from 192.0.2.1: icmp_seq=0 ttl=64 time=2839.663 ms 64 bytes from 192.0.2.1: icmp_seq=1 ttl=64 time=2463.433 ms 64 bytes from 192.0.2.1: icmp_seq=2 ttl=64 time=2269.077 ms 64 bytes from 192.0.2.1: icmp_seq=3 ttl=64 time=1548.765 ms 64 bytes from 192.0.2.1: icmp_seq=4 ttl=64 time=844.779 ms 64 bytes from 192.0.2.1: icmp_seq=5 ttl=64 time=505.582 ms 64 bytes from 192.0.2.1: icmp_seq=6 ttl=64 time=852.323 ms 64 bytes from 192.0.2.1: icmp_seq=7 ttl=64 time=1724.594 ms ^C --- 192.0.2.1 ping statistics --- 9 packets transmitted, 8 packets received, 11% packet loss round-trip min/avg/max/stddev = 505.582/1631.027/2839.663/795.890 ms
spine21
{master:0} kotetsu@spine21> show lldp neighbors Local Interface Parent Interface Chassis Id Port info System Name xe-0/0/0 - 02:05:86:71:55:00 DEV=spine21 IF=xe-0/0/0 bb01 {master:0} kotetsu@spine21> show route inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 10.0.0.0/24 *[Direct/0] 08:41:29 > via em0.0 10.0.0.202/32 *[Local/0] 08:41:30 Local via em0.0 169.254.0.0/24 *[Direct/0] 08:46:47 > via em1.0 169.254.0.2/32 *[Local/0] 08:46:47 Local via em1.0 192.0.2.4/30 *[Direct/0] 00:03:53 > via xe-0/0/0.0 192.0.2.6/32 *[Local/0] 00:03:53 Local via xe-0/0/0.0 inet6.0: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both fe80::286:2b0f:fcd0:9b00/128 *[Direct/0] 08:46:47 > via lo0.0 {master:0} kotetsu@spine21> ping 192.0.2.5 PING 192.0.2.5 (192.0.2.5): 56 data bytes 64 bytes from 192.0.2.5: icmp_seq=0 ttl=64 time=427.225 ms 64 bytes from 192.0.2.5: icmp_seq=1 ttl=64 time=709.372 ms 64 bytes from 192.0.2.5: icmp_seq=2 ttl=64 time=1231.701 ms 64 bytes from 192.0.2.5: icmp_seq=3 ttl=64 time=732.131 ms ^C --- 192.0.2.5 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max/stddev = 427.225/775.107/1231.701/289.684 ms
lo0 + eBGP 設定
今回、いずれもシングル構成なのでマルチパス関係の設定は入れていませんよ。
bb01
set interfaces lo0 unit 0 family inet address 172.31.0.1/32 set policy-options policy-statement POLICY_EXPORT_LO0 from family inet set policy-options policy-statement POLICY_EXPORT_LO0 from protocol direct set policy-options policy-statement POLICY_EXPORT_LO0 from route-filter 0.0.0.0/0 prefix-length-range /32-/32 set policy-options policy-statement POLICY_EXPORT_LO0 then accept set routing-options router-id 172.31.0.1 set routing-options autonomous-system 65000 set protocols bgp group BGP_UNDERLAY type external set protocols bgp group BGP_UNDERLAY advertise-peer-as set protocols bgp group BGP_UNDERLAY family inet unicast loops 2 set protocols bgp group BGP_UNDERLAY export POLICY_EXPORT_LO0 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.2 description spine11 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.2 peer-as 65001 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.6 description spine21 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.6 peer-as 65002
spine11
set interfaces lo0 unit 0 family inet address 172.16.1.1/32 set policy-options policy-statement POLICY_EXPORT_LO0 from family inet set policy-options policy-statement POLICY_EXPORT_LO0 from protocol direct set policy-options policy-statement POLICY_EXPORT_LO0 from route-filter 0.0.0.0/0 prefix-length-range /32-/32 set policy-options policy-statement POLICY_EXPORT_LO0 then accept set routing-options router-id 172.16.1.1 set routing-options autonomous-system 65001 set protocols bgp group BGP_UNDERLAY type external set protocols bgp group BGP_UNDERLAY advertise-peer-as set protocols bgp group BGP_UNDERLAY family inet unicast loops 2 set protocols bgp group BGP_UNDERLAY export POLICY_EXPORT_LO0 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.1 description bb00 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.1 peer-as 65000
spine21
set interfaces lo0 unit 0 family inet address 172.16.2.1/32 set policy-options policy-statement POLICY_EXPORT_LO0 from family inet set policy-options policy-statement POLICY_EXPORT_LO0 from protocol direct set policy-options policy-statement POLICY_EXPORT_LO0 from route-filter 0.0.0.0/0 prefix-length-range /32-/32 set policy-options policy-statement POLICY_EXPORT_LO0 then accept set routing-options router-id 172.16.2.1 set routing-options autonomous-system 65002 set protocols bgp group BGP_UNDERLAY type external set protocols bgp group BGP_UNDERLAY advertise-peer-as set protocols bgp group BGP_UNDERLAY family inet unicast loops 2 set protocols bgp group BGP_UNDERLAY export POLICY_EXPORT_LO0 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.5 description bb00 set protocols bgp group BGP_UNDERLAY neighbor 192.0.2.5 peer-as 65000
eBGP確認
それぞれ lo0
の IPアドレスを相互学習したことを確認します。
この後やる Overlay 用の MP-BGP (iBGP) で bb01
が Route Reflector になるので、実際には bb01
と spine[12]1
で交換できていれば十分な筈ですが。
bb01
{master:0} kotetsu@bb01> show bgp summary Groups: 1 Peers: 2 Down peers: 1 Table Tot Paths Act Paths Suppressed History Damp State Pending inet.0 1 1 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 192.0.2.2 65001 4 4 0 0 20 1/1/1/0 0/0/0/0 192.0.2.6 65002 1 2 0 0 5:57 OpenConfirm {master:0} kotetsu@bb01> show bgp summary Groups: 1 Peers: 2 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending inet.0 2 2 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 192.0.2.2 65001 4 5 0 0 25 1/1/1/0 0/0/0/0 192.0.2.6 65002 4 4 0 0 4 1/1/1/0 0/0/0/0 {master:0} kotetsu@bb01> {master:0} kotetsu@bb01> show bgp summary Groups: 1 Peers: 2 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending inet.0 2 2 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 192.0.2.2 65001 4 5 0 0 26 1/1/1/0 0/0/0/0 192.0.2.6 65002 4 4 0 0 5 1/1/1/0 0/0/0/0 {master:0} kotetsu@bb01> show bgp group BGP_UNDERLAY brief Group Type: External Local AS: 65000 Name: BGP_UNDERLAY Index: 0 Flags: <Export Eval> Export: [ POLICY_EXPORT_LO0 ] Options: <AdvertisePeerAs> Holdtime: 0 Total peers: 2 Established: 2 192.0.2.2+56114 192.0.2.6+49934 inet.0: 2/2/2/0 {master:0} kotetsu@bb01> show bgp neighbor Peer: 192.0.2.2+56114 AS 65001 Local: 192.0.2.1+179 AS 65000 Description: spine11 Group: BGP_UNDERLAY Routing-Instance: master Forwarding routing-instance: master Type: External State: Established Flags: <Sync> Last State: OpenConfirm Last Event: RecvKeepAlive Last Error: None Export: [ POLICY_EXPORT_LO0 ] Options: <Preference AddressFamily PeerAS Refresh> Options: <AdvertisePeerAs PeerSpecficLoopsAllowed> Address families configured: inet-unicast Holdtime: 90 Preference: 170 Number of flaps: 0 Peer ID: 172.16.1.1 Local ID: 172.31.0.1 Active Holdtime: 90 Keepalive Interval: 30 Group index: 0 Peer index: 0 BFD: disabled, down Local Interface: xe-0/0/0.0 NLRI for restart configured on peer: inet-unicast NLRI advertised by peer: inet-unicast NLRI for this session: inet-unicast Peer supports Refresh capability (2) Stale routes from peer are kept for: 300 Peer does not support Restarter functionality Restart flag received from the peer: Notification NLRI that restart is negotiated for: inet-unicast NLRI of received end-of-rib markers: inet-unicast NLRI of all end-of-rib markers sent: inet-unicast Peer does not support LLGR Restarter functionality Peer supports 4 byte AS extension (peer-as 65001) Peer does not support Addpath Table inet.0 Bit: 10000 RIB State: BGP restart is complete Send state: in sync Active prefixes: 1 Received prefixes: 1 Accepted prefixes: 1 Suppressed due to damping: 0 Advertised prefixes: 2 Last traffic (seconds): Received 23 Sent 5 Checked 56 Input messages: Total 179 Updates 2 Refreshes 0 Octets 3478 Output messages: Total 186 Updates 2 Refreshes 0 Octets 3663 Output Queue[0]: 0 (inet.0, inet-unicast) Peer: 192.0.2.6+49934 AS 65002 Local: 192.0.2.5+179 AS 65000 Description: spine21 Group: BGP_UNDERLAY Routing-Instance: master Forwarding routing-instance: master Type: External State: Established Flags: <Sync> Last State: OpenConfirm Last Event: RecvKeepAlive Last Error: None Export: [ POLICY_EXPORT_LO0 ] Options: <Preference AddressFamily PeerAS Refresh> Options: <AdvertisePeerAs PeerSpecficLoopsAllowed> Address families configured: inet-unicast Holdtime: 90 Preference: 170 Number of flaps: 0 Peer ID: 172.16.2.1 Local ID: 172.31.0.1 Active Holdtime: 90 Keepalive Interval: 30 Group index: 0 Peer index: 1 BFD: disabled, down Local Interface: xe-0/0/1.0 NLRI for restart configured on peer: inet-unicast NLRI advertised by peer: inet-unicast NLRI for this session: inet-unicast Peer supports Refresh capability (2) Stale routes from peer are kept for: 300 Peer does not support Restarter functionality Restart flag received from the peer: Notification NLRI that restart is negotiated for: inet-unicast NLRI of received end-of-rib markers: inet-unicast NLRI of all end-of-rib markers sent: inet-unicast Peer does not support LLGR Restarter functionality Peer supports 4 byte AS extension (peer-as 65002) Peer does not support Addpath Table inet.0 Bit: 10000 RIB State: BGP restart is complete Send state: in sync Active prefixes: 1 Received prefixes: 1 Accepted prefixes: 1 Suppressed due to damping: 0 Advertised prefixes: 2 Last traffic (seconds): Received 54 Sent 19 Checked 15 Input messages: Total 92 Updates 2 Refreshes 0 Octets 1825 Output messages: Total 184 Updates 2 Refreshes 0 Octets 3625 Output Queue[0]: 0 (inet.0, inet-unicast)
{master:0} kotetsu@bb01> show route protocol bgp inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.1.1/32 *[BGP/170] 00:02:11, localpref 100 AS path: 65001 I, validation-state: unverified > to 192.0.2.2 via xe-0/0/0.0 172.16.2.1/32 *[BGP/170] 00:01:49, localpref 100 AS path: 65002 I, validation-state: unverified > to 192.0.2.6 via xe-0/0/1.0 inet6.0: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden) {master:0} kotetsu@bb01> ping 172.16.2.1 PING 172.16.2.1 (172.16.2.1): 56 data bytes 64 bytes from 172.16.2.1: icmp_seq=0 ttl=64 time=908.929 ms 64 bytes from 172.16.2.1: icmp_seq=1 ttl=64 time=1249.259 ms ^C --- 172.16.2.1 ping statistics --- 3 packets transmitted, 2 packets received, 33% packet loss round-trip min/avg/max/stddev = 908.929/1079.094/1249.259/170.165 ms {master:0} kotetsu@bb01> ping 172.16.1.1 PING 172.16.1.1 (172.16.1.1): 56 data bytes 64 bytes from 172.16.1.1: icmp_seq=0 ttl=64 time=2595.413 ms 64 bytes from 172.16.1.1: icmp_seq=1 ttl=64 time=1406.501 ms ^C --- 172.16.1.1 ping statistics --- 3 packets transmitted, 2 packets received, 33% packet loss round-trip min/avg/max/stddev = 1406.501/2000.957/2595.413/594.456 ms
spine11
{master:0} kotetsu@spine11> show bgp summary Groups: 1 Peers: 1 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending inet.0 2 2 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 192.0.2.1 65000 174 169 0 0 1:16:34 2/2/2/0 0/0/0/0 {master:0} kotetsu@spine11> show bgp group BGP_UNDERLAY brief Group Type: External Local AS: 65001 Name: BGP_UNDERLAY Index: 0 Flags: <Export Eval> Export: [ POLICY_EXPORT_LO0 ] Options: <AdvertisePeerAs> Holdtime: 0 Total peers: 1 Established: 1 192.0.2.1+179 inet.0: 2/2/2/0 {master:0} kotetsu@spine11> show bgp neighbor Peer: 192.0.2.1+179 AS 65000 Local: 192.0.2.2+56114 AS 65001 Description: bb00 Group: BGP_UNDERLAY Routing-Instance: master Forwarding routing-instance: master Type: External State: Established Flags: <Sync> Last State: OpenConfirm Last Event: RecvKeepAlive Last Error: None Export: [ POLICY_EXPORT_LO0 ] Options: <Preference AddressFamily PeerAS Refresh> Options: <AdvertisePeerAs PeerSpecficLoopsAllowed> Address families configured: inet-unicast Holdtime: 90 Preference: 170 Number of flaps: 0 Peer ID: 172.31.0.1 Local ID: 172.16.1.1 Active Holdtime: 90 Keepalive Interval: 30 Group index: 0 Peer index: 0 BFD: disabled, down Local Interface: xe-0/0/0.0 NLRI for restart configured on peer: inet-unicast NLRI advertised by peer: inet-unicast NLRI for this session: inet-unicast Peer supports Refresh capability (2) Stale routes from peer are kept for: 300 Peer does not support Restarter functionality Restart flag received from the peer: Notification NLRI that restart is negotiated for: inet-unicast NLRI of received end-of-rib markers: inet-unicast NLRI of all end-of-rib markers sent: inet-unicast Peer does not support LLGR Restarter functionality Peer supports 4 byte AS extension (peer-as 65000) Peer does not support Addpath Table inet.0 Bit: 10000 RIB State: BGP restart is complete Send state: in sync Active prefixes: 2 Received prefixes: 2 Accepted prefixes: 2 Suppressed due to damping: 0 Advertised prefixes: 1 Last traffic (seconds): Received 9 Sent 7 Checked 50 Input messages: Total 182 Updates 3 Refreshes 0 Octets 3524 Output messages: Total 177 Updates 1 Refreshes 0 Octets 3459 Output Queue[0]: 0 (inet.0, inet-unicast)
{master:0} kotetsu@spine11> show route protocol bgp inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.2.1/32 *[BGP/170] 01:22:49, localpref 100 AS path: 65000 65002 I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 172.31.0.1/32 *[BGP/170] 01:23:10, localpref 100 AS path: 65000 I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 inet6.0: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden) {master:0} kotetsu@spine11> ping 172.31.0.1 PING 172.31.0.1 (172.31.0.1): 56 data bytes 64 bytes from 172.31.0.1: icmp_seq=0 ttl=64 time=1597.291 ms 64 bytes from 172.31.0.1: icmp_seq=1 ttl=64 time=1215.306 ms ^C --- 172.31.0.1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 1215.306/1406.299/1597.291/190.993 ms
spine21
{master:0} kotetsu@spine21> show bgp summary Groups: 1 Peers: 1 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending inet.0 2 2 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 192.0.2.5 65000 173 88 0 0 38:05 2/2/2/0 0/0/0/0 {master:0} kotetsu@spine21> show bgp group BGP_UNDERLAY brief Group Type: External Local AS: 65002 Name: BGP_UNDERLAY Index: 0 Flags: <Export Eval> Export: [ POLICY_EXPORT_LO0 ] Options: <AdvertisePeerAs> Holdtime: 0 Total peers: 1 Established: 1 192.0.2.5+179 inet.0: 2/2/2/0 kotetsu@spine21> show bgp neighbor Peer: 192.0.2.5+179 AS 65000 Local: 192.0.2.6+49934 AS 65002 Description: bb00 Group: BGP_UNDERLAY Routing-Instance: master Forwarding routing-instance: master Type: External State: Established Flags: <Sync> Last State: OpenConfirm Last Event: RecvKeepAlive Last Error: None Export: [ POLICY_EXPORT_LO0 ] Options: <Preference AddressFamily PeerAS Refresh> Options: <AdvertisePeerAs PeerSpecficLoopsAllowed> Address families configured: inet-unicast Holdtime: 90 Preference: 170 Number of flaps: 0 Peer ID: 172.31.0.1 Local ID: 172.16.2.1 Active Holdtime: 90 Keepalive Interval: 30 Group index: 0 Peer index: 0 BFD: disabled, down Local Interface: xe-0/0/0.0 NLRI for restart configured on peer: inet-unicast NLRI advertised by peer: inet-unicast NLRI for this session: inet-unicast Peer supports Refresh capability (2) Stale routes from peer are kept for: 300 Peer does not support Restarter functionality Restart flag received from the peer: Notification NLRI that restart is negotiated for: inet-unicast NLRI of received end-of-rib markers: inet-unicast NLRI of all end-of-rib markers sent: inet-unicast Peer does not support LLGR Restarter functionality Peer supports 4 byte AS extension (peer-as 65000) Peer does not support Addpath Table inet.0 Bit: 10000 RIB State: BGP restart is complete Send state: in sync Active prefixes: 2 Received prefixes: 2 Accepted prefixes: 2 Suppressed due to damping: 0 Advertised prefixes: 1 Last traffic (seconds): Received 1 Sent 24 Checked 3 Input messages: Total 175 Updates 3 Refreshes 0 Octets 3391 Output messages: Total 88 Updates 1 Refreshes 0 Octets 1768 Output Queue[0]: 0 (inet.0, inet-unicast)
{master:0} kotetsu@spine21> show route protocol bgp inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.1.1/32 *[BGP/170] 00:41:43, localpref 100 AS path: 65000 65001 I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 172.31.0.1/32 *[BGP/170] 00:41:43, localpref 100 AS path: 65000 I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 inet6.0: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden) {master:0} kotetsu@spine21> ping 172.31.0.1 PING 172.31.0.1 (172.31.0.1): 56 data bytes 64 bytes from 172.31.0.1: icmp_seq=0 ttl=64 time=691.327 ms 64 bytes from 172.31.0.1: icmp_seq=1 ttl=64 time=1227.117 ms 64 bytes from 172.31.0.1: icmp_seq=2 ttl=64 time=238.494 ms ^C --- 172.31.0.1 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 238.494/718.979/1227.117/404.077 ms
Overlay 設定~確認 (MP-BGP)
Underlay eBGP で経路交換した各 lo0
同士で iBGP を組みます。
まあ、長々となってしまいますが、絵にすると単純で以下のような感じです。
iBGP (MP-BGP )設定
ポイントは1つだけで family evpn signaling
を設定して EVPN の NLRI を扱うってとこですかね。
bb01
set protocols bgp group BGP_OVERLAY type internal set protocols bgp group BGP_OVERLAY local-address 172.31.0.1 set protocols bgp group BGP_OVERLAY family evpn signaling set protocols bgp group BGP_OVERLAY cluster 172.31.0.1 set protocols bgp group BGP_OVERLAY local-as 64512 set protocols bgp group BGP_OVERLAY neighbor 172.16.1.1 description spine11 set protocols bgp group BGP_OVERLAY neighbor 172.16.2.1 description spine21
spine11
set protocols bgp group BGP_OVERLAY type internal set protocols bgp group BGP_OVERLAY local-address 172.16.1.1 set protocols bgp group BGP_OVERLAY family evpn signaling set protocols bgp group BGP_OVERLAY local-as 64512 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.1 description bb01
spine21
set protocols bgp group BGP_OVERLAY type internal set protocols bgp group BGP_OVERLAY local-address 172.16.2.1 set protocols bgp group BGP_OVERLAY family evpn signaling set protocols bgp group BGP_OVERLAY local-as 64512 set protocols bgp group BGP_OVERLAY neighbor 172.31.0.1 description bb01
iBGP (MP-BGP) 確認
最初 neighbor IP アドレス設定をタイポしたせいで、Last Error: Open Message Error
とか残っているのはご愛敬ということでひとつ...。
bb01
{master:0} kotetsu@bb01> show bgp summary Groups: 2 Peers: 4 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending inet.0 2 2 0 0 0 0 bgp.evpn.0 0 0 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 172.16.1.1 64512 3 3 0 0 25 Establ bgp.evpn.0: 0/0/0/0 172.16.2.1 64512 3 2 0 0 12 Establ bgp.evpn.0: 0/0/0/0 192.0.2.2 65001 502 518 0 0 3:58:25 1/1/1/0 0/0/0/0 192.0.2.6 65002 257 517 0 0 3:58:04 1/1/1/0 0/0/0/0 {master:0} kotetsu@bb01> show bgp group BGP_OVERLAY Group Type: Internal AS: 64512 Local AS: 64512 Name: BGP_OVERLAY Index: 1 Flags: <Export Eval> Options: <Cluster LocalAS> Holdtime: 0 Local AS: 64512 Local System AS: 65000 Total peers: 2 Established: 2 172.16.1.1+52050 172.16.2.1+62794 Trace options: normal Trace file: /var/log/bgp.log size 10240 files 30 bgp.evpn.0: 0/0/0/0 {master:0} kotetsu@bb01> show bgp neighbor Peer: 172.16.1.1+52050 AS 64512 Local: 172.31.0.1+179 AS 64512 Description: spine11 Group: BGP_OVERLAY Routing-Instance: master Forwarding routing-instance: master Type: Internal State: Established (route reflector client)Flags: <Sync> Last State: OpenConfirm Last Event: RecvKeepAlive Last Error: Open Message Error Options: <Preference LocalAddress Cluster AddressFamily LocalAS Rib-group Refresh> Address families configured: evpn Local Address: 172.31.0.1 Holdtime: 90 Preference: 170 Local AS: 64512 Local System AS: 65000 Number of flaps: 0 Error: 'Open Message Error' Sent: 20 Recv: 0 Peer ID: 172.16.1.1 Local ID: 172.31.0.1 Active Holdtime: 90 Keepalive Interval: 30 Group index: 1 Peer index: 0 BFD: disabled, down NLRI for restart configured on peer: evpn NLRI advertised by peer: evpn NLRI for this session: evpn Peer supports Refresh capability (2) Stale routes from peer are kept for: 300 Peer does not support Restarter functionality Restart flag received from the peer: Notification NLRI that restart is negotiated for: evpn NLRI of received end-of-rib markers: evpn NLRI of all end-of-rib markers sent: evpn Peer does not support LLGR Restarter functionality Peer supports 4 byte AS extension (peer-as 64512) Peer does not support Addpath Table bgp.evpn.0 Bit: 20000 RIB State: BGP restart is complete RIB State: VPN restart is complete Send state: in sync Active prefixes: 0 Received prefixes: 0 Accepted prefixes: 0 Suppressed due to damping: 0 Advertised prefixes: 0 Last traffic (seconds): Received 1 Sent 9 Checked 0 Input messages: Total 6 Updates 1 Refreshes 0 Octets 169 Output messages: Total 6 Updates 0 Refreshes 0 Octets 188 Output Queue[1]: 0 (bgp.evpn.0, evpn) Trace options: normal Trace file: /var/log/bgp.log size 10240 files 30 Peer: 172.16.2.1+62794 AS 64512 Local: 172.31.0.1+179 AS 64512 Description: spine21 Group: BGP_OVERLAY Routing-Instance: master Forwarding routing-instance: master Type: Internal State: Established (route reflector client)Flags: <Sync> Last State: OpenConfirm Last Event: RecvKeepAlive Last Error: Open Message Error Options: <Preference LocalAddress Cluster AddressFamily LocalAS Rib-group Refresh> Address families configured: evpn Local Address: 172.31.0.1 Holdtime: 90 Preference: 170 Local AS: 64512 Local System AS: 65000 Number of flaps: 0 Error: 'Open Message Error' Sent: 20 Recv: 0 Peer ID: 172.16.2.1 Local ID: 172.31.0.1 Active Holdtime: 90 Keepalive Interval: 30 Group index: 1 Peer index: 1 BFD: disabled, down NLRI for restart configured on peer: evpn NLRI advertised by peer: evpn NLRI for this session: evpn Peer supports Refresh capability (2) Stale routes from peer are kept for: 300 Peer does not support Restarter functionality Restart flag received from the peer: Notification NLRI that restart is negotiated for: evpn NLRI of received end-of-rib markers: evpn NLRI of all end-of-rib markers sent: evpn Peer does not support LLGR Restarter functionality Peer supports 4 byte AS extension (peer-as 64512) Peer does not support Addpath Table bgp.evpn.0 Bit: 20000 RIB State: BGP restart is complete RIB State: VPN restart is complete Send state: in sync Active prefixes: 0 Received prefixes: 0 Accepted prefixes: 0 Suppressed due to damping: 0 Advertised prefixes: 0 Last traffic (seconds): Received 46 Sent 0 Checked 9 Input messages: Total 10 Updates 1 Refreshes 0 Octets 245 Output messages: Total 18 Updates 0 Refreshes 0 Octets 416 Output Queue[1]: 0 (bgp.evpn.0, evpn) Trace options: normal Trace file: /var/log/bgp.log size 10240 files 30 ...
spine11
{master:0} kotetsu@spine11> show bgp summary Groups: 2 Peers: 2 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending inet.0 2 2 0 0 0 0 bgp.evpn.0 0 0 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 172.31.0.1 64512 21 22 0 0 9:07 Establ bgp.evpn.0: 0/0/0/0 192.0.2.1 65000 536 521 0 0 3:59:55 2/2/2/0 0/0/0/ {master:0} kotetsu@spine11> show bgp group BGP_OVERLAY Group Type: Internal AS: 64512 Local AS: 64512 Name: BGP_OVERLAY Index: 1 Flags: <Export Eval> Options: <LocalAS> Holdtime: 0 Local AS: 64512 Local System AS: 65001 Total peers: 1 Established: 1 172.31.0.1+179 Trace options: normal Trace file: /var/log/bgp.log size 10240 files 30 bgp.evpn.0: 0/0/0/0 {master:0} kotetsu@spine11> show bgp neighbor Peer: 172.31.0.1+179 AS 64512 Local: 172.16.1.1+52050 AS 64512 Description: bb01 Group: BGP_OVERLAY Routing-Instance: master Forwarding routing-instance: master Type: Internal State: Established Flags: <Sync> Last State: OpenConfirm Last Event: RecvKeepAlive Last Error: None Options: <Preference LocalAddress AddressFamily LocalAS Rib-group Refresh> Address families configured: evpn Local Address: 172.16.1.1 Holdtime: 90 Preference: 170 Local AS: 64512 Local System AS: 65001 Number of flaps: 0 Peer ID: 172.31.0.1 Local ID: 172.16.1.1 Active Holdtime: 90 Keepalive Interval: 30 Group index: 1 Peer index: 1 BFD: disabled, down NLRI for restart configured on peer: evpn NLRI advertised by peer: evpn NLRI for this session: evpn Peer supports Refresh capability (2) Stale routes from peer are kept for: 300 Peer does not support Restarter functionality Restart flag received from the peer: Notification NLRI that restart is negotiated for: evpn NLRI of received end-of-rib markers: evpn NLRI of all end-of-rib markers sent: evpn Peer does not support LLGR Restarter functionality Peer supports 4 byte AS extension (peer-as 64512) Peer does not support Addpath Table bgp.evpn.0 RIB State: BGP restart is complete RIB State: VPN restart is complete Send state: not advertising Active prefixes: 0 Received prefixes: 0 Accepted prefixes: 0 Suppressed due to damping: 0 Last traffic (seconds): Received 1 Sent 8 Checked 46 Input messages: Total 34 Updates 1 Refreshes 0 Octets 657 Output messages: Total 34 Updates 0 Refreshes 0 Octets 720 Trace options: normal Trace file: /var/log/bgp.log size 10240 files 30 ...
spine21
{master:0} kotetsu@spine21> show bgp summary Groups: 2 Peers: 2 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending inet.0 2 2 0 0 0 0 bgp.evpn.0 0 0 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 172.31.0.1 64512 34 19 0 0 7:30 Establ bgp.evpn.0: 0/0/0/0 192.0.2.5 65000 549 273 0 0 2:02:08 2/2/2/0 0/0/0/0 {master:0} kotetsu@spine21> show bgp group BGP_OVERLAY Group Type: Internal AS: 64512 Local AS: 64512 Name: BGP_OVERLAY Index: 1 Flags: <Export Eval> Options: <LocalAS> Holdtime: 0 Local AS: 64512 Local System AS: 65002 Total peers: 1 Established: 1 172.31.0.1+179 Trace options: normal Trace file: /var/log/bgp.log size 10240 files 30 bgp.evpn.0: 0/0/0/0 {master:0} kotetsu@spine21> show bgp neighbor Peer: 172.31.0.1+179 AS 64512 Local: 172.16.2.1+62794 AS 64512 Description: bb01 Group: BGP_OVERLAY Routing-Instance: master Forwarding routing-instance: master Type: Internal State: Established Flags: <Sync> Last State: OpenConfirm Last Event: RecvKeepAlive Last Error: None Options: <Preference LocalAddress AddressFamily LocalAS Rib-group Refresh> Address families configured: evpn Local Address: 172.16.2.1 Holdtime: 90 Preference: 170 Local AS: 64512 Local System AS: 65002 Number of flaps: 0 Peer ID: 172.31.0.1 Local ID: 172.16.2.1 Active Holdtime: 90 Keepalive Interval: 30 Group index: 1 Peer index: 1 BFD: disabled, down NLRI for restart configured on peer: evpn NLRI advertised by peer: evpn NLRI for this session: evpn Peer supports Refresh capability (2) Stale routes from peer are kept for: 300 Peer does not support Restarter functionality Restart flag received from the peer: Notification NLRI that restart is negotiated for: evpn NLRI of received end-of-rib markers: evpn NLRI of all end-of-rib markers sent: evpn Peer does not support LLGR Restarter functionality Peer supports 4 byte AS extension (peer-as 64512) Peer does not support Addpath Table bgp.evpn.0 RIB State: BGP restart is complete RIB State: VPN restart is complete Send state: not advertising Active prefixes: 0 Received prefixes: 0 Accepted prefixes: 0 Suppressed due to damping: 0 Last traffic (seconds): Received 14 Sent 17 Checked 58 Input messages: Total 36 Updates 1 Refreshes 0 Octets 695 Output messages: Total 20 Updates 0 Refreshes 0 Octets 454 Trace options: normal Trace file: /var/log/bgp.log size 10240 files 30 ...
Overlay設定~確認(EVPN+VXLAN)
EVPN の設定と、その Dataplane として使う VXLAN 周りの設定をしていきます。(息切れ)
EVPN+VXLAN 設定
冒頭の全体構成に書いたのですが bb01
はこの辺の挙動に関しては土管に徹しているので登場しません。
VNI は 1..16777214
まで使えるので、単純に全 spine で VLAN ID と 1:1 で同じ対応付けをさせて、一律で VLAN ID + 10000
の値を振ってます。
あ、VNI 10100 以外は本項ではまだ使いません。
spine11
set vlans VLAN0100 vlan-id 100 set vlans VLAN0100 vxlan vni 10100 set vlans VLAN0100 vxlan ingress-node-replication set vlans VLAN0300 vlan-id 300 set vlans VLAN0300 vxlan vni 10300 set vlans VLAN0300 vxlan ingress-node-replication set protocols evpn encapsulation vxlan set protocols evpn extended-vni-list all set protocols evpn multicast-mode ingress-replication set protocols evpn vni-options vni 10100 vrf-target export target:1:10100 set protocols evpn vni-options vni 10300 vrf-target export target:1:10300 set policy-options community COM_10100 members target:1:10100 set policy-options community COM_10300 members target:1:10300 set policy-options community COM_LEAF_ESI members target:9999:9999 set policy-options policy-statement POLICY_VRF_IMPORT term T_10100 from community COM_10100 set policy-options policy-statement POLICY_VRF_IMPORT term T_10100 then accept set policy-options policy-statement POLICY_VRF_IMPORT term T_10300 from community COM_10300 set policy-options policy-statement POLICY_VRF_IMPORT term T_10300 then accept set policy-options policy-statement POLICY_VRF_IMPORT term T_99900 from community COM_LEAF_ESI set policy-options policy-statement POLICY_VRF_IMPORT term T_99900 then accept set policy-options policy-statement POLICY_VRF_IMPORT term T_99999 then reject set switch-options vtep-source-interface lo0.0 set switch-options route-distinguisher 64512:11 set switch-options vrf-import POLICY_VRF_IMPORT set switch-options vrf-target target:9999:9999 set switch-options vrf-target auto set interfaces xe-0/0/1 description "DEV=torSW11 IF=1" set interfaces xe-0/0/1 unit 0 family ethernet-switching interface-mode trunk set interfaces xe-0/0/1 unit 0 family ethernet-switching vlan members all
spine21
set vlans VLAN0100 vlan-id 100 set vlans VLAN0100 vxlan vni 10100 set vlans VLAN0100 vxlan ingress-node-replication set vlans VLAN0200 vlan-id 200 set vlans VLAN0200 vxlan vni 10200 set vlans VLAN0200 vxlan ingress-node-replication set protocols evpn encapsulation vxlan set protocols evpn extended-vni-list all set protocols evpn multicast-mode ingress-replication set protocols evpn vni-options vni 10100 vrf-target export target:1:10100 set protocols evpn vni-options vni 10200 vrf-target export target:1:10200 set policy-options community COM_10100 members target:1:10100 set policy-options community COM_10200 members target:1:10200 set policy-options community COM_LEAF_ESI members target:9999:9999 set policy-options policy-statement POLICY_VRF_IMPORT term T_10100 from community COM_10100 set policy-options policy-statement POLICY_VRF_IMPORT term T_10100 then accept set policy-options policy-statement POLICY_VRF_IMPORT term T_10200 from community COM_10200 set policy-options policy-statement POLICY_VRF_IMPORT term T_10200 then accept set policy-options policy-statement POLICY_VRF_IMPORT term T_99900 from community COM_LEAF_ESI set policy-options policy-statement POLICY_VRF_IMPORT term T_99900 then accept set policy-options policy-statement POLICY_VRF_IMPORT term T_99999 then reject set switch-options vtep-source-interface lo0.0 set switch-options route-distinguisher 64512:21 set switch-options vrf-import POLICY_VRF_IMPORT set switch-options vrf-target target:9999:9999 set switch-options vrf-target auto set interfaces xe-0/0/1 description "DEV=torSW21 IF=1" set interfaces xe-0/0/1 unit 0 family ethernet-switching interface-mode trunk set interfaces xe-0/0/1 unit 0 family ethernet-switching vlan members all
動作確認
node 同士の疎通確認
- node11
$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:86:2b:8d:10:01 brd ff:ff:ff:ff:ff:ff inet 192.168.1.1/24 brd 192.168.1.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::286:2bff:fe8d:1001/64 scope link valid_lft forever preferred_lft forever $ ping 192.168.1.2 PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=975 ms 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=949 ms $ ip n show dev ens4 192.168.1.2 lladdr 00:86:2b:5c:0d:01 STALE
- node21
$ ip a show dev ens4 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:86:2b:5c:0d:01 brd ff:ff:ff:ff:ff:ff inet 192.168.1.2/24 brd 192.168.1.255 scope global ens4 valid_lft forever preferred_lft forever inet6 fe80::286:2bff:fe5c:d01/64 scope link valid_lft forever preferred_lft forever $ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=639 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=926 ms $ ip n show dev ens4 192.168.1.1 lladdr 00:86:2b:8d:10:01 STALE
vQFX のテーブル確認
前述の Juniper公式日本語資料 のページ 36 によると
bgp.evpn.0 = Junos OS ルーティング プロトコル プロセス(RPD)内のグローバル EVPN ルーティング テーブル default.switch.evpn.0(QFX5100 の場合) = Junos OS RPD 内のスイッチ レベル EVPN 転送テーブル \<virtual-switch-name>.evpn.0(MX の場合) = Junos OS RPD 内の仮想スイッチ レベル EVPN 転送テーブル
らしいですよ。
spine11
こいつにとっての vtep.32769
てのは spine21
(の VTEP)
{master:0} kotetsu@spine11> show ethernet-switching table MAC flags (S - static MAC, D - dynamic MAC, L - locally learned, P - Persistent static SE - statistics enabled, NM - non configured MAC, R - remote PE MAC, O - ovsdb MAC) Ethernet switching table : 2 entries, 2 learned Routing instance : default-switch Vlan MAC MAC Logical Active name address flags interface source VLAN0100 00:86:2b:5c:0d:01 D vtep.32769 172.16.2.1 VLAN0100 00:86:2b:8d:10:01 D xe-0/0/1.0 {master:0} kotetsu@spine11> show interfaces vtep.32769 Logical interface vtep.32769 (Index 566) (SNMP ifIndex 537) Flags: Up SNMP-Traps Encapsulation: ENET2 VXLAN Endpoint Type: Remote, VXLAN Endpoint Address: 172.16.2.1, L2 Routing Instance: default-switch, L3 Routing Instance: default Input packets : 4 Output packets: 4 Protocol eth-switch, MTU: Unlimited Flags: Trunk-Mode
EVPN の Type2(MAC/IP Advertisement route
) と Type3(Inclusive Multicast Ethernet Tag route
) を spine21
(RD 64512:21
)から学習して bgp.evpn.0
から default-switch.evpn.0
にロードされている様子
{master:0} kotetsu@spine11> show route ... :vxlan.inet.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 10.0.0.0/24 *[Direct/0] 00:23:24 > via em0.0 10.0.0.201/32 *[Local/0] 00:06:15 Local via em0.0 169.254.0.0/24 *[Direct/0] 00:23:24 > via em1.0 169.254.0.2/32 *[Local/0] 00:23:24 Local via em1.0 172.16.1.1/32 *[Direct/0] 00:23:24 > via lo0.0 172.16.2.1/32 *[Static/1] 00:13:22, metric2 0 > to 192.0.2.1 via xe-0/0/0.0 192.0.2.0/30 *[Direct/0] 00:23:24 > via xe-0/0/0.0 192.0.2.2/32 *[Local/0] 00:23:24 Local via xe-0/0/0.0 bgp.evpn.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 2:64512:21::10100::00:86:2b:5c:0d:01/304 *[BGP/170] 00:08:29, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 3:64512:21::10100::172.16.2.1/304 *[BGP/170] 00:13:23, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 default-switch.evpn.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 2:64512:11::10100::00:86:2b:8d:10:01/304 *[EVPN/170] 00:08:33 Indirect 2:64512:21::10100::00:86:2b:5c:0d:01/304 *[BGP/170] 00:08:29, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0 3:64512:11::10100::172.16.1.1/304 *[EVPN/170] 00:23:27 Indirect 3:64512:11::10300::172.16.1.1/304 *[EVPN/170] 00:15:11 Indirect 3:64512:21::10100::172.16.2.1/304 *[BGP/170] 00:13:23, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.1 via xe-0/0/0.0
{master:0} kotetsu@spine11> show route forwarding-table ... Routing table: :vxlan.inet Internet: Destination Type RtRef Next hop Type Index NhRef Netif default perm 0 rjct 1724 1 0.0.0.0/32 perm 0 dscd 1722 1 169.254.0.0/24 user 0 rtbl 1 5 169.254.0.2/32 user 0 169.254.0.2 locl 338 3 172.16.1.1/32 user 0 rtbl 1 5 172.16.2.1/32 user 0 indr 131070 3 192.0.2.1 ucst 1719 7 xe-0/0/0.0 192.0.2.0/30 user 0 rtbl 1 5 192.0.2.2/32 user 0 192.0.2.2 locl 1717 3 224.0.0.0/4 perm 0 mdsc 1723 1 224.0.0.1/32 perm 0 224.0.0.1 mcst 1726 1 255.255.255.255/32 perm 0 bcst 1727 1 ... Routing table: default-switch.bridge Bridging domain: VLAN0100.bridge VPLS: Destination Type RtRef Next hop Type Index NhRef Netif 00:86:2b:5c:0d:01/48 user 0 comp 1707 6 00:86:2b:8d:10:01/48 user 0 ucst 1712 6 xe-0/0/1.0 0x30001/51 user 0 comp 1739 2 0x30006/51 user 0 comp 1732 2 0x30002/51 user 0 comp 1733 2 Routing table: default-switch.bridge Bridging domain: VLAN0300.bridge VPLS: Destination Type RtRef Next hop Type Index NhRef Netif 0x30007/51 user 0 comp 1741 2 0x30005/51 user 0 comp 1714 2 0x30003/51 user 0 comp 1734 2 ...
spine21
こいつにとっての vtep.32769
てのは spine11
(の VTEP)
{master:0} kotetsu@spine21> show ethernet-switching table MAC flags (S - static MAC, D - dynamic MAC, L - locally learned, P - Persistent static SE - statistics enabled, NM - non configured MAC, R - remote PE MAC, O - ovsdb MAC) Ethernet switching table : 2 entries, 2 learned Routing instance : default-switch Vlan MAC MAC Logical Active name address flags interface source VLAN0100 00:86:2b:5c:0d:01 D xe-0/0/1.0 VLAN0100 00:86:2b:8d:10:01 D vtep.32769 172.16.1.1
EVPN の Type2(MAC/IP Advertisement route
) と Type3(Inclusive Multicast Ethernet Tag route
) を spine11
(RD 64512:11
)から学習して bgp.evpn.0
から default-switch.evpn.0
にロードされている様子
{master:0} kotetsu@spine21> show route ... :vxlan.inet.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 10.0.0.0/24 *[Direct/0] 00:18:41 > via em0.0 10.0.0.202/32 *[Local/0] 00:11:20 Local via em0.0 169.254.0.0/24 *[Direct/0] 00:18:41 > via em1.0 169.254.0.2/32 *[Local/0] 00:18:41 Local via em1.0 172.16.1.1/32 *[Static/1] 00:18:39, metric2 0 > to 192.0.2.5 via xe-0/0/0.0 172.16.2.1/32 *[Direct/0] 00:18:41 > via lo0.0 192.0.2.4/30 *[Direct/0] 00:18:41 > via xe-0/0/0.0 192.0.2.6/32 *[Local/0] 00:18:41 Local via xe-0/0/0.0 bgp.evpn.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 2:64512:11::10100::00:86:2b:8d:10:01/304 *[BGP/170] 00:12:17, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 3:64512:11::10100::172.16.1.1/304 *[BGP/170] 00:18:40, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 default-switch.evpn.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 2:64512:11::10100::00:86:2b:8d:10:01/304 *[BGP/170] 00:12:17, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 2:64512:21::10100::00:86:2b:5c:0d:01/304 *[EVPN/170] 00:12:16 Indirect 3:64512:11::10100::172.16.1.1/304 *[BGP/170] 00:18:40, localpref 100, from 172.31.0.1 AS path: I, validation-state: unverified > to 192.0.2.5 via xe-0/0/0.0 3:64512:21::10100::172.16.2.1/304 *[EVPN/170] 00:14:43 Indirect 3:64512:21::10200::172.16.2.1/304 *[EVPN/170] 00:14:43 Indirect
{master:0} kotetsu@spine21> show route forwarding-table ... Routing table: :vxlan.inet Internet: Destination Type RtRef Next hop Type Index NhRef Netif default perm 0 rjct 1716 1 0.0.0.0/32 perm 0 dscd 1714 1 169.254.0.0/24 user 0 rtbl 1 5 169.254.0.2/32 user 0 169.254.0.2 locl 334 3 172.16.1.1/32 user 0 indr 131070 3 192.0.2.5 ucst 1711 7 xe-0/0/0.0 172.16.2.1/32 user 0 rtbl 1 5 192.0.2.4/30 user 0 rtbl 1 5 192.0.2.6/32 user 0 192.0.2.6 locl 1709 3 224.0.0.0/4 perm 0 mdsc 1715 1 224.0.0.1/32 perm 0 224.0.0.1 mcst 1718 1 255.255.255.255/32 perm 0 bcst 1719 1 ... Routing table: default-switch.bridge Bridging domain: VLAN0100.bridge VPLS: Destination Type RtRef Next hop Type Index NhRef Netif 00:86:2b:5c:0d:01/48 user 0 ucst 1730 6 xe-0/0/1.0 00:86:2b:8d:10:01/48 user 0 comp 1723 6 0x30006/51 user 0 comp 1731 2 0x30004/51 user 0 comp 1725 2 0x30001/51 user 0 comp 1726 2 Routing table: default-switch.bridge Bridging domain: VLAN0200.bridge VPLS: Destination Type RtRef Next hop Type Index NhRef Netif 0x30007/51 user 0 comp 1734 2 0x30005/51 user 0 comp 1729 2 0x30002/51 user 0 comp 1728 2
bb01
{master:0} kotetsu@bb01> show ethernet-switching table
単純に EVPN 経路を reflect する土管なので bgp.evpn.0
にしか載っていない様子
{master:0} kotetsu@bb01> show route ... bgp.evpn.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 2:64512:11::10100::00:86:2b:8d:10:01/304 *[BGP/170] 00:31:03, localpref 100, from 172.16.1.1 AS path: I, validation-state: unverified > to 192.0.2.2 via xe-0/0/0.0 2:64512:21::10100::00:86:2b:5c:0d:01/304 *[BGP/170] 00:31:01, localpref 100, from 172.16.2.1 AS path: I, validation-state: unverified > to 192.0.2.6 via xe-0/0/1.0 3:64512:11::10100::172.16.1.1/304 *[BGP/170] 00:46:21, localpref 100, from 172.16.1.1 AS path: I, validation-state: unverified > to 192.0.2.2 via xe-0/0/0.0 3:64512:11::10300::172.16.1.1/304 *[BGP/170] 00:37:52, localpref 100, from 172.16.1.1 AS path: I, validation-state: unverified > to 192.0.2.2 via xe-0/0/0.0 3:64512:21::10100::172.16.2.1/304 *[BGP/170] 00:36:05, localpref 100, from 172.16.2.1 AS path: I, validation-state: unverified > to 192.0.2.6 via xe-0/0/1.0 3:64512:21::10200::172.16.2.1/304 *[BGP/170] 00:35:45, localpref 100, from 172.16.2.1 AS path: I, validation-state: unverified > to 192.0.2.6 via xe-0/0/1.0 {master:0} kotetsu@bb01> show route forwarding-table ...
パケットキャプチャ
いくつか特徴的なパケットを拾って眺めていきます。
前述の通り、今回は RE 同士を接続するところで直結構成にしてしまい bb01
が xe-0/0/2
から captureSW
方面にポートミラーリングして、GNS3 の bb01(RE)
と captureSW
間のリンクを右クリックして start capture
とかやっていきます。
なので bb01
に以下のような設定をして、xe-0/0/0
(spine11
側)の出入りを xe-0/0/2
にミラーリングしときます。
set interfaces xe-0/0/2 description "DEV=captureSW IF=1" set interfaces xe-0/0/2 unit 0 family ethernet-switching set forwarding-options analyzer ANAL_PORT input ingress interface xe-0/0/0.0 set forwarding-options analyzer ANAL_PORT input egress interface xe-0/0/0.0 set forwarding-options analyzer ANAL_PORT output interface xe-0/0/2.0
見返していて思ったんすが、アナルポートって...ちょっと...
あと、vQFX でも start shell
して tcpdump
とか使えますよ。Control Plane 宛のトラフィックだけとりたい時とかには。
DataPlane
bb01
で拾った VXLAN のパケットを見ていきます。
node11
から node21
に ping うった時、最初に出る ARP Request と ARP reply
VXLAN カプセルの IP ヘッダ的にはマルチキャストではなく、spine11 VTEP
と spine21 VTEP
間のユニキャストになってます。
node11
と node21
間の ICMP echo Request と ICMP echo Reply
これは EVPN 使おうが関係なく、ただの VXLAN ヘッダついたパケットです。
ControlPlane
bb01
で拾った EVPN のパケットを見ていきます。
EVPN NLRI Type2(MAC/IP Advertisement route) Update
まずは node11
からの ARP Request を受信した spine11
が advertise する様子
次に node21
からの ARP Reply を受信した spine21
が advertise したのを bb01
が spine11
方面に reflect する様子
EVPN NLRI Type2(MAC/IP Advertisement route) Withdrawn
spine11
で clear ethernet-switching table
して node11
の MAC を消す
EVPN NLRI Type3(Inclusive Multicast Ethernet Tag route) Withdrawn
spine21
で以下のような感じで、雑に VLAN 100 = VNI10100 at RD 64512:21 が消えたことを advertise させた時の様子
{master:0}[edit] kotetsu@spine21# deactivate vlans VLAN0100 {master:0}[edit] kotetsu@spine21# show | compare [edit vlans] ! inactive: VLAN0100 { ... } {master:0}[edit] kotetsu@spine21# commit
次に spine21
で VLAN 100 = VNI10100 at RD 64512:21 ができたことを advertise させた時の様子
{master:0}[edit] kotetsu@spine21# activate vlans VLAN0100 {master:0}[edit] kotetsu@spine21# show | compare [edit vlans] ! active: VLAN0100 { ... } {master:0}[edit] kotetsu@spine21# commit
おしまい
vQFX10000 を KVM+GNS3 で動かす (original : 2017/01/02)
この記事は某所で 2017/01/02
に書いた記事のコピーです。
そのため 2017/05/11
時点ではやや古い情報も含まれています。(以下一例)
- Juniper さんの
vQFX
ダウンロード規約が変わっていそう (詳細は未確認) - 201705 に
GNS3 ver2.0 stable
が出た
.
最初に
個人メール/名義で Juniper vQFX10000 trial 版 のダウンロード権限申請をしたら、ちょっとしたメールのやりとりの後に権限を頂けました。
Juniper さんへの感謝を込めて、幾つか記事を投稿しておきます。
本項でやること
- Juniper QFX10000 シリーズの仮想版であるところの Juniper vQFX10000 を KVM+GNS3 で動かして、簡単な L2 疎通確認をするところまで
- 公式サイトで案内されている Installation Guide (Juniper 公式 gitbuh | Juniper/vqfx10k-vagrant) では
vagrant
でのインストール手順のみが公開されている(2016/12/22現在)が、OSイメージとしては vmdk 版も配布されているし(&自分のメイン環境が KVM なので)、という都合 - KVM や GNS3 の導入手順、Junos 操作の基礎は省略 (ある程度知っている人向け)
Juniper vQFX?
- Juniper QFX10000 シリーズの仮想版(trial)
- 少なくとも 2016/07 時点では「github 上に Installation Guide はあがっているけれど、OSイメージは公開されていない」という状況だった
- 2016/12現在、いつのまにか Free Trial が始まっていたことに気付いた
- そして上記の Installation Guide が公式なものになっている
- 例によって、ダウンロードするためには権限申請が必要
- 今回も個人アカウントで申請したのですが Juniper の方とちょっとしたメールのやりとりで承認して頂けました。本当にありがとうございます。
環境情報
軽く
- KVM 母艦
Ubuntu16.04.1-server-amd64
- に
apt
で降ってくる KVM と GNS3 一式
- vQFX10000
- PFE も RE も
2016/12/22
時点で trial ダウンロード可能な最新版- PFE は
vqfx10k-pfe-20160609-2.vmdk
- RE は
vqfx10k-re-15.1X53-D60.vmdk
- PFE は
- PFE も RE も
$ uname -a Linux vkvm02 4.4.0-57-generic #78-Ubuntu SMP Fri Dec 9 23:50:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS" $ virsh -v 1.3.1 $ qemu-system-x86_64 --version QEMU emulator version 2.5.0 (Debian 1:2.5+dfsg-5ubuntu10.6), Copyright (c) 2003-2008 Fabrice Bellard $ gns3 --version 1.5.2
Install 手順
KVM 一式や GNS3 は以下あたりを参考に導入済みであること。(雑)
vQFX イメージファイル入手 ~ 配置 ~ format 変換
イメージファイル入手~KVM母艦に配置
- 前述の公式から飛べる vQFX Evaluation - Download Software へ
- 2016/12/22 現在ダウンロード可能な最新版一式(今回は
Format
がvmdk
の 2 ファイルのみで OK)をダウンロードVQFX10K PFE Disk Image
VQFX10K RE Disk Image
- KVM母艦に配置
$ md5sum vm_images/vqfx10k-pfe-20160609-2.vmdk faa6905fd8e935c6e97859191143e8c3 vm_images/vqfx10k-pfe-20160609-2.vmdk $ cat vm_images/vqfx10k-pfe-20160609-2_md5.txt faa6905fd8e935c6e97859191143e8c3 $ md5sum vm_images/vqfx10k-re-15.1X53-D60.vmdk 758669e88213fbd7943f5da7f6d7bd59 vm_images/vqfx10k-re-15.1X53-D60.vmdk $ cat vm_images/vqfx10k-re-15.1X53-D60_md5.txt 758669e88213fbd7943f5da7f6d7bd59
vmdk を qcow2 に format 変換
いつも通り
$ cd ~/vm_images/ $ mkdir qemu $ ls -al total 917640 drwxrwxr-x 3 kotetsu kotetsu 4096 Dec 25 11:32 . drwxr-xr-x 12 kotetsu kotetsu 4096 Dec 25 11:08 .. drwxrwxr-x 2 kotetsu kotetsu 4096 Dec 25 11:32 qemu -rw-r--r-- 1 kotetsu kotetsu 32 Dec 24 10:59 vqfx10k-pfe-20160609-2_md5.txt -rw-r--r-- 1 kotetsu kotetsu 584086528 Dec 24 10:42 vqfx10k-pfe-20160609-2.vmdk -rw-r--r-- 1 kotetsu kotetsu 32 Dec 24 11:00 vqfx10k-re-15.1X53-D60_md5.txt -rw-r--r-- 1 kotetsu kotetsu 355542528 Dec 24 10:50 vqfx10k-re-15.1X53-D60.vmdk $ qemu-img convert -f vmdk -O qcow2 vqfx10k-pfe-20160609-2.vmdk qemu/vqfx10k-pfe-20160609-2.qcow2 $ qemu-img convert -f vmdk -O qcow2 vqfx10k-re-15.1X53-D60.vmdk qemu/vqfx10k-re-15.1X53-D60.qcow2 $ ls -al qemu/ total 1585044 drwxrwxr-x 2 kotetsu kotetsu 4096 Dec 25 11:37 . drwxrwxr-x 3 kotetsu kotetsu 4096 Dec 25 11:32 .. -rw-r--r-- 1 kotetsu kotetsu 1144782848 Dec 25 11:37 vqfx10k-pfe-20160609-2.qcow2 -rw-r--r-- 1 kotetsu kotetsu 478412800 Dec 25 11:37 vqfx10k-re-15.1X53-D60.qcow2
GNS3 上でテンプレートイメージとして登録
ここは、各人が使っている KVM 管理ソフトウェアに読み替えて下さい。 CPU/Memory の要件は、前述の Installation Guide に書いてあります。
PFE
以下でとりあえず(自分の検証用途では問題なく)動いてます。
RE
以下でとりあえず(自分の検証用途では問題なく)動いてます。
ここの Adapters
数は、最低 2 個必要で 4 個目からが xe-0/0/0~
にマッピングされます。上限数はちゃんと確認していないものの、6 個しか割り当てなくても固定で xe-0/0/11
まで見えるし、12個の筈。
GNS3 でテンプレートからデプロイ ~ 結線 ~ 起動
登録したテンプレートから PFE と RE を 1 セットドラッグアンドドロップでデプロイします。 一応、ついでに適当な疎通確認用のノードも 2 個くらい作っておきました。
結線時、各仮想マシンの外から見える Adapters
のカウントと OS 内のインターフェース対応は以下の感じです。PFE の 2 個目と RE の 2 個目を接続しておけば、最低限 PFE を認識するところまでは動きます。
コンポーネント | 外から見えるインターフェース番号(GNS3 デフォルト名) | OSでの使われ方 | 備考 |
---|---|---|---|
PFE | 1 (Ethernet0) | eth0 | 初期設定で DHCP になっている管理インターフェースなので、必要に応じて外界と接続 |
PFE | 2 (Ethernet1) | eth1 (169.254.0.1/24) | RE との Dedicated Link |
RE | 1 (Ethernet0) | em0 | 初期設定で DHCP になっている管理インターフェースなので、必要に応じて外界と接続したり固定アドレスに変更したり |
RE | 2 (Ethernet1) | em1 (169.254.0.2/24) | PFE との Dedicated Link |
RE | 3 (Ethernet2) | 不明 | 使ったことないけどたぶん em2 かと |
RE | 4~ (Ethernet3~) | xe-0/0/0~ |
というわけで、例えば以下の感じで。
絵でいうところの SW1
~ Cloud
というやつは外界 (母艦KVM の linux bridge へ)に接続して、既存環境と相互通信(管理用)させています。その辺はまあ、環境に合わせて。
余談ですが、GNS3 1.5.2
では github gns3-gui issues | QEMU link Packet Captures の通り qemu 同士の結線ではパケットキャプチャできないので、複数デプロイして RE 同士を接続する場合には、間に GNS3 の Ethernet Switch
を挟んだり、vQFX 側で port mirroring したりとかの工夫をすることになるかと思います。(ということで GNS3 2.0 stable
以降を使おう!)
あとは RE と PFE を GNS3 から Start
してしばらく待ちます。
RE が起動してから結構待つと、PFE と勝手に繋がって PFE が見えるようになります。気長に待ちましょう。
~$ ps aux | grep [Q]FX root 4819 56.8 7.0 1907744 1165860 pts/10 Sl+ Dec25 63:24 /usr/bin/qemu-system-x86_64 -name vQFX_RE_15.1X53-D60-1 -m 1024M -smp cpus=1 -enable-kvm -boot order=c -drive file=/home/kotetsu/GNS3/projects/vqfx/project-files/qemu/f8b3330f-b59c-4035-970e-77368631a1f5/hda_disk.qcow2,if=ide,index=0,media=disk -serial telnet:127.0.0.1:5001,server,nowait -monitor tcp:127.0.0.1:55276,server,nowait -net none -device e1000,mac=00:86:2b:a1:f5:00,netdev=gns3-0 -netdev socket,id=gns3-0,udp=127.0.0.1:10011,localaddr=127.0.0.1:10010 -device e1000,mac=00:86:2b:a1:f5:01,netdev=gns3-1 -netdev socket,id=gns3-1,udp=127.0.0.1:10000,localaddr=127.0.0.1:10005 -device e1000,mac=00:86:2b:a1:f5:02 -device e1000,mac=00:86:2b:a1:f5:03 -device e1000,mac=00:86:2b:a1:f5:04,netdev=gns3-4 -netdev socket,id=gns3-4,udp=127.0.0.1:10004,localaddr=127.0.0.1:10003 -device e1000,mac=00:86:2b:a1:f5:05,netdev=gns3-5 -netdev socket,id=gns3-5,udp=127.0.0.1:10002,localaddr=127.0.0.1:10001 -nographic root 4826 99.3 9.3 2468864 1533164 pts/10 Sl+ Dec25 110:45 /usr/bin/qemu-system-x86_64 -name vQFX_PFE_20160609-1 -m 1536M -smp cpus=1 -enable-kvm -boot order=c -drive file=/home/kotetsu/GNS3/projects/vqfx/project-files/qemu/21773ec6-55f8-4c3f-9cfb-fedd5f0f38da/hda_disk.qcow2,if=ide,index=0,media=disk -serial telnet:127.0.0.1:5000,server,nowait -monitor tcp:127.0.0.1:44622,server,nowait -net none -device e1000,mac=00:86:2b:38:da:00 -device e1000,mac=00:86:2b:38:da:01,netdev=gns3-1 -netdev socket,id=gns3-1,udp=127.0.0.1:10005,localaddr=127.0.0.1:10000 -nographic
Junos 側の確認
RE 確認
Juniper 公式 gitbuh | Juniper/vqfx10k-vagrant にも書いてありますが、アカウント: root
パスワード: Juniper
でログインしたら、いつも通り cli
コマンドで JUNOS shell へ入ります。
基本情報を確認... QFX3500
とか書いてある...けど、本質ではないので無視。
{master:0} root@vqfx-re> show chassis hardware Hardware inventory: Item Version Part number Serial number Description Chassis 84425636318 QFX3500 {master:0} root@vqfx-re> show version fpc0: -------------------------------------------------------------------------- Hostname: vqfx-re Model: vqfx-10000 Junos: 15.1X53-D60.4 JUNOS Base OS boot [15.1X53-D60.4] JUNOS Base OS Software Suite [15.1X53-D60.4] JUNOS Crypto Software Suite [15.1X53-D60.4] JUNOS Online Documentation [15.1X53-D60.4] JUNOS Kernel Software Suite [15.1X53-D60.4] JUNOS Packet Forwarding Engine Support (qfx-10-f) [15.1X53-D60.4] JUNOS Routing Software Suite [15.1X53-D60.4] JUNOS Enterprise Software Suite [15.1X53-D60.4] JUNOS Web Management [15.1X53-D60.4] JUNOS py-base-i386 [15.1X53-D60.4] {master:0} root@vqfx-re> show system license License usage: none Licenses installed: none
root@vqfx-re:RE:0% uname -a JUNOS vqfx-re 15.1X53-D60.4 JUNOS 15.1X53-D60.4 #0: 2016-08-26 23:07:01 UTC builder@mayland.juniper.net:/volume/build/junos/15.1/service/15.1X53-D60.4/obj/i386/junos/bsd/kernels/JUNIPER-QFX/kernel i386 root@vqfx-re:RE:0% python --version Python 2.7.8
PFE とつながって、認識されたことを確認。
{master:0} root@vqfx-re> show pfe terse fpc0: -------------------------------------------------------------------------- Slot Type Slot State Uptime 0 FXPC Present Online 01:23:47 {master:0} root@vqfx-re> show chassis fpc Temp CPU Utilization (%) CPU Utilization (%) Memory Utilization (%) Slot State (C) Total Interrupt 1min 5min 15min DRAM (MB) Heap Buffer 0 Online Testing 17 12 0 0 0 1024 0 66 1 Empty 2 Empty 3 Empty 4 Empty 5 Empty 6 Empty 7 Empty 8 Empty 9 Empty {master:0} root@vqfx-re> show interfaces em1 Physical interface: em1 , Enabled, Physical link is Up Interface index: 9, SNMP ifIndex: 23 Type: Ethernet, Link-level type: Ethernet, MTU: 1514, Speed: 1000mbps Device flags : Present Running Interface flags: SNMP-Traps Link type : Full-Duplex Current address: 00:86:2b:a1:f5:01, Hardware address: 00:86:2b:a1:f5:01 Last flapped : 2016-12-25 13:21:12 UTC (01:25:04 ago) Input packets : 614505 Output packets: 957499 Logical interface em1.0 (Index 6) (SNMP ifIndex 24) Flags: Up SNMP-Traps 0x4000000 Encapsulation: ENET2 Input packets : 614547 Output packets: 957499 Protocol inet, MTU: 1500 Flags: Sendbcast-pkt-to-re Addresses, Flags: Is-Preferred Is-Primary Destination: 169.254.0/24, Local: 169.254.0.2, Broadcast: 169.254.0.255 {master:0} root@vqfx-re> show arp MAC Address Address Name Interface Flags 52:54:00:07:30:c0 10.0.0.65 10.0.0.65 em0.0 none 00:a0:de:c0:55:80 10.0.0.254 10.0.0.254 em0.0 none 00:86:2b:38:da:01 169.254.0.1 169.254.0.1 em1.0 none Total entries: 3
当該 RE 仮想マシンに割り当てた Adapters
は 6 個だけでしたが、固定で xe-0/0/0
~ xe-0/0/11
まで出来てますねえ...しかも何故か全て Link
が up
状態
{master:0} root@vqfx-re> show interfaces terse Interface Admin Link Proto Local Remote gr-0/0/0 up up pfe-0/0/0 up up pfe-0/0/0.16383 up up inet inet6 pfh-0/0/0 up up pfh-0/0/0.16383 up up inet pfh-0/0/0.16384 up up inet xe-0/0/0 up up xe-0/0/0.0 up up inet xe-0/0/1 up up xe-0/0/1.0 up up eth-switch xe-0/0/2 up up xe-0/0/2.0 up up eth-switch xe-0/0/3 up up xe-0/0/3.0 up up eth-switch xe-0/0/4 up up xe-0/0/4.0 up up eth-switch xe-0/0/5 up up xe-0/0/5.0 up up eth-switch xe-0/0/6 up up xe-0/0/6.0 up up inet xe-0/0/7 up up xe-0/0/7.0 up up inet xe-0/0/8 up up xe-0/0/8.0 up up inet xe-0/0/9 up up xe-0/0/9.0 up up inet xe-0/0/10 up up xe-0/0/10.0 up up inet xe-0/0/11 up up xe-0/0/11.0 up up inet bme0 up up bme0.0 up up inet 128.0.0.1/2 128.0.0.4/2 128.0.0.16/2 128.0.0.63/2 cbp0 up up dsc up up em0 up up em0.0 up up inet 10.0.0.201/24 em1 up up em1.0 up up inet 169.254.0.2/24 em2 up up em2.32768 up up inet 192.168.1.2/24 em3 up up em4 up up em5 up up esi up up gre up up ipip up up irb up up lo0 up up lo0.0 up up inet inet6 fe80::286:2b0f:fca1:f500 lo0.16385 up up inet lsi up up mtun up up pimd up up pime up up pip0 up up tap up up vme up down vtep up up
何も設定していない状況でのリソース状況とかを見ていく。
root@vqfx-re:RE:0% vmstat procs memory page disk faults cpu r b w avm fre flt re pi po fr sr ad0 in sy cs us sy id 2 0 0 4940056 289632 79 1 6 0 84 0 0 853 2822 1917 0 29 70 root@vqfx-re:RE:0% df -h Filesystem Size Used Avail Capacity Mounted on /dev/ad0s1a 2.4G 405M 1.8G 18% / devfs 1.0K 1.0K 0B 100% /dev /dev/md0 87M 87M 0B 100% /packages/mnt/jbase /dev/md1 527M 527M 0B 100% /packages/mnt/jkernel-qfx-x86-32-15.1X53-D60.4 /dev/md2 31M 31M 0B 100% /packages/mnt/jpfe-qfx-10-f-15.1X53-D60.4 /dev/md3 11M 11M 0B 100% /packages/mnt/jdocs-dc-re-15.1X53-D60.4 /dev/md4 215M 215M 0B 100% /packages/mnt/jroute-qfx-x86-32-15.1X53-D60.4 /dev/md5 32M 32M 0B 100% /packages/mnt/jcrypto-dc-re-15.1X53-D60.4 /dev/md6 53M 53M 0B 100% /packages/mnt/jswitch-qfx-x86-32-15.1X53-D60.4 /dev/md7 25M 25M 0B 100% /packages/mnt/jweb-qfx-15.1X53-D60.4 /var/jail/etc 2.4G 405M 1.8G 18% /packages/mnt/jweb-qfx-15.1X53-D60.4/jail/var/etc /var/jail/run 2.4G 405M 1.8G 18% /packages/mnt/jweb-qfx-15.1X53-D60.4/jail/var/run /var/jail/tmp 2.4G 405M 1.8G 18% /packages/mnt/jweb-qfx-15.1X53-D60.4/jail/var/tmp /var/tmp 2.4G 405M 1.8G 18% /packages/mnt/jweb-qfx-15.1X53-D60.4/jail/var/tmp/uploads devfs 1.0K 1.0K 0B 100% /packages/mnt/jweb-qfx-15.1X53-D60.4/jail/dev /var/jail/jweb-app 2.4G 405M 1.8G 18% /packages/mnt/jweb-qfx-15.1X53-D60.4/jail/var/jweb-app /dev/md8 12M 12M 0B 100% /packages/mnt/py-base-i386-15.1X53-D60.4 /dev/md9 1.0G 10K 926M 0% /tmp procfs 4.0K 4.0K 0B 100% /proc /dev/ad0s1e 604M 110K 555M 0% /config /var/jails/rest-api 2.4G 405M 1.8G 18% /packages/mnt/jroute-qfx-x86-32-15.1X53-D60.4/web-api/var
start shell
して top
last pid: 1882; load averages: 0.20, 0.30, 0.31 up 0+01:17:00 14:36:02 73 processes: 1 running, 71 sleeping, 1 zombie CPU states: 0.0% user, 0.0% nice, 4.5% system, 9.8% interrupt, 85.7% idle Mem: 564M Active, 51M Inact, 66M Wired, 89M Cache, 69M Buf, 203M Free Swap: 1024M Total, 1024M Free PID USERNAME THR PRI NICE SIZE RES STATE TIME WCPU COMMAND 1452 root 4 96 0 336M 231M select 7:28 3.76% olive-ultimat.elf
起動直後のところだけ dmesg
を抜粋。
root@vqfx-re:RE:0% dmesg | more Copyright (c) 1996-2016, Juniper Networks, Inc. All rights reserved. Copyright (c) 1992-2007 The FreeBSD Project. Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD is a registered trademark of The FreeBSD Foundation. JUNOS 15.1X53-D60.4 #0: 2016-08-26 23:07:01 UTC builder@mayland.juniper.net:/volume/build/junos/15.1/service/15.1X53-D60.4/obj/i386/junos/bsd/kernels/JUNIPER-QFX/kernel can't re-use a leaf (fe_storm_timeout)! can't re-use a leaf (alt_break_to_debugger)! can't re-use a leaf (break_to_debugger)! Timecounter "i8254" frequency 1193182 Hz quality 0 CPU: QEMU Virtual CPU version 2.5+ (3096.49-MHz 686-class CPU) Origin = "GenuineIntel" Id = 0x663 Stepping = 3 Features=0x783fbfd<FPU,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2> Features2=0x80202021<SSE3,VMX,CX16,x2APIC,<b31>> AMD Features=0x20100800<SYSCALL,NX,LM> AMD Features2=0x1<LAHF> real memory = 1073741824 (1024 MB) avail memory = 1017835520 (970 MB) MPTable: <BOCHSCPU 0.1 > Security policy loaded: Junos MAC/veriexec (mac_veriexec) MAC/veriexec fingerprint module loaded: SHA256 MAC/veriexec fingerprint module loaded: SHA1 ioapic0: Assuming intbase of 0 ioapic0 <Version 1.1> irqs 0-23 on motherboard ETHERNET SOCKET BRIDGE initialising fpga driver loaded, 0 (null) FXPCI warning: hw.pci.enable_static_config is not set. Initializing Kernel PVIDB. Initializing DCF X86 platform properties .. Calling dcf_ng_hw_init for platform hw vecs initialization ACPI-0314: *** Error: Invalid signature where RSDP indicates RSDT/XSDT should be located ACPI-0325: *** Error: Looking for RSDT (RSDP->Rev < 2) ACPI-0181: *** Error: AcpiLoadTables: Could not load RSDT: AE_BAD_SIGNATURE ACPI-0213: *** Error: AcpiLoadTables: Could not load tables: AE_BAD_SIGNATURE ACPI: table load failed: AE_BAD_SIGNATURE cpu0 on motherboard pcib0: <MPTable Host-PCI bridge> pcibus 0 on motherboard pci0: <PCI bus> on pcib0 Correcting Natoma config for non-SMP isab0: <PCI-ISA bridge> at device 1.0 on pci0 isa0: <ISA bus> on isab0 atapci0: <Intel PIIX3 WDMA2 controller> port 0x1f0-0x1f7,0x3f6,0x170-0x177,0x376,0xc180-0xc18f at device 1.1 on pci0 ata0: <ATA channel 0> on atapci0 ata1: <ATA channel 1> on atapci0 smb0: <Intel 82371AB SMB controller> irq 9 at device 1.3 on pci0 pci0: <display, VGA> at device 2.0 (no driver attached) pci0: <network, ethernet> at device 3.0 (no driver attached) pci0: <network, ethernet> at device 4.0 (no driver attached) pci0: <network, ethernet> at device 5.0 (no driver attached)
PFE 確認
Juniper 公式 gitbuh | Juniper/vqfx10k-vagrant にも書いてありますが、アカウント: root
パスワード: no
でログインできます。あまり入ることないですが。
root@localhost:~# uname -a Linux localhost 3.10.62-ltsi-WR6.0.0.21_standard #1 SMP PREEMPT Mon Nov 30 07:26:43 PST 2015 x86_64 x86_64 x86_64 GNU/Linux root@localhost:~# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:86:2b:38:da:00 brd ff:ff:ff:ff:ff:ff inet6 fe80::286:2bff:fe38:da00/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:86:2b:38:da:01 brd ff:ff:ff:ff:ff:ff inet 169.254.0.1/24 brd 169.254.0.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::286:2bff:fe38:da01/64 scope link valid_lft forever preferred_lft forever 4: sit0: <NOARP> mtu 1480 qdisc noop state DOWN link/sit 0.0.0.0 brd 0.0.0.0 root@localhost:~# ip route 169.254.0.0/24 dev eth1 proto kernel scope link src 169.254.0.1 root@localhost:~# cat /etc/network/interfaces # /etc/network/interfaces -- configuration file for ifup(8), ifdown(8) # The loopback interface auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp auto eth1 iface eth1 inet static address 169.254.0.1 netmask 255.255.255.0
デフォルト状態だとさほどメモリ持っていかれないようです。
root@localhost:~# vmstat procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 2 0 0 367600 11748 498320 0 0 37 37 1188 445 76 24 1 0 root@localhost:~# free total used free shared buffers cached Mem: 1533320 1165648 367672 0 11708 498332 -/+ buffers/cache: 655608 877712 Swap: 972 0 972 root@localhost:~# df -h Filesystem Size Used Avail Use% Mounted on rootfs 1.9G 837M 941M 48% / udev 732M 0 732M 0% /dev none 732M 0 732M 0% /dev tmpfs 749M 240K 749M 1% /run /dev/sda3 1.9G 837M 941M 48% / /dev/sda5 597M 52M 502M 10% /var tmpfs 749M 240K 749M 1% /run tmpfs 749M 0 749M 0% /var/volatile /dev/sda1 1.2G 210M 1004M 18% /boot /dev/sda2 103M 1.6M 94M 2% /app_disk tmpfs 749M 240K 749M 1% /run/named-chroot/var/run/named tmpfs 749M 240K 749M 1% /run/named-chroot/var/run/bind none 732M 0 732M 0% /run/named-chroot/dev/random none 732M 0 732M 0% /run/named-chroot/dev/zero none 732M 0 732M 0% /run/named-chroot/dev/null
簡易疎通確認
前の絵でノードを 2 個繋いでいるので、適当にその物理IFに access vlan 100 を割り当てて疎通確認しました。(雑)
{master:0} root@vqfx-re> show ethernet-switching interface Routing Instance Name : default-switch Logical Interface flags (DL - disable learning, AD - packet action drop, LH - MAC limit hit, DN - interface down, MMAS - Mac-move action shutdown, SCTL - shutdown by Storm-control ) Logical Vlan TAG MAC STP Logical Tagging interface members limit state interface flags xe-0/0/1.0 8192 untagged VLAN0100 100 1024 Forwarding untagged Routing Instance Name : default-switch Logical Interface flags (DL - disable learning, AD - packet action drop, LH - MAC limit hit, DN - interface down, MMAS - Mac-move action shutdown, SCTL - shutdown by Storm-control ) Logical Vlan TAG MAC STP Logical Tagging interface members limit state interface flags xe-0/0/2.0 8192 untagged VLAN0100 100 1024 Forwarding untagged {master:0} root@vqfx-re> show ethernet-switching table MAC flags (S - static MAC, D - dynamic MAC, L - locally learned, P - Persistent static, C - Control MAC SE - statistics enabled, NM - non configured MAC, R - remote PE MAC, O - ovsdb MAC) Ethernet switching table : 2 entries, 2 learned Routing instance : default-switch Vlan MAC MAC Age Logical NH RTR name address flags interface Index ID VLAN0100 00:86:2b:47:b6:01 D - xe-0/0/2.0 0 0 VLAN0100 00:86:2b:8d:10:01 D - xe-0/0/1.0 0 0
おしまい
- インストールしただけなので別に...
- Juniper さんありがとうございます!感謝を込めて、vQFX で試した内容を追っていくつか纏めておきます。
参考書籍
Juniper QFX10000 の独自プロセッサ開発経緯や特徴・Architecture(HW/SW) の結構詳しい説明・MPLS/VXLAN+EVPNの設計ポイントなど、非常に良い本なので、こんなニッチな記事を読んでいる人におススメ!
Juniper QFX10000 Series: A Comprehensive Guide to Building Next-Generation Data Centers
- 作者: Douglas Richard, Jr. Hanks
- 出版社/メーカー: O'Reilly Media
- 発売日: 2016/08/11
- メディア: ペーパーバック
- この商品を含むブログを見る
- 作者: Douglas Richard, Jr. Hanks
- 出版社/メーカー: O'Reilly Media
- 発売日: 2016/07/28
- メディア: Kindle版
- この商品を含むブログを見る
NW 機器の自前構成情報管理 (ruby-nmap+SNMP で Discovery ~ Ansible Dynamic Inventory 連携) (original : 2015/12/15)
この記事は某所で 2015/12/15
に書いたもののコピーです。
そのため 2017/05/13
時点ではやや古い情報も含まれています。(以下一例)
Ansible
のバージョン1.8
系、今となっては古い
.
概要
NetOpsCoding Advent Calendar 2015 の 2015/12/15 分エントリです。 Ansible Dynamic Inventory で検索してこれにぶつかった人、ごめんなさい。そこはオマケ程度です。
本項でやること
- Nmap と SNMP を ruby で操作して、手っ取り早く NW 機器の構成情報を取得~ JSON 形式で吐き出す
- 上記ファイルを構成情報マスタとみなして、Ansible の dynamic inventory と連携する
モチベーション
- 仮想マシンの構成管理ソフトは割とあるけれど、物理含めた NW 機器も統合的に…となると選択肢は少ない…
- Nmap の fingerprint (OS検出)みたいなことも NW 機器相手に高精度でやりたい
- 色々なミドルウェアで hosts ファイル的な異なるフォーマットの設定ファイルを求めてくるが、手っ取り早く生成したい
- 大袈裟な仕組みは使いたくない
- 2015/11/19 に Nmap 7.0 がリリースされたので使わなきゃ(使命感)
前段
Nmap
言わずと知れた OSS ツールで、以下のような機能があります。超優れもの!
- Host Discovery | 公式
- OS Detection(fingerprint) | 公式
- ポートスキャンの結果などから、対象機器の OS を類推する
- etc etc
まあ 公式ドキュメントのイントロ を見れば分かるでしょう。
インフラ屋さんだと、ファイアウォールやら iptables やらのテストや、簡易な脆弱性診断で使ったりで馴染み深いのでは。
監視ソフトの Discovery 機能なんかでも、内部的に Nmap を呼んでいるものがあります。
基本的にはシェルから扱うのですが、GUI ツールであるZenmapもあります。
ruby-nmap
上記公式からの抜粋↓
A Rubyful interface to the Nmap exploration tool and security / port scanner.
以下のようなことができる Nmap の ruby 版ライブラリです。(作者は異なるものの、同じような機能を持つ Python 版や Perl 版ライブラリも存在する)
- Host Discovery のオプション群を分かりやすい表現で書ける
- CLI オプションとのマッピングは ruby-nmap/lib/nmap/task.rb を見るのが手っ取り早い
- Host Discovery で生成された xml をパース
- xml のパースを自前でやらなくて済むってだけで、嬉しくないですか。僕は嬉しい。
公式の Examples を見ると一目瞭然でしょう。
Ruby SNMP
SNMP を扱える ruby 版ライブラリです。(雑)
割と日本語記事も多いし、メジャーなやつでしょう。
Ansible Dynamic Inventory
- Dynamic Inventory | Ansible Documentation
- 公式ドキュメント
- ansible/contrib/inventory | github
- Ansible 本体に付属してくるサンプルスクリプト群(以下は例)
- OpenStack
- Zabbix
- Proxmox
- Amazon EC2
- VMware
- ssh_config
- etc etc
- Ansible 本体に付属してくるサンプルスクリプト群(以下は例)
- Ansible meetuptokyo 2015 Dynamic Inventory | SlideShare
- プロの Ansibler による分かり易い解説資料
他の場所に構成管理マスタがあり、Ansible の hosts ファイルを静的に書くと二重管理になるような環境で、構成管理マスタから hosts 情報をとってくる…という機能。
Discovery 環境準備
Discovery サーバ環境情報
Discovery を動かすサーバは以下です。
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" $ ruby -v ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux] $ gem list *** LOCAL GEMS *** bigdecimal (1.2.6) bundler (1.10.6) io-console (0.4.3) json (1.8.1) minitest (5.4.3) power_assert (0.2.2) psych (2.0.8) rake (10.4.2) rdoc (4.2.0) test-unit (3.0.8)
あと、このサーバから network reachable な NW 機器をいくらか動かしておきます。(本項では同一セグメント)
Nmap 7.0 インストール
以下公式手順に従います。
Download は以下から。
こんな感じでいけるでしょう。
$ sudo -E apt-get install libssl-dev $ cd /var/tmp/ $ wget https://nmap.org/dist/nmap-7.00.tar.bz2 $ bzip2 -cd nmap-7.00.tar.bz2 | tar xvf - $ ls -al total 8724 drwxrwxrwt 3 root root 4096 Dec 5 14:38 . drwxr-xr-x 11 root root 4096 Nov 7 17:42 .. drwxr-xr-x 22 kotetsu kotetsu 4096 Nov 20 01:19 nmap-7.00 -rw-rw-r-- 1 kotetsu kotetsu 8918906 Nov 20 05:23 nmap-7.00.tar.bz2 $ cd nmap-7.00/ $ ./configure $ make $ sudo -E make install (略) NMAP SUCCESSFULLY INSTALLED $ nmap --version Nmap version 7.00 ( https://nmap.org ) Platform: x86_64-unknown-linux-gnu Compiled with: nmap-liblua-5.2.3 openssl-1.0.1f nmap-libpcre-7.6 nmap-libpcap-1.7.3 nmap-libdnet-1.12 ipv6 Compiled without: Available nsock engines: epoll poll select
ruby-nmap / snmp の gem インストール
どちらも gem install
一発で入ります。
ruby-nmap
は xml を扱う関係上、依存関係に Nokogiri
があります。なので、インストールで躓いたらググって解決して下さい。
以下は bundler
を使った場合の手順です。
$ cd $ mkdir discovery $ cd discovery/ $ bundle init Writing new Gemfile to /home/kotetsu/discovery/Gemfile Gemfile を以下のように編集 $ cat Gemfile # A sample Gemfile source "https://rubygems.org" # gem 'ruby-nmap' gem `snmp` $ bundle install --path vendor/bundle $ cat Gemfile.lock GEM remote: https://rubygems.org/ specs: mini_portile2 (2.0.0) nokogiri (1.6.7) mini_portile2 (~> 2.0.0.rc2) rprogram (0.3.2) ruby-nmap (0.8.0) nokogiri (~> 1.3) rprogram (~> 0.3) snmp (1.2.0) PLATFORMS ruby DEPENDENCIES ruby-nmap snmp BUNDLED WITH 1.10.6
NW 機器側の SNMP 設定
今回、OS検知もどきとして SNMP Get で NW 機器の sysDescr
を取得します。
機種依存なく NW 機器の OS を知りたいならば、まあこれしかないでしょう、ってことで。
あと、ラック情報とかも纏めて取れるようにしておくと良いよね、ってことでそれは sysLocation
に設定しておきます(本項では全部仮想環境なのでアレな感じですが)。
何機種分か設定例を。
- JUNOS 例
snmp description とかを設定していると、OS 情報(デフォルト値)をとれなくなってしまうので注意。
kotetsu@vsrx01> show configuration | display set | match snmp set snmp location KotetsuNoteVB set snmp community KOTETSU_NW
- Arista 例
vEOS-spine001#show run | inc snmp snmp-server location KotetsuNoteVB snmp-server community KOTETSU_NW ro
- VyOS 例
kotetsu@vtep-vyos01:~$ show configuration commands | match snmp set service snmp community 'KOTETSU_NW' set service snmp location 'KotetsuNoteVB'
Discovery スクリプト作成~配置
ディレクトリ
以下のように適当なディレクトリを用意して、
$ mkdir scripts $ cd scripts/
後述の 3 つのファイルを配置します。
- スクリプト本体 (discovery_nwdevs.rb)
- スクリプトの設定ファイル(setting_discovery_nwdevs.yml)
- Nmap input file (target_nw.txt)
スクリプト本体
ruby-nmap
と Ruby SNMP
を使って NW 機器の構成情報を収集して、JSON ファイルに吐き出すサンプルスクリプトです。
# encoding: utf-8 # # Usage: # bundle exec ruby discovery_nwdevs.rb <setting.yml> # require 'nmap/program' require 'nmap/xml' require 'snmp' require 'yaml' require 'json' # # SNMP Get method # def snmp_get_system(target_ip, snmp_params) manager = SNMP::Manager.new( :host => target_ip, :port => 161, :version => :SNMPv2c, :community => snmp_params["community"], :timeout => 1, :retries => 1 ) # sysName にはホスト名 # sysDescr には機種やバージョン情報 # sysLocation は(設定していれば)設置場所 # が入っている筈なので、それをとる ret = Hash::new ret[:sysname] = manager.get_value(snmp_params["oid_sysname"]).to_s rescue "" ret[:sysdesc] = manager.get_value(snmp_params["oid_sysdesc"]).to_s rescue "" ret[:syslocation] = manager.get_value(snmp_params["oid_syslocation"]).to_s rescue "" manager.close return ret end # # main # begin # 外出ししている情報 YAML ファイルをロード params = YAML.load_file(ARGV[0]) # Nmap の Host Discovery をして xml ファイルに書き出す # ポートスキャンは UDP/161 のみに限定して、SNMP Get で情報が取得可能かどうかを見ておく # NW 機器なんて Nmap の fingerprint 機能に頼るよりは、SNMP Get で見た方が確実なので、fingerprint もしない Nmap::Program.scan do |nmap| nmap.syn_scan = false nmap.udp_scan = true nmap.service_scan = false nmap.os_fingerprint = false nmap.xml = params["nmap_params"]["xml_file"] nmap.verbose = true nmap.ports = [] unless params["nmap_params"]["scan_udp_ports"].nil? then params["nmap_params"]["scan_udp_ports"].each do |port| nmap.ports << port["port"] end end # Discovery の対象とする NW アドレスを羅列したファイル nmap.target_file = params["nmap_params"]["scan_target_files"]["targetfile"] end # 反応があったノード(up host)の情報(Hash)を格納 array_hosts = [] # Nmap の Host Discovery で生成された xml ファイルを走査 # 反応があったノード(up host)を取得し、 # UDP/161 が Open 判定されていたら SNMP で追加情報取得する Nmap::XML.new(params["nmap_params"]["xml_file"]) do |xml| xml.each_up_host do |host| hash_host = {} hash_snmp_info = {} hash_host[:ipaddr] = host.ipv4 hash_host[:ptr] = host.hostname hash_host[:sysname] = "" hash_host[:sysdesc] = "" hash_host[:syslocation] = "" host.each_port do |port| if (port.number == 161) && (port.state == :open) then hash_snmp_info = snmp_get_system(host.ipv4, params["snmp_params"]) unless hash_snmp_info.nil? then hash_host[:sysname] = hash_snmp_info[:sysname] hash_host[:sysdesc] = hash_snmp_info[:sysdesc] hash_host[:syslocation] = hash_snmp_info[:syslocation] end end end array_hosts << hash_host end end # 収集したノードの情報を JSON 形式ファイルで吐き出す unless array_hosts.nil? then dir_result = File.expand_path(params["nmap_params"]["output_directory"]) json_hosts = JSON.pretty_unparse(array_hosts) File.open("#{dir_result}/list_nwdev.json","w") do |file| file.write(json_hosts) end end # なんか適切にエラーハンドリングしてください rescue SNMP::RequestTimeout => e # rescue StandardError => e puts e puts e.backtrace ensure # end
スクリプトの設定ファイル
前述のスクリプトに食わせる設定ファイルです。
別環境でスクリプトに手を加えず、設定ファイルだけ書き換えて使う…みたいなことを考えていたのですが…「標準 MIB の OID が変わるっていうのか?」なんて突っ込みは不可。
setting_discovery_nwdevs.yml
nmap_params : # nmap の -iL オプションで渡す discovery 対象を記載したファイル scan_target_files : targetfile : './target_nw.txt' # nmap の -PU -p オプションで渡す UDP ポートスキャン対象 scan_udp_ports : - port : 161 # nmap の -oX オプションで渡す、Host Discovery の output である xml ファイル xml_file : './scan.xml' # スクリプトの最終 output である JSON ファイルを生成するディレクトリ(nmap に渡すオプションではないので、nmap_params 配下にいるのは違和感ありますね…) output_directory : './' snmp_params : # 動かす環境の NW 機器に設定してある SNMP community # 同じ環境の community ならきっと統一されているだろう、という前提のもと… community : 'KOTETSU_NW' # SNMP Get 対象の OID たち oid_sysname : '1.3.6.1.2.1.1.5.0' oid_sysdesc : '1.3.6.1.2.1.1.1.0' oid_syslocation : '1.3.6.1.2.1.1.6.0'
Nmap input file
Nmap で Host Discovery する対象を羅列したファイル。
ruby-nmap は内部的に nmap に -iL
オプションで食わせているだけなので、記法は Target Specification | Nmap 公式 を参照。
target_nw.txt
192.168.101.0/24 # mgmt NW
Discovery 実行~出力確認
スクリプト実行
こんな感じで。
Nmap でポートスキャンするには基本的には root 権限が必要なので、sudo
しています。(以下公式の参考資料)
Discoveryスクリプト実行
$ sudo -E bundle exec ruby discovery_nwdevs.rb setting_discovery_nwdevs.yml Starting Nmap 7.00 ( https://nmap.org ) at 2015-12-05 14:11 JST Initiating ARP Ping Scan at 14:11 Scanning 255 hosts [1 port/host] Completed ARP Ping Scan at 14:11, 1.64s elapsed (255 total hosts) Initiating Parallel DNS resolution of 255 hosts. at 14:11 Completed Parallel DNS resolution of 255 hosts. at 14:11, 0.04s elapsed (略) Read data files from: /usr/local/bin/../share/nmap Nmap done: 256 IP addresses (5 hosts up) scanned in 2.14 seconds Raw packets sent: 513 (14.784KB) | Rcvd: 11 (836B)
生成ファイル確認
生成されたファイル
Nmap が生成した scan.xml
と、スクリプトが生成した list_nwdev.json
が root:root
で吐き出されています。
$ ls -al total 60 drwxrwxr-x 2 kotetsu kotetsu 4096 Dec 6 14:11 . drwxrwxr-x 5 kotetsu kotetsu 4096 Dec 6 14:08 .. -rw-r--r-- 1 kotetsu kotetsu 3129 Dec 6 14:04 discovery_nwdevs.rb -rw-r--r-- 1 root root 643 Dec 6 14:11 list_nwdev.json -rw-r--r-- 1 root root 34690 Dec 6 14:11 scan.xml -rw-r--r-- 1 kotetsu kotetsu 281 Dec 6 14:01 setting_discovery_nwdevs.yml -rw-rw-r-- 1 kotetsu kotetsu 28 Dec 6 11:07 target_nw.txt
Nmap が生成した xml ファイル
scan.xml
の中身を軽く見ていきます。(この辺は、Nmap を使っている人ならよく知っているのでは)
- 最初のほうで、実際に
ruby-nmap
が実行したコマンドオプションや Nmap の実行バージョン、実行時刻などが分かる
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE nmaprun> <?xml-stylesheet href="file:///usr/local/bin/../share/nmap/nmap.xsl" type="text/xsl"?> <!-- Nmap 7.00 scan initiated Wed Dec 6 14:11:37 2015 as: /usr/local/bin/nmap -sU -oX ./scan.xml -v -p 161 -iL ./target_nw.txt --> <nmaprun scanner="nmap" args="/usr/local/bin/nmap -sU -oX ./scan.xml -v -p 161 -iL ./target_nw.txt" start="1449637897" startstr="Sat Dec 6 14:11:37 2015" version="7.00" xmloutputversion="1.04"> <scaninfo type="udp" protocol="udp" numservices="1" services="161"/> <verbose level="1"/> <debugging level="0"/> <taskbegin task="ARP Ping Scan" time="1449378697"/> <taskend task="ARP Ping Scan" time="1449378699" extrainfo="255 total hosts"/> <taskbegin task="Parallel DNS resolution of 255 hosts." time="1449378699"/> <taskend task="Parallel DNS resolution of 255 hosts." time="1449378699"/>
- Down しているホストの情報が続く
<host><status state="down" reason="no-response" reason_ttl="0"/> <address addr="192.168.101.3" addrtype="ipv4"/> </host> <host><status state="down" reason="no-response" reason_ttl="0"/> <address addr="192.168.101.4" addrtype="ipv4"/> </host>
- Up しているホストの情報が続く
<host starttime="1449378697" endtime="1449378699"><status state="up" reason="arp-response" reason_ttl="0"/> <address addr="192.168.101.30" addrtype="ipv4"/> <address addr="52:54:00:76:24:2C" addrtype="mac" vendor="QEMU virtual NIC"/> <hostnames> <hostname name="vsrx01" type="PTR"/> </hostnames> <ports><port protocol="udp" portid="161"><state state="open" reason="udp-response" reason_ttl="64"/><service name="snmp" method="table" conf="3"/></port> </ports> <times srtt="24054" rttvar="34787" to="163202"/> </host>
スクリプトが生成した JSON ファイル
- Nmap が名前解決出来たもの(以下例では
192.168.101.30
のみ名前登録してあった)は xml のhostname
をptr
に格納 sysname
とsysdesc
とsyslocation
は SNMP Get で取得した情報- Nmap で UDP 161 が Open していないと判断した
192.168.101.172
に関しては、ほとんど情報は取得できていない- まあ、その IP アドレスが何らかの機器に使われている、ということくらい
list_nwdev.json
[ { "ipaddr": "192.168.101.30", "ptr": "vsrx01", "sysname": "vsrx01", "sysdesc": "Juniper Networks, Inc. vsrx internet router, kernel JUNOS 15.1X49-D15.4, Build date: 2015-07-31 03:30:01 UTC Copyright (c) 1996-2015 Juniper Networks, Inc.", "syslocation": "KotetsuNoteVB" }, { "ipaddr": "192.168.101.50", "ptr": null, "sysname": "vEOS-spine001", "sysdesc": "Arista Networks EOS version 4.14.8M running on an Arista Networks vEOS", "syslocation": "KotetsuNoteVB" }, { "ipaddr": "192.168.101.52", "ptr": null, "sysname": "vEOS-leaf001", "sysdesc": "Arista Networks EOS version 4.14.8M running on an Arista Networks vEOS", "syslocation": "KotetsuNoteVB" }, { "ipaddr": "192.168.101.71", "ptr": null, "sysname": "vtep-vyos01", "sysdesc": "Vyatta VyOS 1.1.1", "syslocation": "KotetsuNoteVB" }, { "ipaddr": "192.168.101.172", "ptr": null, "sysname": "", "sysdesc": "", "syslocation": "" } ]
連携例 ~Ansible の Dynamic Inventory~
やること
先に生成した JSON ファイルを「構成情報マスタ」とみなして連携する例として Ansible の Dynamic Inventory で使ってみます。
NW 機器の中から Arista だけを抜き出して、Arista 用の Role を使った Playbook を実行するです。
環境
横着して、昔(2014/12)作った以下環境を流用して Arista をターゲットに使います。
2015/12 現在だと、Ansible は 2.1.0 とかまで出ているし、ansible-eos (Arista 用の Role)もかなり更新が入っていますが…。
Dynamic Inventory サンプルスクリプト
先に作った JSON ファイルをパースして、最低限動くだけのサンプルです。
要するに sysDescr
で機種を仕分けているだけ。
dynamic_nwdevs.rb
#! /usr/bin/env ruby # encoding: utf-8 require 'json' FILE_INVENTORY = '/home/kotetsu/discovery/scripts/list_nwdev.json' begin if (ARGV[0] && ARGV[0] == '--list') then ret = {} list_junos = [] list_arista = [] list_vyos = [] JSON.load(File.open(FILE_INVENTORY).read).each do |nwdev| case nwdev["sysdesc"] when /^Juniper.*JUNOS.*/ list_junos << nwdev["ipaddr"] when /^Arista Networks EOS.*/ list_arista << nwdev["ipaddr"] when /^Vyatta VyOS/ list_vyos << nwdev["ipaddr"] else # end end ret["junos_all"] = list_junos.dup unless list_junos.size == 0 ret["arista_all"] = list_arista.dup unless list_arista.size == 0 ret["vyos_all"] = list_vyos.dup unless list_vyos.size == 0 puts JSON.pretty_unparse(ret) elsif (ARGV[1] && ARGV[0] == "--host") then JSON.load(File.open(FILE_INVENTORY).read).each do |nwdev| if ( nwdev["sysname"] =~ Regexp.new(ARGV[1]) || nwdev["ipaddr"] =~ Regexp.new(ARGV[1]) || nwdev["ptr"] =~ Regexp.new(ARGV[1]) ) then puts JSON.pretty_unparse(nwdev) end end end rescue Exception => e puts e puts e.backtrace end
公式のサンプルスクリプトでは Python が圧倒的に多いですが、よくある「所定の引数をつけて実行した時に、所定のOutputを返せば良い」系のやつなので、言語は何で書いても良いです。(この程度ならシェルスクリプトでも)
で、これを実行すると以下の感じ。
$ ./dynamic_nwdevs.rb --list { "junos_all": [ "192.168.101.30" ], "arista_all": [ "192.168.101.50", "192.168.101.52" ], "vyos_all": [ "192.168.101.71" ] } $ ./dynamic_nwdevs.rb --host vEOS-spine001 { "ipaddr": "192.168.101.50", "ptr": null, "sysname": "vEOS-spine001", "sysdesc": "Arista Networks EOS version 4.14.8M running on an Arista Networks vEOS", "syslocation": "KotetsuNoteVB" }
_meta
を出さないので、無駄な処理が走るのですがね。まあローカルのファイル読んでいるテスト環境なので…(モゴモゴ)
その辺は Ansible meetuptokyo 2015 Dynamic Inventory | SlideShare のスライド 10~12 を見ましょう。
Arista 用のサンプル Playbook
role
で Arista 公式の Role を呼んでいる完全に Arista 専用の Playbookhosts
では先の./dynamic_nwdevs.rb --list
で出力されたarista_all
という Arista 全台グループを指定show version
して stdout するだけ
playbook_sample_arista.yml
- name: eos nodes hosts: arista_all gather_facts: no sudo: true vars: eapi_username: kotetsu eapi_password: kotetsu eapi_protocol: http roles: - role: arista.eos tasks: - name: show version action: eos_command args: { commands: [ "show version" ], eapi_username: "{{ eapi_username }}", eapi_password: "{{ eapi_password }}", eapi_protocol: "{{ eapi_protocol }}" } register: output_version - debug: var=output_version
Playbook 実行
レッツゴー
(-i
で呼んでいるのが hosts
ファイルではなくて、先の dynamic_nwdevs.rb
なのがポイント)
DynamicInventoryでPlaybook実行
$ ansible-playbook playbook_sample_arista.yml -f 10 -u ansible -i dynamic_nwdevs.rb PLAY [eos nodes] ************************************************************** TASK: [arista.eos | check if running on eos node] ***************************** ok: [192.168.101.50] ok: [192.168.101.52] TASK: [arista.eos | collect eos facts] **************************************** ok: [192.168.101.50] ok: [192.168.101.52] TASK: [arista.eos | include eos variables] ************************************ ok: [192.168.101.50] ok: [192.168.101.52] TASK: [arista.eos | check for working directory] ****************************** ok: [192.168.101.52] ok: [192.168.101.50] TASK: [arista.eos | create source] ******************************************** skipping: [192.168.101.52] skipping: [192.168.101.50] TASK: [arista.eos | check if pip is installed] ******************************** ok: [192.168.101.50] ok: [192.168.101.52] TASK: [arista.eos | copy pip extension to node] ******************************* skipping: [192.168.101.50] skipping: [192.168.101.52] TASK: [arista.eos | create tmp config file to load pip] *********************** skipping: [192.168.101.50] skipping: [192.168.101.52] TASK: [arista.eos | load pip eos extension] *********************************** skipping: [192.168.101.52] skipping: [192.168.101.50] TASK: [arista.eos | copy required libraries to node] ************************** ok: [192.168.101.50] => (item=eapilib-0.1.0.tar.gz) ok: [192.168.101.52] => (item=eapilib-0.1.0.tar.gz) TASK: [arista.eos | install required libraries] ******************************* ok: [192.168.101.50] => (item=eapilib-0.1.0.tar.gz) ok: [192.168.101.52] => (item=eapilib-0.1.0.tar.gz) TASK: [arista.eos | install jsonrpclib] *************************************** skipping: [192.168.101.50] skipping: [192.168.101.52] TASK: [arista.eos | install required libraries and dependencies] ************** skipping: [192.168.101.50] => (item=eapilib-0.1.0.tar.gz) skipping: [192.168.101.52] => (item=eapilib-0.1.0.tar.gz) TASK: [show version] ********************************************************** ok: [192.168.101.52] ok: [192.168.101.50] TASK: [debug var=output_version] ********************************************** ok: [192.168.101.50] => { "output_version": { "changed": false, "invocation": { "module_args": "", "module_name": "eos_command" }, "output": [ { "command": "show version", "response": { "architecture": "i386", "bootupTimestamp": 1449902847.6, "hardwareRevision": "", "internalBuildId": "a6bbeeb3-95b7-42bc-9721-266f9bff424e", "internalVersion": "4.14.8M-2475814.4148M", "memFree": 20516, "memTotal": 996140, "modelName": "vEOS", "serialNumber": "", "systemMacAddress": "08:00:27:31:60:65", "version": "4.14.8M" } } ] } } ok: [192.168.101.52] => { "output_version": { "changed": false, "invocation": { "module_args": "", "module_name": "eos_command" }, "output": [ { "command": "show version", "response": { "architecture": "i386", "bootupTimestamp": 1449902847.71, "hardwareRevision": "", "internalBuildId": "a6bbeeb3-95b7-42bc-9721-266f9bff424e", "internalVersion": "4.14.8M-2475814.4148M", "memFree": 46872, "memTotal": 996140, "modelName": "vEOS", "serialNumber": "", "systemMacAddress": "08:00:27:e2:d0:f4", "version": "4.14.8M" } } ] } } PLAY RECAP ******************************************************************** 192.168.101.50 : ok=10 changed=0 unreachable=0 failed=0 192.168.101.52 : ok=10 changed=0 unreachable=0 failed=0
Arista だけに処理が走りました。
おしまい
plus one
今回は Discovery との連携例として Ansible の Dynamic Inventory を使いましたが、Discovery は Nmap/SNMP だけの超単純な仕組みなので、他の仕組みとの連携も面倒なくいけるんですよな。
例えば、こんなのはよくやっているのではないでしょうか。
- ここで生成した JSON ファイルをロードして
sysDescr
をcase
で分けて、機種に応じた処理- 詳細な inventory 情報取得(シリアル番号とかラインカード/SFP構成とか)
- config 取得 (後述の rancid 方式でもよい)
- discovery ~ config 取得 ~ バージョン管理コマンドも cron で回しておくと、増えた機器が勝手にバックアップ・バージョン管理される
- 各種ミドルウェアの設定ファイル生成(サンプルスクリプトのアウトプットを JSON でなく、設定ファイル形式にするでも)
- rancid
- Ansible
- hosts ファイル
- Dynamic Inventory と連携
- 本項で軽くやったやつ
- 監視ソフト(auto discovery 的な機能がない)
- 機種に応じた自前の plugin を指定して…とかも自動でやれる
- 特定バージョンを対象とした
- OS ファイル転送
- 設定撒き
ptr
が空でsysname
を取得できたものに関して、内部 DNS コンテンツの設定生成(~追加)sysDesc
とsysname
の組み合わせで条件付けて、待機系機器のみ云々
- JSON ファイルに書き出した情報を SQL に放り込んで、WebUI なり API なりを提供
- 前述の内容を実現するのに、踏み台サーバや監視サーバからも inventory 情報を取得したい、って思ったり
- 別に rsync とかで撒いてもよいが
- 実機から取得できる情報には限界があるし、人間が入力・更新したい情報もあるのでは(商用環境だと保守期限とか)
- ありもの製品の WebUI は実運用要件を充たすようにカスタマイズできないから、自前で簡易で運用要件を充たすものを立てたほうが楽、とか
- そういう思いから自前で作り込まれた社内システムとかには、文句たらたらで「ありもののパッケージ使えよ」とか言うのにね
- 前述の内容を実現するのに、踏み台サーバや監視サーバからも inventory 情報を取得したい、って思ったり
所感
- まあ、なんというか「何をマスタ情報にして、他コンポーネントとどういう連携をするか」は環境次第なので、こんな方法もあるよ、ってだけですな
- 超メジャーな Nmap を使った Inventory の生成、なんてのは割とポピュラーな手法で、以下のようなものを使えば同じこと+アルファが出来ます(いずれも内部的には Nmap を使っている模様)
- Open-AudIT
- JSON, xlsx, pdf 形式などで情報をエクスポートできるらしい
- 本項の Discovery レベルの話は全部できそう
- ローレベルディスカバリ | Zabbix 2.2
- SNMP 連携できるディスカバリって点では、物理 NW 機器を一元管理する場合には、これがマッチする気がする
- Open-AudIT
- ただまあ、もっと手軽に…とか、アウトプットの書式を任意に作りたい(他のミドルウェアで使う設定ファイル生成とか)とかのケースでは、使えるのではないでしょうかね
- 生で Nmap 叩いて xml をサクッとパースすればライブラリさえ使う必要ないのですが…
- Nmap 7.0 の新機能を一切触ってないじゃねぇか!
Juniper vSRX(15.1X) を VirtualBox で動かす (original : 2015/12/11)
この記事は某所で 2015/12/11
に書いたもののコピーです。
そのため 2017/05/13
時点ではやや古い情報も含まれています。
- Juniper さんの vSRX ダウンロード規約が変わっていそう (詳細は未確認)
.
概要
本項でやること
- KVM、VMware ESX 向けの 60 日間 trial 版が公開されている Juniper vSRX を VirtualBox に入れる
- 公式にはサポートされない手順なので、自己責任で
- JUNOS の基本的な操作は省略(ある程度知っている人向け)
環境情報
- ホスト: Windows7 + VirtualBox 4.3.18
- Juniper vSRX: JUNOS 15.1X49-D15.4
vSRX?
- Juniper SRX の 仮想版
- 以前は Firefly Perimeter として公開されていた
- DPDK 対応などの機能強化を果たして、ほぼ別物として名前も Firefly から vSRX になった
- 参考 2014年03月時点での Firefly Perimeter ロードマップなど
- version が 12.1X となっているものは Firefly で 15.1X となっているものは vSRX
- だが、最近は旧 Firefly も vSRX と呼ばれていたりして、ややこしい
手順
vSRX イメージファイル取得
- Trial 版ダウンロードページ | Juniper または ダウンロードページ | Juniper にアクセス
vSRX VMware Appliance with IDE virtual disk
を選択してmedia-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.ova
をダウンロード2015/11/23
現在の最新版
ovf 形式にファイル変換
- 取得したovaファイルを ovf 形式にする (以下例では VMwarePlayer などに同梱されている ovftool を使用)
>ovftool.exe media-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.ova \convert\media-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.ovf Opening OVA source: media-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.ova The manifest validates Opening OVF target: \convert\media-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.ovf Writing OVF package: \convert\media-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.ovf Transfer Completed Source is signed but could not verify certificate (possibly self-signed) Completed successfully
media-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.ovf media-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide-disk1.vmdk media-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.mf
変換したファイルに小細工(インポートエラーが出ないように)
media-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.mf
ファイルは別ディレクトリに除外しておくmedia-srx-ffp-vsrx-vmdisk-15.1X49-D15.4.ide.ovf
の line 82 を以下のように上書き編集(%iid%
->2
)
編集前
<Item ovf:configuration="4GvRAM"> <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits> <rasd:Description>Memory Size</rasd:Description> <rasd:ElementName>Memory</rasd:ElementName> <rasd:InstanceID>%iid%</rasd:InstanceID> <rasd:ResourceType>4</rasd:ResourceType> <rasd:VirtualQuantity>4096</rasd:VirtualQuantity>
編集後
<Item ovf:configuration="4GvRAM"> <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits> <rasd:Description>Memory Size</rasd:Description> <rasd:ElementName>Memory</rasd:ElementName> <rasd:InstanceID>2</rasd:InstanceID> <rasd:ResourceType>4</rasd:ResourceType> <rasd:VirtualQuantity>4096</rasd:VirtualQuantity>
VirtualBox に ovf をインポート
ファイル
->仮想マシンのインポート
で先の編集した ovf ファイルを指定
- 以降の画面キャプチャはインポート後の設定からとってきたもの
- どうやら
アダプタータイプ
は一回起動したあとは勝手に準仮想化ネットワーク(virtio-net)
にされるようだ アダプター 1
が JUNOS 側から見るとfxp0
(管理用ポート)になる
コンソール画面から初期設定
- 起動する
- 無事に起動できたら、コンソールログインして以下を設定する
# root password の設定(必須) set system root-authentication plain-text-password -> 対話型で入力 # ユーザ作成とパスワード設定 set system login user <username> class super-user set system login user <username> authentication plain-text-password # ssh 有効化 set system services ssh root-login deny set system services ssh protocol-version v2
- 必要に応じて、以下手順でデフォルトのファイアウォールモードからルータモード(いずれも俗称)に切り替える(要再起動)
ssh して状態確認
--- JUNOS 15.1X49-D15.4 built 2015-07-31 02:20:21 UTC kotetsu> kotetsu> show version Model: vSRX Junos: 15.1X49-D15.4 JUNOS Software Release [15.1X49-D15.4] kotetsu> show chassis hardware Hardware inventory: Item Version Part number Serial number Description Chassis 5028f7dddeb5 VSRX Midplane System IO Routing Engine VSRX RE FPC 0 Virtual FPC PIC 0 Virtual GE Power Supply 0 kotetsu> show system license License usage: Licenses Licenses Licenses Expiry Feature name used installed needed Virtual Appliance 1 1 0 59 days Licenses installed: License identifier: E420588955 License version: 4 Software Serial Number: 20150625 Customer ID: vSRX-JuniperEval Features: Virtual Appliance - Virtual Appliance count-down, Original validity: 60 days kotetsu> show configuration | display set set version 15.1X49-D15.4 set system root-authentication encrypted-password "$1$8FV6oxYf$H0vFbn4hEjZEwb748.JxK0" set system login user kotetsu uid 2000 set system login user kotetsu class super-user set system login user kotetsu authentication encrypted-password "$1$w/Ff6i9v$1wW4Wrt8Xy04P8ee63/Hb." set system services ssh root-login deny set system services ssh protocol-version v2 set system services web-management http interface fxp0.0 set system syslog user * any emergency set system syslog file messages any any set system syslog file messages authorization info set system syslog file interactive-commands interactive-commands any set system license autoupdate url https://ae1.juniper.net/junos/key_retrieval set security forwarding-options family mpls mode packet-based set interfaces fxp0 unit 0 family inet address 192.168.101.30/24
おわり
- インストールしただけなので別に…