仮想化通信

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

Ubuntu Xenial (16.04) でOpen vSwitch+DPDKな環境を作る(QEMUアップデート編)

以前、UbuntuでOpen vSwitch+DPDKを導入してKVMで利用する手順をここで書かせていただきました。

tech.virtualtech.jp

tech.virtualtech.jp

現在Ubuntu 16.04ではOcataリポジトリーを有効にすると、標準パッケージよりも新しいQEMU-KVMパッケージがインストールできるようになります。

~$ apt list -a qemu-kvm
Listing... Done
qemu-kvm/xenial-updates 1:2.8+dfsg-3ubuntu2.3~cloud0 amd64
qemu-kvm/xenial-updates,xenial-security 1:2.5+dfsg-5ubuntu10.14 amd64
qemu-kvm/xenial 1:2.5+dfsg-5ubuntu10 amd64

当然新しいものを選択すると思うのですが、実際に従来のバージョンからアップグレードする場合および新規インストールする際にそれぞれ注意することがあったので、ここにまとめようと思います。

アップグレードする場合

DPDKとOpenvSwitch、KVM環境をNewton版パッケージを使って構築して、Ocata版のパッケージに更新したいと思った場合、通常はこのように実行すると思います。

# add-apt-repository cloud-archive:ocata
# apt update
# apt upgrade && reboot
...
# add-apt-repository -r cloud-archive:newton  #Newtonリポジトリーを無効化

ああ簡単、よかったよかった…などと思っていると、次のようなエラーになりOVS+DPDKがうまく動いていないことがわかります。

~# ovs-vsctl show
2910fa6f-1c8b-4e8d-b321-bf36a65509ba
    Bridge "ovsbr0"
        Port "vhost-user1"
            Interface "vhost-user1"
                type: dpdkvhostuser
                error: "could not open network device vhost-user1 (Address family not supported by protocol)"
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
        Port "vhost-user2"
            Interface "vhost-user2"
                type: dpdkvhostuser
                error: "could not open network device vhost-user2 (Address family not supported by protocol)"
        Port "dpdk0"
            Interface "dpdk0"
                type: dpdk
                error: "could not open network device dpdk0 (Address family not supported by protocol)"
    ovs_version: "2.6.1"

とりあえずUbuntuでDPDKを使っている環境でアップグレードするときは、apt upgradeした後、update-alternatives --set ovs-vswitchd /usr/lib/openvswitch-switch-dpdk/ovs-vswitchd-dpdkコマンドを実行してDPDK enableモードでOVSを実行する設定を改めて行なったあと、openvswitch-switchサービスを再起動しなさいってことみたいです。

DPDKが正常に動くようになったから早速VMを起動しようとすると、次のようなログが出力されてVMが起動できない問題に出くわします。

仮想マシンの開始中にエラーが発生しました: unsupported configuration: Shared memory mapping is supported only with hugepages
Traceback (most recent call last):
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 90, in cb_wrapper
    callback(asyncjob, *args, **kwargs)
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 126, in tmpcb
    callback(*args, **kwargs)
  File "/usr/share/virt-manager/virtManager/libvirtobject.py", line 83, in newfn
    ret = fn(self, *args, **kwargs)
  File "/usr/share/virt-manager/virtManager/domain.py", line 1402, in startup
    self._backend.create()
  File "/usr/lib/python2.7/dist-packages/libvirt.py", line 1035, in create
    if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
libvirtError: unsupported configuration: Shared memory mapping is supported only with hugepages

これはVirt-Managerを使って起動しようとした場合のログですが、virshコマンドでVMを起動してもだいたい同じようなエラーが出て起動しません。hugepagesの書き方がQEMUのバージョンの更新(2.5から2.8)によって変更されたようです。記述の仕方はこちらにまとまっています。

libvirt.org

この「MemoryBacking」というところが今回重要です。HugePagesとして確保したメモリーをどこのノードからVMに割り当てるのか厳密に書く必要があるようです。実際の例で説明すると、従来は次のように記述するだけでした。

<memory unit='KiB'>1048576</memory>
  <currentMemory unit='KiB'>1048576</currentMemory>
  <memoryBacking>
    <hugepages/>
  </memoryBacking>

これで良きに計らってくれていたのですが、QEMU 2.8では次のように記述する必要がありました。

  <memory unit='KiB'>1048576</memory>
  <currentMemory unit='KiB'>1048576</currentMemory>
  <memoryBacking>
    <hugepages>
      <page size='2048' unit='KiB' nodeset='0'/>
    </hugepages>
    <nosharepages/>
  </memoryBacking>

システムで1GのHugePagesを確保している場合は2Mではなく、1Gを割り当てることもできます。以上の設定変更でVMが正常起動し、ネットワークはvhostuserで提供できるようになります。

nodeはNuma Nodeを指定します。numactl -Hコマンドで確認できますので、その出力結果をもとにどのノードからメモリーを確保するか指定します。

Ubuntu XenialでOpen vSwitch+DPDKを新規セットアップする場合

基本的には前編後編の流れでセットアップすれば構いません。新しいQEMUを使いたい場合はOcata以降のリポジトリーを有効にしてDPDK、OVS、KVM環境を構築します。

# add-apt-repository cloud-archive:ocata
# apt update

あとはVMの設定を前で説明したようにHugePagesの設定でpage size、nodeをきちんと指定します。それ以外は前編、後編の流れでOpen vSwitch+DPDK+Linux KVM環境を導入できます。