MS-01で遊んでみた 2 PCIパススルーして負荷試験(MS-01/ESXi/Almalinux/iperf)

はじめに

PCIパススルーという仕組みを使ってみました。

これはどんな機能かというと、仮想マシンから物理的なPCIデバイスに直接接続する仕組みです。具体的にいうと、仮想マシンからインターネットなどに通信する際に
 ・通常:仮想マシン→仮想スイッチ→物理NIC→インターネット等
 ・PCIパススルー有り:仮想マシン→物理NIC→インターネット等
となります。
PCIパススルーを使うと、仮想スイッチを経由しなくなるため、物理NICに出ていく通信のCPU使用率の減少が見込まれます。

っていうなんだかすごそうな機能なのでiperfで10Gbpsの負荷をかけた際のCPU使用率をPCIパススルーありとなしで比較しました。

構成

LANケーブルが4本ささるPC 1台に、仮想マシンを2台作りました。
図は下記の通りで、vmkernelは省略しています。

vmk0など一部の構成は省略しています

一番右のポートを家のNWに接続。このポートから各仮想マシンやESXiにログインします。
左の2つのポート(SFP+の10Gbpsポート)を直結。それぞれを仮想マシンにPCIパススルーで認識させて、SFPポート経由で仮想マシンの通信をできるようにします。つまり、赤矢印の通信を実現して10Gbps出します。

構築

仮想マシンを構築する部分は省略し、ALMA-LOAD-001、ALMA-LOAD-002に設定を投入していくところから記載します。
Almalinuxで作った負荷試験(loading test)用のサーバという意味。この記事内のコマンドはこれらのサーバで動かしてます)

SSH有効化

※rootの許可はしない方がよさそうだが、自宅ラボなので…

vi /etc/ssh/sshd_config

40行目を下記に変更
PermitRootLogin yes

service sshd restart

IFの設定

# IFの確認とルーティング確認
nmcli connection
nmcli device show
ip address show
ip route show


# IPv4の設定
nmcli con mod ens34 ipv4.addresses 192.168.11.52/24
nmcli con mod ens34 ipv4.gateway 192.168.11.1
nmcli con mod ens34 +ipv4.dns 8.8.8.8
nmcli con mod ens34 +ipv4.dns 8.8.4.4
nmcli con mod ens34 ipv4.method manual
nmcli con mod ens34 connection.autoconnect yes
nmcli con down ens34; nmcli con up ens34;


# IPv6の無効化
nmcli con mod ens34 ipv6.method ignore
grubby --update-kernel ALL --args ipv6.disable=1
grubby --info DEFAULT
reboot

設定後のIFの状態

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
2: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:5a:b5:00 brd ff:ff:ff:ff:ff:ff
    altname enp2s2
    inet 192.168.11.52/24 brd 192.168.11.255 scope global noprefixroute ens34
       valid_lft forever preferred_lft forever

PCIデバイス確認

ALMA-LOAD-001、ALMA-LOAD-002がSFP+の10GbpsのNICを認識している必要があります。なのでlspciで確認します。

# lspciを使えるようにする
yum install -y pciutils


# lspciでPCIデバイス確認
[root@localhost ~]# lspci
00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (rev 01)
00:01.0 PCI bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge (rev 01)
00:07.0 ISA bridge: Intel Corporation 82371AB/EB/MB PIIX4 ISA (rev 08)
00:07.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)
00:07.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08)
00:07.7 System peripheral: VMware Virtual Machine Communication Interface (rev 10)
00:0f.0 VGA compatible controller: VMware SVGA II Adapter
02:00.0 Serial Attached SCSI controller: VMware PVSCSI SCSI Controller (rev 02)
02:01.0 USB controller: VMware USB1.1 UHCI Controller
02:02.0 Ethernet controller: VMware VMXNET3 Ethernet Controller (rev 01)
02:03.0 USB controller: VMware USB2 EHCI Controller
02:04.0 SATA controller: VMware SATA AHCI controller

パススルーをアクティブにしているのに、0000:02:00.0と0000:02:00.0が出てこない。(チェックを入れた後に「パススルーの切り替え」を押下したらアクティブになります)

仮想マシンの「編集」→「その他のデバイスの追加」→新規PCIデバイスに対象のPCIデバイスを追加 かつ、メモリの固定割り当て(「すべてのゲスト メモリを予約」にチェック)が必要

無事表示されました。

[root@localhost ~]# lspci | grep Ethernet
02:02.0 Ethernet controller: VMware VMXNET3 Ethernet Controller (rev 01)
02:05.0 Ethernet controller: Intel Corporation Ethernet Controller X710 for 10GbE SFP+ (rev 02)

