More than 1 year has passed since last update.

動機

前回 Docker + KVM で作成した仮想マシンにWindows7 をインストールしましたが、インストール自体やOSの起動はとても早いものの、いざ使ってみるとかなりモッサリしています。このままだと実使用には耐えないと思い、パフォーマンスの改善を試みることにしました。

現状を知る

まずは Windows エクスペリエンス インデックスを見てみます。exp.png
1.0とか初めて見たんですけど...。ビデオカードをエミュレートするのが重いのでしょうか。それ以外のリソースは問題ないようです。

QXLドライバを利用する

調べたところ、-vga qxlを指定しつつSPICEでKVMに接続している状況下では、ゲストOSでQXL用のデバイスドライバを利用すると描画性能が向上する(本来のパフォーマンスを発揮する)ようです。
参考資料1, 参考資料2

QXLドライバをダウンロードする

こちら の Guest -> Windows binaries -> Windows QXL driver にWindowsゲスト用 QXLドライバがありますので、これをダウンロードします。Windows7の32bit版(qxl_w7_x86.zip)です。zipファイルをダウンロードしたら解凍して適当なディレクトリに置きます。

QXLドライバをインストールする

デバイスマネージャから ディスプレイ アダプター -> 標準 VGA グラフィックアダプター を選択し、ドライバーの更新 を選択します
driver_up1.png

解凍したファイルを置いたディレクトリを指定して、ドライバを更新します。driver_up2.png

ドライバ署名が云々、みたいな問題も発生せず、インストールできました。

結果を確認する

ゲストOSの再起動後、結果を確認してみます。既にマウスカーソルの動きが機敏に感じるのですが、気のせいかもしれないので エクスペリエンス インデックス を更新します。
exp2.png
変わってねぇ! ...ですが体感では明らかにモッサリ感がなくなったので ヨシとします。

サウンドカードを変更する1

デバイスマネージャを開いたときに気づいたのですが、-device AC97 で仮想サウンドカードを追加したものの Windows7にドライバが含まれていないようで、動作していませんでした。仮想サウンドカードを別のものに変更し、音が出るようにします。
ac97.png

KVMの起動パラメータを変更する

docker-compose.yml を編集して、-device AC97-device intel-hda -device hda-duplex へ変更します。

動作を確認する

KVMを再起動して動作確認します。
まずはゲストのWindows7をシャットダウンします。このときKVMとともにDockerコンテナが停止するため、$ docker-compose up -d windows7 でコンテナを再作成します(同時にKVMが起動します)。
SPICEクライアントから Windows7に再接続してデバイスマネージャを見ると、変更後の仮想サウンドカードが正しく認識されていました。
hda.png

Windows7で再生された音が、SPICEクライアントでも再生されるようになりました。

virtioを利用する

(4/2追記 @tukiyo3 さんのコメントより)
仮想ディスクへの接続を準仮想化ドライバであるvirtioに変更して、ディスクパフォーマンスの改善を試みます。

変更前のベンチマークはこんな感じです。
before.png

ドライバを準備する

こちらからドライバの入ったイメージファイル(ISO)をダウンロードします。

$ wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso
$ mv virtio-win.iso /mnt/vm/windows7/

また、追加の仮想ディスク temp.raw を作成しておきます。

$ dd if=/dev/zero of=/mnt/vm/windows7/temp.raw bs=10M count=100

ドライバをインストールする

docker-compose.yml を編集して

  • ダウンロードしたイメージファイルをCDROMとして、
  • 作成した仮想ディスク temp.raw をHDDとして、仮想マシンに追加します。

このとき、temp.raw のみ接続インタフェースをvirtioとします。(if=virtioの部分)
if=virtioを記述すると、-hda, -hdb, -cdrom のオプションは使えなくなるためこれらは全て -driveに統一する必要があります。2

docker-compose.yml
  command: "/run.sh  \
(略)
    -drive file=/mnt/vm/windows7/virtio-win.iso,media=cdrom \
    -drive file=/mnt/vm/windows7/primary.raw \
    -drive file=/mnt/vm/windows7/temp.raw,if=virtio"

この状態でコンテナを作成し、Windows7を起動します。

drives_before.png
volumes_before.png

virtio-win.iso は正しくマウントされましたが、temp.rawのほうは virtio接続のドライバが未インストールであるため正しく認識されていません。

デバイスマネージャを見ると、virtio接続が 謎のSCSIコントローラーとして追加されているので これに対してドライバをインストールします。
devices_before.png

  1. そのままデバイスマネージャの SCSIコントローラー をダブルクリック
  2. ドライバの更新 を押下
  3. コンピュータを参照してドライバソフトウェアを検索
  4. E:\viostor\w7\x86 3 を選択して 次へ
  5. Red Hat VirtIO SCSI controller が見つかるのでインストール

4のドライバのありかを指定する部分については、x86まで明示的に指定したほうがよいようです。(E:\を指定したらBSODになりました。誤って64bit版が選択される?)
install.png

devices_after.png

インストールが完了したら、一旦仮想マシンをシャットダウンします。

virtioを有効化する

元々あった仮想ディスク(primary.raw)をvirtio接続に変えつつ、ドライバインストール用に追加した仮想ディスク(temp.raw)とCDROM(virtio-win.iso)を削除します。

docker-compose.yml
  command: "/run.sh  \
(略)
    -drive file=/mnt/vm/windows7/primary.raw,if=virtio"

再度 Windows7を起動したところ 問題ないようです。ベンチマークを取ります

after.png

劇的な効果です! 3倍以上になった数値もあります

以上


  1. 全然チューニングじゃなくてスミマセン 

  2. -cdrom file=hoge.iso としてしまうと、qemu-system-x86_64: -cdrom file=hoge.iso: could not open disk image file=hoge.iso: Could not open 'file=hoge.iso': No such file or directory というエラーが出ます。非常にわかりにくいというかハマりました 

  3. 64bit版のWindows7なら x86の部分はamd64になります。