第521回でのLXD 3.
SR-IOV
SR-IOV (Single Root I/
ハードウェア側でデバイスを仮想的に分割するため、
とても魅力的な機能ですが、
基本的なSR-IOVデバイスの利用方法
まずはSR-IOVがどのようなものか簡単に試してみましょう。少し古いPCIeデバイスですが、
lspci
コマンドでマシン上のPCIgrep
してみましょう。
$ lspci | grep 82599 04:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) 04:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
X520-DA2はSFP+ポートを2ポート持ちます。上記では各ポートがそれぞれ表示されています。続いてip
コマンドでネットワークインタフェースを見てみましょう。
$ ip address (略) 4: enp4s0f0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 00:1b:21:bc:04:a2 brd ff:ff:ff:ff:ff:ff 5: enp4s0f1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 00:1b:21:bc:04:a3 brd ff:ff:ff:ff:ff:ff
ネットワークインタフェース名は環境によって異なり、enp4s0f0
、enp4s0f1
となっています。
SR-IOV対応のPCIeデバイスにおいて、
IntelのSR-IOV対応10GbEカードを使用する場合は、enp4s0f0
を親とします。
$ sudo ip link set dev enp4s0f0 up
Physical FunctionのstateがUPになっていることを確認します。
$ ip address show enp4s0f0 4: enp4s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:1b:21:bc:04:a2 brd ff:ff:ff:ff:ff:ff inet6 fe80::21b:21ff:febc:4a2/64 scope link valid_lft forever preferred_lft forever
Virtual Functionを作成します。Ubuntuを含む、
/sys/class/net/ネットワークインタフェース名/device/sriov_numvfs
筆者の環境では、/sys/
になります。
$ ls -l /sys/class/net/enp4s0f0/device/sriov_numvfs -rw-rw-r-- 1 root root 4096 Sep 22 19:39 /sys/class/net/enp4s0f0/device/sriov_numvfs $ cat /sys/class/net/enp4s0f0/device/sriov_numvfs 0
このsriov_
ファイルにroot権で数字を書き込むことで、2
を書き込んでVirtual Functionを2個作ってみましょう。
$ sudo sh -c 'echo 2 > /sys/class/net/enp4s0f0/device/sriov_numvfs'
lspci
コマンドでPCIeデバイス情報を見てみましょう。
$ lspci | grep 82599 04:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) 04:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) 04:10.0 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01) 04:10.2 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
「Intel Corporation 82599 Ethernet Controller Virtual Function」
$ ip address (略) 4: enp4s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:1b:21:bc:04:a2 brd ff:ff:ff:ff:ff:ff inet6 fe80::21b:21ff:febc:4a2/64 scope link valid_lft forever preferred_lft forever 5: enp4s0f1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 00:1b:21:bc:04:a3 brd ff:ff:ff:ff:ff:ff 6: enp4s16: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 62:b5:c8:8f:2b:ce brd ff:ff:ff:ff:ff:ff 7: enp4s16f2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 86:92:1a:8a:a6:f1 brd ff:ff:ff:ff:ff:ff
enp4s16
、enp4s16f2
の2つのネットワークインタフェースが作成されています。この内のenp4s16
にIPアドレス172.
を設定してみましょう。
$ sudo ip address add 172.16.1.20/24 dev enp4s16 $ sudo ip link set dev enp4s16 up $ ip address show enp4s16 6: enp4s16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 62:b5:c8:8f:2b:ce brd ff:ff:ff:ff:ff:ff inet 172.16.1.20/24 scope global enp4s16 valid_lft forever preferred_lft forever inet6 fe80::60b5:c8ff:fe8f:2bce/64 scope link valid_lft forever preferred_lft forever
10GbEのネットワークの対向に位置するIPアドレス172.
のマシンと通信してみましょう
$ ping -c 4 172.16.1.11 PING 172.16.1.11 (172.16.1.11) 56(84) bytes of data. 64 bytes from 172.16.1.11: icmp_seq=1 ttl=64 time=0.323 ms 64 bytes from 172.16.1.11: icmp_seq=2 ttl=64 time=0.197 ms 64 bytes from 172.16.1.11: icmp_seq=3 ttl=64 time=0.133 ms 64 bytes from 172.16.1.11: icmp_seq=4 ttl=64 time=0.198 ms --- 172.16.1.11 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3049ms rtt min/avg/max/mdev = 0.133/0.212/0.323/0.071 ms
通信できていますね。
ホストマシンからVirtual Functionを削除する場合は、sriov_
ファイルに0
を書き込みます。
$ sudo sh -c 'echo 0 > /sys/class/net/enp4s0f0/device/sriov_numvfs'
コンテナからSR-IOVデバイスを利用する
今度はLXDからSR-IOV対応のネットワークデバイスを利用してみましょう。こちらもIntel 10GbEカードを使用する環境では事前に親Physical Functionをインタフェースアップしておきます
$ sudo ip link set dev enp4s0f0 up
lxc config device add
コマンドでコンテナにnic
デバイスを追加します。この際、nictype=sriov
を指定することで、
$ lxc config device add コンテナ名 設定名 nic nictype=sriov parent=親Physical Function名
各項目の詳しい説明はUbuntu weekly recipeの535回、
nictype=sriov
を指定する場合、parent=
に親となるPhysical Functionを指定します。LXDがこのPhysical Functionを調べ、
parent=
にSR-IOV未対応のネットワークインタフェースを指定した場合や、lxc
コマンドがエラーを返します。
実際に試してみましょう。この例ではubuntu:18.nadeshiko
という名前でコンテナを作成、
$ lxc launch ubuntu:18.04 nadeshiko Creating nadeshiko Starting nadeshiko $ lxc list -c ns4 +-----------+---------+----------------------+ | NAME | STATE | IPV4 | +-----------+---------+----------------------+ | nadeshiko | RUNNING | 10.150.118.16 (eth0) | +-----------+---------+----------------------+
コンテナnadeshiko
にVirtual Functionをネットワークインタフェースeth1
として追加します
$ lxc config device add nadeshiko eth1 nic nictype=sriov parent=enp4s0f0 Device eth1 added to nadeshiko
コンテナnadeshiko
内でip
コマンドを実行して確認してみましょうlxc exec
コマンド経由で実行しています。
$ lxc exec nadeshiko ip address show eth1 12: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 00:16:3e:b5:3e:cb brd ff:ff:ff:ff:ff:ff
コンテナnadeshiko
のeth1
にIPアドレス172.
を設定し、
$ lxc exec nadeshiko ip address add 172.16.1.12/24 dev eth1 $ lxc exec nadeshiko ip link set dev eth1 up $ lxc exec nadeshiko ip address show eth1 12: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:16:3e:b5:3e:cb brd ff:ff:ff:ff:ff:ff inet 172.16.1.12/24 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::216:3eff:feb5:3ecb/64 scope link valid_lft forever preferred_lft forever
lxc list
コマンドでもnadeshiko
のeth1
にIPアドレスが振られていることが確認できます。
$ lxc list -c ns4 +-----------+---------+----------------------+ | NAME | STATE | IPV4 | +-----------+---------+----------------------+ | nadeshiko | RUNNING | 172.16.1.12 (eth1) | | | | 10.150.118.16 (eth0) | +-----------+---------+----------------------+
対向のIPアドレス172.
のマシンと通信してみましょう。
$ lxc exec nadeshiko -- ping -c 4 172.16.1.11 PING 172.16.1.11 (172.16.1.11) 56(84) bytes of data. 64 bytes from 172.16.1.11: icmp_seq=1 ttl=64 time=0.222 ms 64 bytes from 172.16.1.11: icmp_seq=2 ttl=64 time=0.126 ms 64 bytes from 172.16.1.11: icmp_seq=3 ttl=64 time=0.127 ms 64 bytes from 172.16.1.11: icmp_seq=4 ttl=64 time=0.180 ms --- 172.16.1.11 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3053ms rtt min/avg/max/mdev = 0.126/0.163/0.222/0.043 ms
コンテナnadeshiko
と対向のマシンにネットワークスループット計測用ソフトウェアのiperf3
をインストールし、
$ lxc exec nadeshiko -- iperf3 -c 172.16.1.11 -i 0 Connecting to host 172.16.1.11, port 5201 [ 5] local 172.16.1.12 port 51452 connected to 172.16.1.11 port 5201 [ ID] Interval Transfer Bandwidth Retr Cwnd [ 5] 0.00-10.00 sec 11.0 GBytes 9.42 Gbits/sec 11 925 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Retr [ 5] 0.00-10.00 sec 11.0 GBytes 9.42 Gbits/sec 11 sender [ 5] 0.00-10.00 sec 11.0 GBytes 9.41 Gbits/sec receiver iperf Done.
Bandwidthの値をみると9.
複数のコンテナでSR-IOVデバイスを利用する
もう一台コンテナを作成して、enp4s0f0
を親に持つ別のVirtual Functionを割り当ててみましょう。コンテナ名はshimarin
とします。
$ lxc launch ubuntu:18.04 shimarin Creating shimarin Starting shimarin $ lxc config device add shimarin eth1 nic nictype=sriov parent=enp4s0f0 Device eth1 added to shimarin
コマンドはnadeshiko
にeth1
を割り当てた時とコンテナ名が異なるだけです。LXDが未使用のVirtual Functionを選んでコンテナに割り当てるため、
コンテナshimarin
のeth1
にはIPアドレス172.
を設定します。
$ lxc exec shimarin ip address add 172.16.1.13/24 dev eth1 $ lxc exec shimarin ip link set dev eth1 up $ lxc list -c ns4 +-----------+---------+-----------------------+ | NAME | STATE | IPV4 | +-----------+---------+-----------------------+ | nadeshiko | RUNNING | 172.16.1.12 (eth1) | | | | 10.150.118.16 (eth0) | +-----------+---------+-----------------------+ | shimarin | RUNNING | 172.16.1.13 (eth1) | | | | 10.150.118.237 (eth0) | +-----------+---------+-----------------------+
shimarin
にもiperf3
をインストールし、nadeshiko
とshimarin
の2台で対向のIPアドレス 172.
のマシン間のスループットを計測してみましょう。対向のマシンではサーバーモードのiperf3
を2プロセス、nadeshiko
からポート5201宛に、shimarin
からポート5202宛に、iperf3
のクライアントモードで同時に接続します。実行タイミングがずれると正確な転送スピードが測れないため、systemd-run
コマンドを使用してホスト上のsystemdiperf3
を実行してみます。
$ systemd-run --user --timer-property=AccuracySec=1s --on-calendar='2018-09-25 22:55:00 JST' \ lxc exec nadeshiko -- /bin/sh -c 'iperf3 -c 172.16.1.11 -i 0 -p 5201 > nadeshiko.iperf3.txt' $ systemd-run --user --timer-property=AccuracySec=1s --on-calendar='2018-09-25 22:55:00 JST' \ lxc exec shimarin -- /bin/sh -c 'iperf3 -c 172.16.1.11 -i 0 -p 5202 > shimarin.iperf3.txt'
--user --timer-property=AccuracySec=1s --on-calendar=
までがsytemd.--user
でユーザー権限での登録、--timer-property=AccuracySec=1s
でタイマー精度を1秒に指定--on-calendar='2018-09-25 22:55:00 JST'
でコマンドの実行開始時刻を指定しています。lxc exec
以降が各コンテナ内でのiperf3
実行部分です。コンテナ内でiperf3
の出力をファイルにリダイレクトする都合上、/bin/
コマンドの-c
オプションでシェルプロセスとして実行しています。
指定した実行開始時刻になると、lxc exec
コマンドが実行されます。実行終了まで待って結果を見てみましょう。
コンテナnadeshiko
の実行結果です。
$ lxc exec nadeshiko -- ls -l nadeshiko.iperf3.txt -rw-r--r-- 1 root root 534 Sep 25 22:55 nadeshiko.iperf3.txt $ lxc exec nadeshiko -- cat nadeshiko.iperf3.txt Connecting to host 172.16.1.11, port 5201 [ 5] local 172.16.1.12 port 48584 connected to 172.16.1.11 port 5201 [ ID] Interval Transfer Bandwidth Retr Cwnd [ 5] 0.00-10.00 sec 5.48 GBytes 4.71 Gbits/sec 17 714 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Retr [ 5] 0.00-10.00 sec 5.48 GBytes 4.71 Gbits/sec 17 sender [ 5] 0.00-10.00 sec 5.48 GBytes 4.71 Gbits/sec receiver iperf Done.
コンテナshimarin
の実行結果です。
$ lxc exec shimarin -- ls -l shimarin.iperf3.txt -rw-r--r-- 1 root root 534 Sep 25 22:55 shimarin.iperf3.txt $ lxc exec shimarin -- cat shimarin.iperf3.txt Connecting to host 172.16.1.11, port 5202 [ 5] local 172.16.1.13 port 34928 connected to 172.16.1.11 port 5202 [ ID] Interval Transfer Bandwidth Retr Cwnd [ 5] 0.00-10.00 sec 5.49 GBytes 4.71 Gbits/sec 2 691 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Retr [ 5] 0.00-10.00 sec 5.49 GBytes 4.71 Gbits/sec 2 sender [ 5] 0.00-10.00 sec 5.48 GBytes 4.71 Gbits/sec receiver iperf Done.
nadeshiko
とshimarin
のどちらも4.
コンテナからSR-IOVデバイスを削除する
コンテナからSR-IOVデバイスを削除する方法は、
$ lxc config device remove shimarin eth1 Device eth1 removed from shimarin
nictype=sriov
のデバイスを削除すると、