Ubuntu 10.04のKVMでどうにかしてvhost-netを使う

KVMの最近のバージョンにはvhost-netという機能が追加されていて、公式の見解ではレイテンシが10%軽減され通常のvirtioの7倍から8倍近いスループットが発揮されるらしい。是非使いたい機能だが、Ubuntu 10.04はおろか10.10でも標準で用意されているパッケージだけでは使用できない。今回はすこし頑張ってUbuntu 10.04にいくつかのパッケージを追加してvhost-netを使用出来るようにしてみた。

まず、vhost-netを使うにはカーネル側の対応が必要となる。機能自体はカーネル2.6.34以降で取り込まれているようなのだが、10.04のカーネルは2.6.32なので対応していない。10.10であればデフォルトで対応している。次に、qemu-kvmのバージョンアップも必要となる。こちらはバージョン0.13から機能が取り込まれているのだが10.04でも10.10でも対応してない。

10.04の場合、まずはカーネルのバージョンを上げる。これは比較的簡単である。marverickのlinux-image-2.6.35-22-*パッケージがlucid-updatesに公式でbackportsされているのでapt-getでインストールするだけである。flavorは使用環境に合わせて選ぶ必要があが、たとえばサーバー版ならばsudo apt-get install linux-image-2.6.35-22-serverでよい。

qemu-kvmのアップデートは若干手間がかかる、maverickのqemu-kvmもバージョンが0.12.5なので使用できない。幸い、現在テスト中のnatty(11.04)のパッケージが公開されていて、そちらはバージョンが0.13なのでこれを使う。もちろんテスト版なので不具合の可能性は否定できないので注意が必要である。ダウンロードはパッケージに関する詳細ページの一番下のリンクから可能だ。

debファイルをダウンロードしてきたらdpkg -i [ファイル名]でインストールできるが、おそらく依存関係で失敗する。qemu-kvmに関連したパッケージをいくつか追加でダウンロードする必要があるだろう。手元では最終的に以下のパッケージを使うことになった。

全てがインストールできたらvhost-netモジュールをカーネルに組み込む必要がある(CONFIG_VHOST_NETがyのカーネルならば自動で組み込まれているかもしれないがnattyはmだった)。sudo modprove vhost-netで読み込む。これだけだと再起動時に元に戻ってしまうので、/etc/modulesに書き加えておくのがいい

あとはいつも通りvirshでゲストを開始する。libvirt-bin自体のバージョンも上がっているので、vhost-netは自動で有効になる。psコマンドなどで実際に実行されているコマンドを見るとvhost=onのような記述が追加されているはずだ。追加されていない場合、ゲストのカーネルが古くてvhost-netを使用できない状況が考えられる。ゲスト側はカーネル2.6.31以降で、CONFIG_PCI_MSI=y付きでビルドされている必要があるようだ。

というわけで、ゲストは通常のlucidなら問題無いはずなのだが、手元の環境だとCPU負荷がかかっていないのにloadが非常に高くなる現象が発生し、まともに使える状況ではなくなってしまった。そもそもvirshで起動する際に「cpu0 unhandled rdmsr」というエラーが出る上に、ゲスト側でもCPUがスタックしたというメッセージが表示される。適当に調べてみたところ「そのエラーは問題無いので無視して良い」という情報もあったのだが、どうやってもおかしい。問題が起きたのはlucidのゲストだけで、maverickのゲストでは問題が起こらなかったため、試しにゲスト側もカーネルだけ同じ方法でbackportsから2.6.35に更新してみたところ解決した。

以上でUbuntu 10.04でvhost-netが使用できるようになった。netperfでゲスト-ホスト間のスループットをはかってみると確かに7Gbps程度の速度が出る。ただし、フルスピード時のCPU負荷は結構厳しい。ゲスト間だと3Gbps程度で通信できる。単位帯域に対するCPU負荷は結構な割合で下がっているように思われるのでとりあえず導入しておけばそれなりに役に立つと思われる。