CentOS7上に3台の仮想マシン(CentOS)を稼働させつつDPDKとpktgenをインストールして10Gワイヤーレートが出るパケットジェネレータを作成しました。
1.環境
1-1.母体(ホストOS)
筐体 : ProLiant DL360p Gen8 System ROM : P71 01/22/2018 CPU : Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz NIC : Intel X520-SR2(82599ES) OS : CentOS7.4(1708) Kernel : kernel-3.10.0-693.el7.x86_64 Installed Environment Groups : Server with GUI Add-Ons for Selected Environment : Virtualization Client, Virtualization Hypervisor, Virtualization Tools
1-2.仮想マシン(ゲストOS)
筐体 : 下記参照 System ROM : 下記参照 CPU : 下記参照 NIC : Intel X520-SR2(82599ES) OS : CentOS7.4(1708) Kernel : kernel-3.10.0-693.el7.x86_64 Installed Environment Groups : Server with GUI Add-Ons for Selected Environment : Virtualization Client, Virtualization Hypervisor, Virtualization Tools , Development Tools
筐体、System ROMはホストOSにインストールされているqemu-kvmをそのまま使用。
yum updateやupgradeは未実施。
CPUはNestedKVMを有効化しているため、ホストOSと同一 。
ゲストOSはDPDKやpktgenのビルドが必須なため、Development Toolsを加えています。
1-3.全体の流れ
ホストOSでNestedKVM, SR-IOV, VFIOの設定
ゲストOSでHugePage & IOMMU, VFIOの設定
ゲストOSでDPDKのインストール, igb_uioの設定
ゲストOSでpktgenのインストール
ゲストOS×3台使った負荷試験
2.ホストOSの設定
2-1.NestedKVMの設定
ゲストOS3台の名前はc741, c742, c743とします。
ファイルを新規作成 vi /etc/modprobe.d/kvm-nested.conf 以下を追記して保存。 options kvm_intel nested=1 再読み込み modprobe -r kvm_intel modprobe kvm_intel ゲストOS作成後、以下のようにvirshにて設定 virsh edit c741 <cpu mode='custom' match='exact'> の行を <cpu mode='host-passthrough'> に変更して保存。
2-2.SR-IOVの設定*1
grubにiommuの設定追加
vi /etc/default/grub GRUB_CMDLINE_LINUX=の行末に追加 intel_iommu=on iommu=pt pci=realloc 保存後、grubに反映 grub2-mkconfig -o /etc/grub2.cfg
起動時にVFが作成されるようrc.localの設定
vi /etc/rc.local 最下行に追加 echo 4 > /sys/class/net/ens1f0/device/sriov_numvfs echo 4 > /sys/class/net/ens1f1/device/sriov_numvfs sleep 1 ip link set ens1f0 vf 0 mac 00:11:22:33:44:50 ip link set ens1f0 vf 1 mac 00:11:22:33:44:51 ip link set ens1f0 vf 2 mac 00:11:22:33:44:52 ip link set ens1f0 vf 3 mac 00:11:22:33:44:53 ip link set ens1f1 vf 0 mac 00:11:22:33:44:60 ip link set ens1f1 vf 1 mac 00:11:22:33:44:61 ip link set ens1f1 vf 2 mac 00:11:22:33:44:62 ip link set ens1f1 vf 3 mac 00:11:22:33:44:63 sleep 1 ip link set ens1f0 vf 0 spoofchk off ip link set ens1f0 vf 1 spoofchk off ip link set ens1f0 vf 2 spoofchk off ip link set ens1f0 vf 3 spoofchk off ip link set ens1f1 vf 0 spoofchk off ip link set ens1f1 vf 1 spoofchk off ip link set ens1f1 vf 2 spoofchk off ip link set ens1f1 vf 3 spoofchk off exit 0 保存後、実行権限を付与 chmod +x /etc/rc.d/rc.local
VFがホストOSに読み込まれないよう設定
vi /lib/modprobe.d/dist-blacklist.conf 最下行に追加 # ixgbevf driver blacklist ixgbevf
2-3.VFIOの設定*2
ファイルを新規作成 vi /etc/modprobe.d/vfio_pci.conf 以下を追記して保存 options vfio_pci ids=8086:10ed こちらも追記 echo 'vfio_pci' > /etc/modules-load.d/vfio_pci.conf 一旦再起動 reboot
8086:10edはlspciで表示されるVFのBus,Slot,Function番号(筐体ごとに異なる)から、lspci -n -s 0008:10.2のようにコマンドを入力することでPCIデバイスのベンダID(8086)とデバイスID(10ed)を確認し、ベンダID(8086)とデバイスID(10ed)をVFIO-PCI driverに登録します。
3.ゲストOSの設定
ゲストOSの設定の前にVirt-Managerなどで仮想マシンを作成してください。
その際、CPUは4コア、Memは8GB以上が理想です。また、管理用IP以外にPCI Host Deviceとして、VFを2つ追加してください。
VF追加は、こんな感じのイメージです。*3
3-1.HugePageとIOMMUの設定
vi /etc/default/grub GRUB_CMDLINE_LINUX=行の最後に以下を追記。 default_hugepagesz=1G hugepagesz=1G hugepages=8 intel_iommu=on iommu=pt grub2-mkconfig -o /boot/grub2/grub.cfg
4.DPDKのインストール
4-1.ソースのDLとビルド
ソースをDLします。 cd /usr/src wget http://fast.dpdk.org/rel/dpdk-17.11.1.tar.gz tar zxvf dpdk-17.11.1.tar.gz cd dpdk-stable-17.11.1 展開したディレクトリでビルドを実施 make install T=x86_64-native-linuxapp-gcc DESTDIR=/usr/local EXTRA_CFLAGS="-O3"
5.pktgenのインストール
5-1.ソースのDLとビルド
ソースをDLします。 cd /usr/src wget http://www.dpdk.org/browse/apps/pktgen-dpdk/snapshot/pktgen-3.5.0.tar.gz tar zxvf pktgen-3.5.0.tar.gz 一旦パスを通す export RTE_SDK=/usr/src/dpdk-stable-17.11.1 export RTE_TARGET=x86_64-native-linuxapp-gcc 展開したディレクトリでビルドを実施 cd pktgen-3.5.0 make
6.負荷試験
6-1.DPDKにバインド
SR-IOVでパススルーされたVFをゲストOSのKernelからDPDK管理下におくためにバインドします。
dpdk-devbind --status Network devices using DPDK-compatible driver ============================================Network devices using kernel driver =================================== 0000:00:07.0 '82599 Ethernet Controller Virtual Function' if=ins2f0 drv=ixgbevf unused=igb_uio,vfio-pci 0000:00:08.0 '82599 Ethernet Controller Virtual Function' if=ins2f1 drv=ixgbevf unused=igb_uio,vfio-pci ~略~ dpdk-devbind -b igb_uio 0000:00:07.0 0000:00:08.0 dpdk-devbind --status
上記バインドを実施することにより、ゲストOS上のカーネルドライバで動作していたVFがDPDKドライバで動作するようになります。バインド後、ゲストOS上でip link showなどを実施しても、ゲストOS上からVFが認識されなくなります(DPDK管理下におかれます)。
6-2.pktgenの起動
ビルドしたディレクトリに移動*4 cd /usr/src/pktgen-3.5.0 移動後のディレクトリ上で、pktgenの起動 app/x86_64-native-linuxapp-gcc/pktgen -- -m "1.0,2.1"
6-3.pktgenで負荷試験実行
pktgenが起動すると以下のような画面となります。
プロンプトが Pktgen:/>となるので、 start all と入力
これを3台のゲストOSで同時に実施し、
行 Pkts /s Max/Tx
列 TotalRate
のフィールドが5Mppsくらいになると、
ワイヤーレート(14.8Mpps)が出てそうな雰囲気になります。
実際にやるとこんな感じです。
1台あたり5Mpps超えてるのがかなり怪しいですが・・・
ホストOS単体では思うようにワイヤーレートが出なかったので、この辺りはもう少しチューニングが必要だと考えています。
以上です。
7.最後に
以下のサイトを参考にさせて頂きました。
みらくるブログ — サイバートラスト株式会社
Getting Started with Pktgen — Pktgen 3.2.4 documentation
私自身もまだまだ勉強不足なため、不要な設定が入っている気がしています。具体的にはホストOSでSR-IOVしているため、ホストOS上のVFIO設定は不要なのでは?といったところです。ホストとゲスト、ユーザ空間とカーネル空間のどこで必要とされている設定なのか?など、一度整理してみないとダメだなと考えています。
*1:詳細は過去記事を参照してください。CentOS7でSR-IOV設定 - Metonymical Deflection
*2:詳細は過去記事を参照してください。CentOS7でvThunderのセットアップ - Metonymical Deflection
*3:画像はX540のものですが、X520でも同様です。
*4:cdした/usr/src/pktgen-3.5.0のディレクトリ上からでないとpktgenが起動しませんでした。make時のパスの通し方がダメな気がしています。要調査