動機
前回 Docker + KVM で作成した仮想マシンにWindows7 をインストールしましたが、インストール自体やOSの起動はとても早いものの、いざ使ってみるとかなりモッサリしています。このままだと実使用には耐えないと思い、パフォーマンスの改善を試みることにしました。
現状を知る
まずは Windows エクスペリエンス インデックスを見てみます。
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 グラフィックアダプター を選択し、ドライバーの更新 を選択します
解凍したファイルを置いたディレクトリを指定して、ドライバを更新します。
ドライバ署名が云々、みたいな問題も発生せず、インストールできました。
結果を確認する
ゲストOSの再起動後、結果を確認してみます。既にマウスカーソルの動きが機敏に感じるのですが、気のせいかもしれないので エクスペリエンス インデックス を更新します。
変わってねぇ! ...ですが体感では明らかにモッサリ感がなくなったので ヨシとします。
サウンドカードを変更する1
デバイスマネージャを開いたときに気づいたのですが、-device AC97
で仮想サウンドカードを追加したものの Windows7にドライバが含まれていないようで、動作していませんでした。仮想サウンドカードを別のものに変更し、音が出るようにします。
KVMの起動パラメータを変更する
docker-compose.yml を編集して、-device AC97
を-device intel-hda -device hda-duplex
へ変更します。
動作を確認する
KVMを再起動して動作確認します。
まずはゲストのWindows7をシャットダウンします。このときKVMとともにDockerコンテナが停止するため、$ docker-compose up -d windows7
でコンテナを再作成します(同時にKVMが起動します)。
SPICEクライアントから Windows7に再接続してデバイスマネージャを見ると、変更後の仮想サウンドカードが正しく認識されていました。
Windows7で再生された音が、SPICEクライアントでも再生されるようになりました。
virtioを利用する
(4/2追記 @tukiyo3 さんのコメントより)
仮想ディスクへの接続を準仮想化ドライバであるvirtioに変更して、ディスクパフォーマンスの改善を試みます。
ドライバを準備する
こちらからドライバの入ったイメージファイル(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
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を起動します。
virtio-win.iso は正しくマウントされましたが、temp.rawのほうは virtio接続のドライバが未インストールであるため正しく認識されていません。
デバイスマネージャを見ると、virtio接続が 謎のSCSIコントローラーとして追加されているので これに対してドライバをインストールします。
- そのままデバイスマネージャの SCSIコントローラー をダブルクリック
- ドライバの更新 を押下
- コンピュータを参照してドライバソフトウェアを検索
- E:\viostor\w7\x86 3 を選択して 次へ
- Red Hat VirtIO SCSI controller が見つかるのでインストール
4のドライバのありかを指定する部分については、x86まで明示的に指定したほうがよいようです。(E:\を指定したらBSODになりました。誤って64bit版が選択される?)
インストールが完了したら、一旦仮想マシンをシャットダウンします。
virtioを有効化する
元々あった仮想ディスク(primary.raw)をvirtio接続に変えつつ、ドライバインストール用に追加した仮想ディスク(temp.raw)とCDROM(virtio-win.iso)を削除します。
command: "/run.sh \
(略)
-drive file=/mnt/vm/windows7/primary.raw,if=virtio"
再度 Windows7を起動したところ 問題ないようです。ベンチマークを取ります
劇的な効果です! 3倍以上になった数値もあります
以上