LinuxのnmcliコマンドによるBonding、VLAN、Bridge Interfaceの設定方法に加えて、SR-IOVを使用した場合について記載しました。
SR-IOVの使用方法として、KVMとLXC/LXDのそれぞれについてもまとめました。
また、SR-IOVを使用する場合の注意点についても記載しました。
さらに、内部ネットワーク的な疎通可否についても記載しました。
1.構成
1-1.環境
筐体 : ProLiant DL360p Gen8 System ROM : P71 01/22/2018 NIC : Intel X520-SR2 OS : CentOS7.5(1804) Kernel : 4.19.0-1.el7.elrepo.x86_64 Installed Environment Groups : Server with GUI Add-Ons for Selected Environment : Virtualization Client, Virtualization Hypervisor, Virtualization Tools
1-2.全体構成
構成図上に(1)~(21)までの番号を割り振りました。
(1)~(10)については過去記事を参照してください。
metonymical.hatenablog.com
(11)~(21)については主にVLANやIPの設定となります。
各VLANとIPは以下の通りです。
(11)(13)(16)(19)
Untag:192.168.30.22x/24
(12)(14)(18)(21)
VLAN301:192.168.31.22x/24
(15)
Untag:192.168.31.222/24*1
SR-IOVを使用する場合、仮想マシンやコンテナを起動する前にVFを予めアタッチした後*2、起動させます。
アタッチ方法については、nmcliコマンドではできないため、適時解説します。
各仮想マシンやコンテナは以下の通りです。
c750~c753:KVM上の仮想マシン
lxc754:LXC/LXD上のコンテナ
スイッチ側の設定は以下となります。
interface GigabitEthernet0/1 switchport trunk encapsulation dot1q switchport trunk native vlan 300 switchport trunk allowed vlan 300,301 switchport mode trunk spanning-tree portfast trunk ! interface Port-channel1 switchport trunk encapsulation dot1q switchport trunk native vlan 300 switchport trunk allowed vlan 300,301 switchport mode trunk spanning-tree portfast trunk ! interface TenGigabitEthernet0/1 switchport trunk encapsulation dot1q switchport trunk native vlan 300 switchport trunk allowed vlan 300,301 switchport mode trunk spanning-tree portfast trunk channel-group 1 mode on ! interface TenGigabitEthernet0/2 switchport trunk encapsulation dot1q switchport trunk native vlan 300 switchport trunk allowed vlan 300,301 switchport mode trunk spanning-tree portfast trunk channel-group 1 mode on ! interface Vlan300 ip address 192.168.30.1 255.255.255.0 ! interface Vlan301 ip address 192.168.31.1 255.255.255.0
1-3.全体の流れ ~概要~
1-4.全体の流れ ~コマンドのみ~
以下のコマンドを投入していきます。
やりたいことが既に決まっている方は、構成図とコマンドの内容を見るだけでもよいと思います。
1.物理+Bridge (1) nmcli connection add type bridge autoconnect yes con-name br1 ifname br1 nmcli connection modify br1 bridge.stp no nmcli connection modify br1 ipv4.method disabled ipv6.method ignore nmcli connection up br1 nmcli con show brctl show (2) nmcli connection add type bridge-slave ifname eno3 master br1 nmcli con show brctl show (3) nmcli connection add type bond con-name bond0 ifname bond0 mode balance-xor nmcli connection mod bond0 ipv4.method disabled ipv6.method ignore nmcli con show (4) nmcli connection add type bond-slave autoconnect yes ifname ens1f0 master bond0 nmcli con show (5) nmcli connection add type bond-slave autoconnect yes ifname ens1f1 master bond0 nmcli con show (6) nmcli connection add type bridge autoconnect yes con-name br0 ifname br0 nmcli connection modify br0 bridge.stp no nmcli connection modify br0 ipv4.method disabled ipv6.method ignore nmcli connection up br0 nmcli con show brctl show (7) nmcli connection modify bond0 connection.master br0 connection.slave-type bridge nmcli con show brctl show (8) nmcli connection add type bridge autoconnect yes con-name br301 ifname br301 nmcli connection modify br301 bridge.stp no nmcli connection modify br301 ipv4.method disabled ipv6.method ignore nmcli connection up br301 nmcli con show brctl show (9) nmcli connection add type vlan autoconnect yes con-name bond0.301 ifname bond0.301 dev bond0 id 301 nmcli con show brctl show (10) nmcli connection modify bond0.301 connection.master br301 connection.slave-type bridge nmcli connection up bond0.301 nmcli con show brctl show c750 (11) nmcli connection add type ethernet autoconnect yes con-name eth1 ifname eth1 nmcli connection mod eth1 ipv4.method manual ipv4.address 192.168.30.220/24 nmcli connection mod eth1 ipv6.method ignore nmcli con up eth1 nmcli con show (12) nmcli connection add type vlan autoconnect yes con-name eth1.301 ifname eth1.301 dev eth1 id 301 nmcli connection mod eth1.301 ipv4.method manual ipv4.address 192.168.31.220/24 nmcli connection mod eth1.301 ipv6.method ignore nmcli con up eth1.301 nmcli con show c751 (13) nmcli connection add type ethernet autoconnect yes con-name eth1 ifname eth1 nmcli connection mod eth1 ipv4.method manual ipv4.address 192.168.30.221/24 nmcli connection mod eth1 ipv6.method ignore nmcli con up eth1 nmcli con show (14) nmcli connection add type vlan autoconnect yes con-name eth1.301 ifname eth1.301 dev eth1 id 301 nmcli connection mod eth1.301 ipv4.method manual ipv4.address 192.168.31.221/24 nmcli connection mod eth1.301 ipv6.method ignore nmcli con up eth1.301 nmcli con show c752 (15) nmcli connection add type ethernet autoconnect yes con-name eth1 ifname eth1 nmcli connection mod eth1 ipv4.method manual ipv4.address 192.168.31.222/24 nmcli connection mod eth1 ipv6.method ignore nmcli con up eth1 nmcli con show c753 Virt-Manager画面上でPCI デバイスを選択 or virsh edit c753 <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x04' slot='0x10' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x04' slot='0x10' function='0x1'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </hostdev> (16) nmcli connection add type bond con-name bond0 ifname bond0 mode balance-xor nmcli connection mod bond0 ipv4.method manual ipv4.address 192.168.30.223/24 nmcli connection mod bond0 ipv6.method ignore nmcli con show (17) nmcli connection add type bond-slave autoconnect yes ifname ens4 master bond0 nmcli connection add type bond-slave autoconnect yes ifname ens5 master bond0 nmcli con show (18) nmcli connection add type vlan autoconnect yes con-name bond0.301 ifname bond0.301 dev bond0 id 301 nmcli connection mod bond0.301 ipv4.method manual ipv4.address 192.168.31.223/24 nmcli connection mod bond0.301 ipv6.method ignore nmcli con up bond0 nmcli con up bond0.301 nmcli con show ip add show lxc754 lxc config device add lxc754 eth1 nic nictype=sriov parent=ens1f0 lxc config device add lxc754 eth2 nic nictype=sriov parent=ens1f1 (19) nmcli connection add type bond con-name bond0 ifname bond0 mode balance-xor nmcli connection mod bond0 ipv4.method manual ipv4.address 192.168.30.224/24 nmcli connection mod bond0 ipv6.method ignore nmcli con show (20) nmcli connection add type bond-slave autoconnect yes ifname eth1 master bond0 nmcli connection add type bond-slave autoconnect yes ifname eth2 master bond0 nmcli con show (21) nmcli connection add type vlan autoconnect yes con-name bond0.301 ifname bond0.301 dev bond0 id 301 nmcli connection mod bond0.301 ipv4.method manual ipv4.address 192.168.31.224/24 nmcli connection mod bond0.301 ipv6.method ignore nmcli con up bond0 nmcli con up bond0.301 nmcli con show ip add show
(1)~(10)の詳細は省略し、以下は(11)から解説します。
また、全ての出力結果を表示させると不要な設定も記載することになるため、一部省略します。
2.c750のEthernet&VLAN+IP
物理とVLANインターフェースを作成しIPをアサインします。
(11)物理インターフェースeth1とIPの設定
(12)VLANインターフェースeth1.301とIPの設定
出力結果 [root@c750 ~]# nmcli con show NAME UUID TYPE DEVICE eth0 2c180c0c-76b3-4f05-b04e-546812f51811 ethernet eth0 eth1 5e55d7f8-1db1-48d0-a954-46c996ad5533 ethernet eth1 eth1.301 e39150fd-d1ab-42e9-8a23-d48733229b38 vlan eth1.301 virbr0 5ee27a89-6153-4e47-9a68-dbbd1caf1e04 bridge virbr0 [root@c750 ~]# ip add show 3: eth1:mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 52:54:00:4d:da:7b brd ff:ff:ff:ff:ff:ff inet 192.168.30.220/24 brd 192.168.30.255 scope global noprefixroute eth1 valid_lft forever preferred_lft forever inet6 fe80::5054:ff:fe4d:da7b/64 scope link valid_lft forever preferred_lft forever 8: eth1.301@eth1: mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 52:54:00:4d:da:7b brd ff:ff:ff:ff:ff:ff inet 192.168.31.220/24 brd 192.168.31.255 scope global noprefixroute eth1.301 valid_lft forever preferred_lft forever inet6 fe80::5054:ff:fe4d:da7b/64 scope link tentative valid_lft forever preferred_lft forever
3.c751のEthernet&VLAN+IP
物理とVLANインターフェースを作成しIPをアサインします。
(13)物理インターフェースeth1とIPの設定
(14)VLANインターフェースeth1.301とIPの設定
出力結果 c750とほぼ同一のため省略 異なる点は、IPアドレスの第4オクテットが221となります。
4.c752のEthernet+IP
物理インターフェースを作成しIPをアサインします。
(15)物理インターフェースeth1とIPの設定
出力結果 c750とほぼ同一のため省略 異なる点は、IPアドレスの第4オクテットが222となります。
5.c753のBonding&VLAN+IP
仮想マシン起動前にVFをアタッチします。
ホストOSのVirt-Manager上でAdd Hardwareを実施し以下の画面のようにアタッチしてください。
上記画面の場合、VFのBus:Device(Slot).function番号が0000:04:10:0となっていますが、以下のようにPFとVFのBus:Device(Slot).function番号は対応しています。
ens1f0=04:10:0, 04:10:2
ens1f1=04:10:1, 04:10:3
または、ホストOS上のvirshでアタッチする場合は、以下のように設定してください。
address domain=の行がVFのBus:Device(Slot).function番号に対応しています。
# virsh edit c753 <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x04' slot='0x10' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x04' slot='0x10' function='0x1'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </hostdev>
上記設定が完了した後、仮想マシンを起動して以下の設定を仮想マシン上で行ってください。
BondingインターフェースとVLANインターフェースを作成します。
(16)Bondingインターフェースbond0とIPの設定
(17)ens4とens5をBond0にアサイン
(18)VLANインターフェースbond0.301とIPの設定
出力結果 [root@c753 ~]# nmcli con show NAME UUID TYPE DEVICE bond-slave-ens4 461a812f-bb8f-4046-84bb-e1e9df598a76 ethernet ens4 bond-slave-ens5 62bd54a3-bb07-4c0a-8ca4-ed7d3ea236b7 ethernet ens5 bond0 9962c767-59ff-41bf-b8ed-097061f6016c bond bond0 bond0.301 44296f6c-a9b3-4435-be5e-541a0fd5e4b9 vlan bond0.301 eth0 2c180c0c-76b3-4f05-b04e-546812f51811 ethernet eth0 virbr0 42ae0bd5-a46a-4e7c-8038-8711ae2aab4d bridge virbr0 [root@c753 ~]# ip add show 2: ens4: <\BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master bond0 state UP group default qlen 1000 link/ether 16:27:f0:0c:e1:4b brd ff:ff:ff:ff:ff:ff 3: ens5: <\BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master bond0 state UP group default qlen 1000 link/ether 16:27:f0:0c:e1:4b brd ff:ff:ff:ff:ff:ff 9: bond0:mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 16:27:f0:0c:e1:4b brd ff:ff:ff:ff:ff:ff inet 192.168.30.223/24 brd 192.168.30.255 scope global noprefixroute bond0 valid_lft forever preferred_lft forever 10: bond0.301@bond0: mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 16:27:f0:0c:e1:4b brd ff:ff:ff:ff:ff:ff inet 192.168.31.223/24 brd 192.168.31.255 scope global noprefixroute bond0.301 valid_lft forever preferred_lft forever [root@c753 ~]#
6.lxc754のBonding&VLAN+IP
コンテナ起動前にVFを仮想マシンにアタッチします。
ホストOS上で以下のように設定してください。*3
# lxc config device add lxc754 eth1 nic nictype=sriov parent=ens1f0 Device eth1 added to lxc754 # lxc config device add lxc754 eth2 nic nictype=sriov parent=ens1f1 Device eth2 added to lxc754
上記設定が完了した後、コンテナを起動して以下の設定をコンテナ上で行ってください。
また、コンテナ上で事前にyum -y install NetworkManagerを実施しておいてください。
BondingとVLANインターフェースを作成します。
(19)Bondingインターフェースbond0とIPの設定
(20)eth1とeth2をBond0にアサイン
(21)VLANインターフェースbond0.301とIPの設定
出力結果 c753とほぼ同一のため省略 異なる点は、IPアドレスの第4オクテットが224となります。
8.補足1:SR-IOVを使用する場合の注意点
以下3つの注意点があります。
先に結論だけ書きますと、以下の通りとしてください。
8-1.VFのMACアドレスについて
VFのMACアドレスは固定設定とせずに、オール0(ゼロ)のままの状態にしておいてください。
通常、VFのMACアドレスを明示的に固定設定とする場合、/etc/rc.localに以下のように記載しますが、全てコメントアウトしてください。
# vi /etc/rc.local
echo 2 > /sys/class/net/ens1f0/device/sriov_numvfs
echo 2 > /sys/class/net/ens1f1/device/sriov_numvfs
sleep 1
#ip link set ens1f0 vf 0 mac 00:11:22:33:44:55
#ip link set ens1f0 vf 1 mac 00:11:22:33:44:56
#ip link set ens1f1 vf 0 mac 00:11:22:33:44:57
#ip link set ens1f1 vf 1 mac 00:11:22:33:44:58
sleep 1
ip link set ens1f0 vf 0 spoofchk off
ip link set ens1f0 vf 1 spoofchk off
ip link set ens1f1 vf 0 spoofchk off
ip link set ens1f1 vf 1 spoofchk off
exit 0
8-2.BlackListについて
BlackListを使用した場合、LXC/LXDでVFをコンテナにアタッチしようする際、エラーで弾かれます。
このため、BlackListからixgbevfはコメントアウト、または削除してください。*5
# vi /lib/modprobe.d/dist-blacklist.conf # # Listing a module here prevents the hotplug scripts from loading it. # Usually that'd be so that some other driver will bind it instead, # no matter which driver happens to get probed first. Sometimes user # mode tools can also control driver binding. # # Syntax: see modprobe.conf(5). # # watchdog drivers blacklist i8xx_tco # framebuffer drivers blacklist aty128fb blacklist atyfb blacklist radeonfb blacklist i810fb blacklist cirrusfb blacklist intelfb blacklist kyrofb blacklist i2c-matroxfb blacklist hgafb blacklist nvidiafb blacklist rivafb blacklist savagefb blacklist sstfb blacklist neofb blacklist tridentfb blacklist tdfxfb blacklist virgefb blacklist vga16fb blacklist viafb # ISDN - see bugs 154799, 159068 blacklist hisax blacklist hisax_fcpcipnp # sound drivers blacklist snd-pcsp # I/O dynamic configuration support for s390x (bz #563228) blacklist chsc_sch # crypto algorithms blacklist sha1-mb # ixgbevf driver #blacklist ixgbevf
9.補足2:内部ネットワーク的な疎通可否
全体構成図を見ながら、以下のマトリックスを見てください。
VLAN300:192.168.30.0/24
VLAN301:192.168.31.0/24
今回は(11)~(21)にIPアドレスをアサインしました。
そこからPing疎通できた箇所にはRTTを記載しました。*6
Ping疎通できなかった箇所はNGと記載しています。
上記の表より、疎通NGだった箇所*7について記載したいと思います。
9-1.VLAN300:192.168.30.0/24の表について
以下2つのフローが疎通NGでした。
- Src:(13), Dst:(16)
- Src:(13), Dst:(19)
PF(ens1f0)⇔VF間におけるEtherフレームの受け渡しがうまくいっていないようでした。
ens1f0でPcapした結果、(13)→(16)、(13)→(19)のarpは確認できたものの、戻りのarp replayが見えず。
一方、c753のens4&5でPcapした結果、(13)→(16)へのarp受信後、(16)→(13)へのarp replayを返送していました。
このため、ens1f0での戻りのarp replayが見えない点が怪しいものの解決に至らず。。。
9-2.VLAN301:192.168.31.0/24の表について
以下2つのフローが疎通NGでしたが、疎通不可な理由は9-1に記載した事象と同一です。
- Src:(15), Dst:(18)
- Src:(15), Dst:(21)
以下の通信が全滅でした。
- Src:(14), Dst:ALL
原因は、戻りのEtherフレームにVLAN301のタグが付いていることにより、(3)から(9)へ転送されてしまうためです。
実際、(9)や(15)でPcapしたところ、(14)宛てのVLANタグ付きフレームが受信できました。
9-3.RTTから見えてくるもの
宛先がSWになっているRTTを見てください。概ね1~2ms程度です。
また、自分自身にPingを打った場合のRTTは、おおむね100μs(0.100ms)以下となっています。
それ以外のRTTは概ね900~200μs(0.9~0.2ms)程度です。
Bridgeを使用したインターフェースのRTTと比較して、SR-IOVを使用したインターフェースのRTTは全体的に短時間(500μs程度)となっています。
加えて、SR-IOVを使用した者同士のRTTはさらに短時間(200~300μs程度)となっています。
10.補足3:KVMによるVF自動アサイン設定
「6.lxc754のBonding&VLAN+IP」に記載したアタッチ方法の場合、VFを自動的にアサインしてくれますが、今回紹介したKVMでの方法は手動設定を行いました。
理由は、KVMによるVF自動アサインを行った結果、(16)(17)を作成した際にens5がLinkUpしなかったためです。
但し、仮想マシン上でBondingしない場合は有用な設定方法だと思いますので、補足として記載しておきます。
10-1.定義ファイルの作成
以下のようにxmlの定義ファイルを作成し、virshコマンドで定義ファイルを読み込ませます。
# cat > sriov_ens1f0.xml << EOF <network> <name>sriov_ens1f0 <forward mode='hostdev' managed='yes'> <pf dev='ens1f0'/> </forward> </network> EOF # virsh net-define sriov_ens1f0.xml
10-2.Virt-Manager上での設定
以下の画面にて、Edit→Connection Detailsを選択
以下の画面にて、Autostartにチェックを入れApplyをクリック。
左下の再生ボタン*8をクリック。
以下の画面にて、AddHardwareより、「Virtual Network 'sriov_ens1f0' : Hostdev network」を選択することができるようになります。
これにより、ens1f0から自動的にVFがアサインされるようになります。
1つのPF上でVFを8個や16個など作成した場合には管理が煩雑となるため、どのVFを使用しているかを意識せずに設定することが可能となります。
以上です。
10.最後に
LinuxBridge*9とSR-IOVを駆使したネットワーク構成としては、概ね網羅できたと思います。
次のステップとしては、Open vSwitchによる分散仮想スイッチ*10の構成になると考えています。
さらに、パフォーマンス面ではDPDKを使用する*11ことに加え、足回りを全てSR-IOVにすることにより、ようやく最下層における基礎/基盤の部分が構成できるようになります。
その上で、あるホストから別のホストへトラフィック*12を転送する際に、MPLSやVxLANでトラフィックを識別し、対向スイッチ上では、MP-BGPやEVPNを使用することにより、Overlayネットワークが構成できるようになります。
SDN/NFVという言葉だけがあちこちに溢れていますが、最下層の仕組みを理解せずに上物だけをやってしまうのは、とても怖い気がしています。
*1:¥(9)にてVLAN301を付与しているためUntagとなります。
*2:厳密には、KVMとLXC/LXDでVFのアタッチ方法が異なります。詳しくは補足に記載します。
*3:補足で解説しますが、LXC/LXDの場合、PF=ens1f0やens1f1を指定するだけで、自動的に空いているVFをアタッチしてくれます。
*4:見かけ上の設定では上手くいったように見えますが、IP疎通性が無くなる場合があります。また、BondingインターフェースのSlaveのうちの一つがLinkUpしてくれないといった状態になります。
*5:つまり、ホストOS上でixgbevfがmodprobeされる状態にしておいてください。
*6:送信元:スイッチに関しては、min/avg/maxRTTの表記となっています。
*7:一部考察も含みます
*8:+ボタンの右隣になる横三角のボタン
*9:仮想スイッチのことです
*10:VMWareでいうところのvDistributionSwitch
*11:所謂、OvS-DPDKのことです