ESXi から Proxmox VE (以下 PVE)に移行しようとして、検証を遅々として進めています。PVE は(というか Linux は)VMFS6 上の vmdk を直接扱うことはできないようなので、一旦何かしらの変換をして扱う必要があります。

ESXi の VM をエクスポートして OVF 形式に変換し、それを PVE でインポートするのがサポートされた方法のようですが、そうすると元の vmdk と同じサイズの一時ディスクが必要になってしまうので嬉しくありません(最近 HDD 高いし)。というわけでディスクイメージを直接変換し、VM そのものの設定は面倒ですが手作業で行うことを考えます。VM の数が少ないならこれでもいいでしょう。

ディスクイメージを直接変換するには、ESXi の VMFS6 を PVE 上で vmfs6-tools で読み込み専用マウントし、vmdk ファイルを qemu-img コマンドで qcow2 形式なり raw 形式に変換します。vmfs6-tools は Debian のパッケージリポジトリから取ってくる形になります。

root@pve:~# apt install vmfs6-tools
(中略)
root@pve:~# vmfs6-fuse /dev/sdb8 /mnt/vmfs
VMFS version: 6
root@pve:~# qemu-img convert -f vmdk -O qcow2 /mnt/vmfs/somevm/somevm.vmdk ~/somevm.qcow2

…というのが通り一遍な話なんですが、検証していて気づいたことがあります。

まず、thin provisioning、lazy zeroed thick provisioning、eager zeroed thick provisioning の vmdk について、それぞれにほぼ同じデータを書いて(具体的には Ubuntu をインストールした)、その後 qcow2 形式に変換しました。すると以下のようになります。

root@pve:~# time qemu-img convert -f vmdk -O qcow2 /mnt/tmp/ubuntu-eager/ubuntu-eager.vmdk /mnt/pve/testdir/images/ubuntu-eager.qcow2

real    20m43.444s
user    0m15.347s
sys     1m3.470s
root@pve:~# time qemu-img convert -f vmdk -O qcow2 /mnt/tmp/ubuntu-lazy/ubuntu-lazy.vmdk /mnt/pve/testdir/images/ubuntu-lazy.qcow2

real    20m7.457s
user    0m15.473s
sys     1m3.892s
root@pve:~# time qemu-img convert -f vmdk -O qcow2 /mnt/tmp/ubuntu-thin/ubuntu-thin.vmdk /mnt/pve/testdir/images/ubuntu-thin.qcow2

real    6m0.489s
user    0m11.766s
sys     1m0.454s
root@pve:~# ls -lh /mnt/pve/testdir/images/
total 15G
-rw-r--r-- 1 root root 4.9G Oct 10 20:58 ubuntu-eager.qcow2
-rw-r--r-- 1 root root 4.9G Oct 10 21:20 ubuntu-lazy.qcow2
-rw-r--r-- 1 root root 4.9G Oct 10 21:27 ubuntu-thin.qcow2

できる qcow2 ファイルのサイズが同じなのは当然予想できたことですが、thin だけが処理が早く、lazy と eager は時間がかかっています。lazy なのに時間がかかるのはおかしいな?と思って vmdk の backing file (実際のディスクのデータが入っているファイル。xxx-flat.vmdk という名前)を dd で読んでみても、やっぱり同じ傾向になります。

root@pve:~# time dd if=/mnt/tmp/ubuntu-eager/ubuntu-eager-flat.vmdk of=/dev/null bs=1M
65536+0 records in
65536+0 records out
68719476736 bytes (69 GB, 64 GiB) copied, 1244.46 s, 55.2 MB/s

real    20m44.479s
user    0m0.331s
sys     0m59.913s
root@pve:~# time dd if=/mnt/tmp/ubuntu-lazy/ubuntu-lazy-flat.vmdk of=/dev/null bs=1M
65536+0 records in
65536+0 records out
68719476736 bytes (69 GB, 64 GiB) copied, 1208.32 s, 56.9 MB/s

real    20m8.364s
user    0m0.322s
sys     1m0.591s
root@pve:~# time dd if=/mnt/tmp/ubuntu-thin/ubuntu-thin-flat.vmdk of=/dev/null bs=1M
65536+0 records in
65536+0 records out
68719476736 bytes (69 GB, 64 GiB) copied, 353.017 s, 195 MB/s

real    5m53.066s
user    0m0.215s
sys     0m51.034s

lazy なら vmdk の大半を占める、まだ書き込みがされていない(つまりゼロのままであるはずの)領域は、実際には読み込みをしない挙動になることが期待されます。しかし、この遅さは明らかに何かしら読み込みを行っていますし、実際 iostat で見ると読み込みを行っているのが分かります。

上の例では ESXi をインストールした HDD はゼロを書いて消去したものを使っていました。ではランダムデータを書いて消去したものを使ったらどうなるでしょうか。なお、今度は Ubuntu はインストールせず、vmkfstools で作成した直後の vmdk を対象としています。

root@pve:~# time qemu-img convert -f vmdk -O qcow2 /mnt/vmfs/dirty-lazy.vmdk ~/dirty-lazy.qcow2

real    20m13.763s
user    0m10.469s
sys     1m35.590s
root@pve:~# time qemu-img convert -f vmdk -O qcow2 /mnt/vmfs/dirty-eager.vmdk ~/dirty-eager.qcow2

real    20m41.797s
user    0m15.293s
sys     1m0.150s
root@pve:~# time qemu-img convert -f vmdk -O qcow2 /mnt/vmfs/dirty-thin.vmdk ~/dirty-thin.qcow2

real    0m51.079s
user    0m11.715s
sys     0m39.344s
root@pve:~# ls -lh
total 65G
-rw-r--r-- 1 root root 193K Dec 14 19:24 dirty-eager.qcow2
-rw-r--r-- 1 root root  65G Dec 14 18:44 dirty-lazy.qcow2
-rw-r--r-- 1 root root 193K Dec 14 19:44 dirty-thin.qcow2

lazy だけデカいです。これは qcow2 イメージにはゼロでない値が保存されている、つまり lazy な vmdk を読んだときにゼロでない値を読んだということです。

lazy な vmdk は、ディスクの領域は予約するが、その領域にゼロを書き込む代わりに、その領域はまだ書き込みが行われていないので読み込んだらゼロを返せとフラグを立てることで lazy なゼロ化を実現しています(予約したうえで実際にゼロを書き込むのが eager zeroed、予約自体をしないのが thin)。今回ゼロでない値を読んでいるということは、上記のフラグを認識せず、予約した領域のデータをそのまま読んでしまっていると見られます。この状態で変換をかけると、ファイルシステムレベルで見せてはいけないVMホストの生ディスクの様子がゲストから見えてしまうことになり、セキュリティ上の問題をはらんでいます。もしこれを気にするのであれば、ESXi 上で eager zeroed に変換する (vmkfstools -k) か thin に変換する (vmkfstools -K) といった処置をしておく必要があります。

Trackback

no comment untill now

Add your comment now