仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

Ubuntu Xenial (16.04) でOpen vSwitch+DPDKな環境を作る(後編)

[2017/7/6 追記] 大幅に内容を書き換えました。

tech.virtualtech.jp

Ubuntu XenialでOpen vSwitch+DPDKな環境を作る(前編) の環境ができたら、次にOpen vSwitch+DPDKをLinux KVM仮想マシンで使ってみます。

Linux KVMのインストール

Linux KVM環境を構築し、仮想マシンを起動して通信できることを確認します。 まずはLinux KVMをインストールします。

kvmhost# apt update
kvmhost# apt install qemu-kvm libvirt-bin

LibvirtでHugePagesを使う設定

こちらの投稿を参考に、/etc/default/qemu-kvmKVM_HUGEPAGESを1に設定変更します。設定変更後はqemu-kvmサービスを再起動します。

仮想マシンを作成

Virt-Managerなどで仮想マシンを作成します。作成した仮想マシンにOSをインストールします。 インストール、アップデートが終わったら、一旦シャットダウンします。

仮想マシンの設定に追記

DPDKに必要な設定を追記します。以下の共通設定は全ての仮想マシンに設定し、vhostuserインターフェイスは別々のポートを各仮想マシンに設定するようにしてください。

共通の設定

  <memory unit='KiB'>1048576</memory>
  <currentMemory unit='KiB'>1048576</currentMemory>
  
<memoryBacking>
    <hugepages/>
  </memoryBacking>
(memoryBackingセクションを追加)

  <cpu mode='host-passthrough'>
    <numa>
      <cell id='0' cpus='0' memory='1048576' unit='KiB' memAccess='shared'/>
    </numa>
 </cpu>
(cpu mode,numaセクションを追加。numaのmemoryサイズはcurrentMemory unitと同じサイズにする)

各VMにDPDKポートの追記

# virsh edit vm1

    <interface type='vhostuser'>
      <source type='unix' path='/var/run/openvswitch/vhost-user1' mode='client'/>
      <model type='virtio'/>
    </interface>

# virsh edit vm2

    <interface type='vhostuser'>
      <source type='unix' path='/var/run/openvswitch/vhost-user2' mode='client'/>
      <model type='virtio'/>
    </interface>

仮想マシンの起動

次のコマンドを実行して仮想マシンの作成、OSイメージの流し込みを行います。仮想マシンの設定には先の手順で作成したファイルを利用します。

kvmhost# virsh start vm1
kvmhost# virsh start vm2

仮想マシンが起動すると、ovs-vswitch.logに次のような出力がされるはずです。

dpdk(vhost_thread1)|INFO|State of queue 0 ( tx_qid 0 ) of vhost device '/var/run/openvswitch/vhost-user1'changed to 'enabled'
dpdk(vhost_thread1)|INFO|vHost Device '/var/run/openvswitch/vhost-user1' has been added on numa node 0
dpdk(vhost_thread1)|INFO|State of queue 0 ( tx_qid 0 ) of vhost device '/var/run/openvswitch/vhost-user2'changed to 'enabled'
dpdk(vhost_thread1)|INFO|vHost Device '/var/run/openvswitch/vhost-user2' has been added on numa node 0

仮想マシンにはsshやvirt-manager,virt-viewerなどでアクセスします。あとは仮想マシンのゲストOSに入って、追加したvhostuserポート側にIPアドレスを割り当てます。

「unable to map backing store for hugepages: Cannot allocate memory」とかエラーが出た場合は、Hugepagesを増やしましょう。

ex.

# sysctl -w vm.nr_hugepages=8192

以上でvhostuserを仮想マシンに割り当てて、仮想マシン間で通信できるようになります。

f:id:virtualtech:20161209141151p:plain:w400

Hello Worldアプリケーションがビルドできない?

5. Hello World Sample Application — Data Plane Development Kit 16.04.0 documentation

に従ってビルドしようとすると、次のようなエラーが出力されます。

# export RTE_SDK=/usr/share/dpdk/
# cd /usr/share/dpdk/examples/helloworld
# make
/usr/share/dpdk//mk/internal/rte.extvars.mk:57: *** Cannot find .config in /usr/share/dpdk//x86_64-native-linuxapp-gcc.  Stop.

それはどうもUbuntuのCloud Airchiveパッケージのバグの可能性があるようです。バグ報告されていない場合はしないといけませんね。どうしても動かしたい場合はDPDKだけビルドした方がいいのかもしれません。

以下の手順で対応可能でした。.configファイルは/usr/share/dpdk/にconfigファイルとして存在していました。また、公式ガイドではexport RTE_TARGET=x86_64-native-linuxapp-gccとなっていますが、Ubuntuパッケージ版はここがx86_64-default-linuxapp-gccになっています。 読み替えて次のように実行します。なお先の手順でDPDKをOpenvSwitchで使っている場合は動作させることができずエラーになりますので、一旦service openvswitch-switch stopが必要です。

# vi /etc/apt/sources.list.d/cloudarchive-newton.list
…
deb-src http://ubuntu-cloud.archive.canonical.com/ubuntu xenial-updates/newton main

# apt install dpdk-doc
# apt update && apt-get build-dep dpdk
# source /usr/share/dpdk/dpdk-sdk-env.sh
# cd ${RTE_SDK}/examples/helloworld
# make
  CC main.o
  LD helloworld
  INSTALL-APP helloworld
  INSTALL-MAP helloworld.map

実行する前にopenvswitch-switchサービスを停止します。

# service openvswitch-switch stop

念のため、こうして置いたほうがいいかもしれません。元に戻すには前編を参考にadd-portしてください。

# ovs-vsctl del-port ovsbr0 dpdk0
# service openvswitch-switch stop

実行してみます。

# ./build/helloworld -c f -n 4
EAL: Detected 16 lcore(s)
EAL: Probing VFIO support...
PMD: bnxt_rte_pmd_init() called for (null)
EAL: PCI device 0000:07:00.0 on NUMA socket -1
EAL:   probe driver: 8086:10d6 rte_igb_pmd
EAL: PCI device 0000:07:00.1 on NUMA socket -1
EAL:   probe driver: 8086:10d6 rte_igb_pmd
EAL: PCI device 0000:08:00.0 on NUMA socket -1
EAL:   probe driver: 8086:10d6 rte_igb_pmd
EAL: PCI device 0000:08:00.1 on NUMA socket -1
EAL:   probe driver: 8086:10d6 rte_igb_pmd
hello from core 1
hello from core 2
hello from core 3
hello from core 0

実行したサンプルプログラムはすぐ終了してしまうので端末を複数開き、一方でtopコマンドを実行し、一方でhelloworldを実行してください。

このエントリーの続編です。

tech.virtualtech.jp