IFの確認

最初と比較して、ens37が追加されました。

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
2: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:5a:b5:00 brd ff:ff:ff:ff:ff:ff
    altname enp2s2
    inet 192.168.11.52/24 brd 192.168.11.255 scope global noprefixroute ens34
       valid_lft forever preferred_lft forever
3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 58:47:ca:78:e6:6f brd ff:ff:ff:ff:ff:ff

ethtoolを確認。speedが10000Mb/s(=10Gbps)と分かる

[root@localhost ~]# ethtool ens37
Settings for ens37:
        Supported ports: [ FIBRE ]
        Supported link modes:   10000baseT/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: No
        Supported FEC modes: Not reported
        Advertised link modes:  10000baseT/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 10000Mb/s
        Duplex: Full
        Auto-negotiation: off
        Port: Direct Attach Copper
        PHYAD: 0
        Transceiver: internal
        Supports Wake-on: g
        Wake-on: g
        Current message level: 0x00000007 (7)
                               drv probe link
        Link detected: yes

パススルーしたIFの設定

nmcli で ens37 が認識されない

ipv4のアドレスを設定しようと思ったらエラーが


[root@localhost ~]# nmcli con mod ens37 ipv4.address 172.16.37.1/24
Error: unknown connection 'ens37'.
[root@localhost ~]#

nmcliでデバイスを確認

"Wired connection 1"という名前になっている

[root@localhost ~]# nmcli connection
NAME                UUID                                  TYPE      DEVICE
ens34               4fdbe3e9-419e-3fa5-8acd-ad3fedf0bffb  ethernet  ens34
lo                  94691b82-57a0-4ff0-b402-7d83b8d87853  loopback  lo
Wired connection 1  cb81f911-8a04-3da2-956a-0864d8c11ae5  ethernet  --

名前を ens37 → Wired connection 1に変更して設定

エラーは出ない

nmcli con mod 'Wired connection 1' ipv4.addresses 172.16.37.1/24;
nmcli con mod 'Wired connection 1' ipv4.method manual;
nmcli con mod 'Wired connection 1' connection.autoconnect yes;
nmcli con down 'Wired connection 1'; nmcli con up 'Wired connection 1';

IFの状態確認

設定できた

[root@localhost ~]# ip address show ens37
3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 58:47:ca:78:e6:6f brd ff:ff:ff:ff:ff:ff
    altname enp2s5
    inet 172.16.37.1/24 brd 172.16.37.255 scope global noprefixroute ens37
       valid_lft forever preferred_lft forever

ルーティング確認

想定通り

[root@localhost ~]# ip route show
default via 192.168.11.1 dev ens34 proto static metric 100
172.16.37.0/24 dev ens37 proto kernel scope link src 172.16.37.1 metric 101
192.168.11.0/24 dev ens34 proto kernel scope link src 192.168.11.52 metric 100


負荷試験

iperfのインストール

yum install -y iperf3

firewallの停止

systemctl stop firewalld
systemctl disable firewalld

負荷試験(サーバ側)

[root@localhost ~]# iperf3 -s
warning: this system does not seem to support IPv6 - trying IPv4
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 172.16.37.1, port 34368
[  5] local 172.16.37.2 port 5201 connected to 172.16.37.1 port 34376
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  1.05 GBytes  9.03 Gbits/sec
[  5]   1.00-2.00   sec  1.10 GBytes  9.41 Gbits/sec
[  5]   2.00-3.00   sec  1.10 GBytes  9.41 Gbits/sec
[  5]   3.00-4.00   sec  1.10 GBytes  9.41 Gbits/sec
[  5]   4.00-5.00   sec  1.10 GBytes  9.41 Gbits/sec
[  5]   5.00-6.00   sec  1.10 GBytes  9.41 Gbits/sec
[  5]   6.00-7.00   sec  1.10 GBytes  9.41 Gbits/sec
[  5]   7.00-8.00   sec  1.10 GBytes  9.41 Gbits/sec
[  5]   8.00-9.00   sec  1.10 GBytes  9.41 Gbits/sec
[  5]   9.00-10.00  sec  1.10 GBytes  9.41 Gbits/sec
[  5]  10.00-10.04  sec  45.7 MBytes  9.40 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.04  sec  11.0 GBytes  9.38 Gbits/sec                  receiver
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

負荷試験(クライアント側)

