2012年9月25日火曜日

Quick clone virtual machines with thin-provisioning

Chefのレシピをテストしていると仮想マシンを作ったり消したりが頻繁に発生します。

これまでは仮想マシンを一度作った後に virt-clone を使ってクローンしていました。しかしこれはそれなりに時間がかかります。

1台あたり1〜2分程度なのですが繰り返し実行したり、複数台準備したりすると待ち時間がうざったく、かつ複数台の場合はIPアドレスを変えたりとまあ面倒くさいことこの上無いです。

また10台単位でクローンを作るとそれなりにディスク容量を消費してしまうのも悩みの種でした。

そこでこの作業をもっと効率良く簡略化できないかと、検索してみると以下のサイトが見つかりました。

libvirtで管理さてるゲストマシンを高速シンプロビジョニングしてくれるツールを作った

まさにこれだ!と思い試して見ましたが、私の環境では上手く動かなかった(後述)なので簡単なスクリプトを作成して使っています。

https://github.com/irixjp/capistrano-recipe/blob/master/virt-clone-thin.sh

解説は以下


使い方

DL後に好きな場所に配置して実行現権限を与えてください。
現在のスクリプトでは仮想マシンにディスク1個だけ、

# ./virt-clone-thin.sh \
  -o master-centos63 \
  -s /var/lib/libvirt/images/master-centos63.qcow2 \
  -n snap-vm2 \
  -h newhost2 \
  -i 192.168.128.32 \
  -k ~/.ssh/id_rsa.pub

こんな感じで使います。

-o 元となる仮想マシン名を指定
-s クローン対象のディスクを指定
-n 新しいVMインスタンス名
-h クローンされたインスタンスのホスト名
-i クローンされたインスタンスのeth0のアドレス
-k 仮想マシンのrootに登録する公開鍵

ディスクサイズに関係なく大体1台あたり1〜3秒でクローンできます。


100台のディプロイも3分程度で終わり、かつディスクもほとんど消費しません。
# for i in {1..100}
> do
> ./virt-clone-thin.sh -o master-centos63 -s /var/lib/libvirt/images/master-centos63.qcow2 -n snap-vm$i -h newhost$i -i 192.168.128.$i
> done

自分用に作ったのでいろいろ決め打ちの部分がありますので、使う場合は自分の環境に合わせてスクリプトの修正をしてください。

・仮想マシンのディスクは1つののみ
・/ 領域は基本パーティション(非LVM
・/ は 第2パーティションに存在する。
・ネットワークはeth0のみ操作
・公開鍵の挿入はrootのみ


解説

スクリプトは至ってシンプルで、まず最初に、

# virt-clone -o xxx -n yyy -f zzz --print-xml

によって、新規仮想マシンのlibvirt用xmlを生成します。


次にvirt-clone時に指定した -f zzz のファイルを差分ディスクで作成します。

# qemu-img create -b xxx.qcow2 -f qcow2 zzz.qcow2


*本来なら、先にqemu-imgで差分ディスクを作成した後に、virt-cloneに--preserve-dataをつければシンプロはもっと簡単に実現可能なのですが、

/usr/lib/python2.7/site-packages/virtinst/CloneManager.py 以下の判定に引っかかってエラーになってしまいます。
483                 if (clone_disk.is_remote() or
484                     clone_disk.type != clone_disk.TYPE_BLOCK or
485                     not orig_disk.path or
486                     not os.access(orig_disk.path, os.R_OK) or
487                     not clone_disk.path or
488                     not os.access(clone_disk.path, os.W_OK)):
489                     raise RuntimeError(
490                         _("Clone onto existing storage volume is not "
491                           "currently supported: '%s'") % clone_disk.path)
clone_disk.type != clone_disk.TYPE_BLOCK この意図がよくわからず、修正しようがなかったので今回は--print-xmlで逃げています。

そして、作成した差分ディスクを qemu-nbd を使ってローカルデバイスとして認識させ、

kpartxでパーティションをdevice mapperへ紐付けて、

最後に通常デバイスの様にマウントします。


マウントできてしまえば、後は設定ファイルをホストから編集して、

最後にダンプしておいてxmlから新しい仮想マシンを定義します。


その他

qcow2で作成したイメージは この 方法で圧縮しておけるので、差分ファイルのみで使う場合はディスク領域を大きく節約できます。

0 件のコメント:

コメントを投稿