[root@localhost ~]# iperf3 -c 172.16.37.2
Connecting to host 172.16.37.2, port 5201
[  5] local 172.16.37.1 port 34376 connected to 172.16.37.2 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  1.10 GBytes  9.44 Gbits/sec    0   1.33 MBytes
[  5]   1.00-2.00   sec  1.10 GBytes  9.42 Gbits/sec   44   1.03 MBytes
[  5]   2.00-3.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.31 MBytes
[  5]   3.00-4.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.31 MBytes
[  5]   4.00-5.00   sec  1.09 GBytes  9.41 Gbits/sec    0   1.31 MBytes
[  5]   5.00-6.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.32 MBytes
[  5]   6.00-7.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.35 MBytes
[  5]   7.00-8.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.35 MBytes
[  5]   8.00-9.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.40 MBytes
[  5]   9.00-10.00  sec  1.10 GBytes  9.42 Gbits/sec    0   1.40 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  11.0 GBytes  9.42 Gbits/sec   44             sender
[  5]   0.00-10.04  sec  11.0 GBytes  9.38 Gbits/sec                  receiver

iperf Done.

結果

9.4Gbpsとなった。10Gぴったりにはならないが、パケット長を調整すると帯域(bitrate)が小さくなるので、FCSが換算されないため等が考えられる。

また、CPUはボトルネックにならなかった。(Linuxには1コアのみ割り当て。CPUは12th Gen Intel(R) Core(TM) i5-12600H)
画像は20分程度負荷をかけた際の仮想マシンのリソースをESXiで見たもの。サーバ側はCPUは55~60%程度、メモリは100%使われている。メモリが100%なのは、「すべてのゲスト メモリを予約」にチェックを入れて、割り当てた2GBのメモリを占有しているためと思われる。

サーバ側

クライアント側

ESXiのパフォーマンスを見ると、使うCPUを順繰り入れ替えていて、MAXでも55%程度になっているように見える。

おまけ:ショートパケットのときの結果

MSSを100にしてショートパケットで試験をしたら1.4Gbps程度しか出なくなった。

[root@localhost ~]# iperf3 -t 1800 -c 172.16.37.2 -b 10000M -M 100 --get-server-output
Connecting to host 172.16.37.2, port 5201
[  5] local 172.16.37.1 port 60740 connected to 172.16.37.2 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   181 MBytes  1.52 Gbits/sec  619   26.3 KBytes
[  5]   1.00-2.00   sec   170 MBytes  1.43 Gbits/sec  578   62.8 KBytes
[  5]   2.00-3.00   sec   170 MBytes  1.43 Gbits/sec  620   27.3 KBytes
[  5]   3.00-4.00   sec   172 MBytes  1.44 Gbits/sec  460   29.6 KBytes
[  5]   4.00-5.00   sec   163 MBytes  1.37 Gbits/sec  489   36.5 KBytes
[  5]   5.00-6.00   sec   170 MBytes  1.43 Gbits/sec  457   57.5 KBytes

送信側のCPU使用率は70%程度。


PCIパススルー無しだとどうなるか

構成

下記のように変更。
PCIパススルーは廃止。vSwitch経由で通信。

iperfのログ

帯域はPCIパススルー有りのときと同様、9.4Gbps出る。

[root@localhost ~]# iperf3 -c 172.16.37.2 -t 1000
Connecting to host 172.16.37.2, port 5201
[  5] local 172.16.37.1 port 34790 connected to 172.16.37.2 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  1.10 GBytes  9.43 Gbits/sec    0   1.32 MBytes
[  5]   1.00-2.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.45 MBytes
[  5]   2.00-3.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.45 MBytes
[  5]   3.00-4.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.61 MBytes
[  5]   4.00-5.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.61 MBytes
[  5]   5.00-6.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.61 MBytes
[  5]   6.00-7.00   sec  1.10 GBytes  9.41 Gbits/sec    0   1.61 MBytes
[  5]   7.00-8.00   sec  1.09 GBytes  9.41 Gbits/sec    0   1.61 MBytes
[  5]   8.00-9.00   sec  1.10 GBytes  9.42 Gbits/sec    0   1.61 MBytes
[  5]   9.00-10.00  sec  1.10 GBytes  9.42 Gbits/sec    0   1.61 MBytes

CPU使用率

一目瞭然で使用率が上がった
上の画像は送信側のAlmalinux。下の画像はCPU全体。
上の画像のメモリが減っているのは、PCIデバイスの割り当てをやめた際にメモリの固定割り当てをやめたため。

おわりに

同じ条件(iperfでパケット長指定なしで9.4Gbps程度の実測地)で比較すると、
 PCIパススルー有り:CPU使用率は55%程度
 PCIパススルー無し:CPU使用率は100%程度
となりました。


次回はSR-IOVを触ってみます。

いいなと思ったら応援しよう!