コピーなしにXenをkvmに移行する方法

事務所に置いていたサーバを整理して、サーバ室に移そうとしている。

そのために、VMの整理とかアップグレードとかしていたのだけど、元々事務所に置いていたサーバはXenで仮想化してあった。

Xen実験機を作る 

これ自体は初期はいろいろトラブルはあったものの、結構安定して動いていたのだけど、最近になってどうやらXenの準仮想化よりも、kvmの完全仮想化の方がパフォーマンスが良いらしいことを知った。

同じサーバで、XenとKVMのベンチマークをとって比較してみた。

「えー?」とか思いつつ調べると、どうやらそれは本当らしい。サーバ室のサーバは作ったのも比較的最近であるし、「今さらXen?」とか思って、半ば思考停止的にkvmを選択していたのだけど、果してこれが最良の選択であったか、当時から疑問であった。とは言え、Xenよりもkvmの方がパフォーマンス良い的な話をあちこちで目にして、どうやらこの選択に誤りはなかったようだ。

Xenは3.0系と4.0系でいろいろ変わってしまったこととか、カーネルのバージョンがどうだとか、いろいろ面倒臭い。その点、kvmはguestとhostは、原則的にはまるっきり依存関係がないので、バージョンアップとか気楽でいい。とか考えると「やっぱりkvmだよね」と言うことで、Xenで動かしていたものもkvmにすることにしたので、いろいろ実験をしていた。

両方やった人はわかっていると思うが、Xenとkvmではディスクの形式が違う。Xenはguest側のパーティションをhost側では適当にマッピングすることが出来るので、guestは同じ物理ディスクだと思っているものが、hostではまるっきり違うとかとゆーことが出来て、いろいろ便利だった。特に単位がパーティションなので、ループバックでmountして… とか出来て便利で良かった。kvmはディスクそのものを仮想化しているので、guestの1ディスクはhostの1イメージになっている。ループバックでmountやfsckする時も、ちょっと面倒臭い。こういった点では、ちょっとだけXenの方が楽… ってのは良いんだが、こういった違いがあるので、合わせてやらないといけない。

同じ問題で悩む人は結構いるらしく、いろいろ方法がある。特にRed Hatの場合は、主力仮想化をXenからkvmに変えた関係で、移行ツールがあったりする。

virt-v2vによるXenからKVMへのVM移行手順

こういったものがDebian系にもあると良いんだが、debはないようだ。そこでいろいろ方法を見つける。

Xen から KVM への移行 (検討中)

Debian squeezeでXen4.0からkvmへの移行

ところが、これらの方法は「コピー」が入る。コピーがあると、面倒臭い上に時間がかかるので、なるべくコピーをしないでやりたい。特にVMのイメージは小さくても数GBはあるので、コピーはなるべくしたくない。何かマッピングみたいな方法で出来ないかなーと思っていたら、

Xen のディスクイメージを KVM で使用する

と言うのを発見する。これをヒントにやってみる。

原理としては、

  • Xenのパーティションイメージには既に必要なものは全部ある
  • Xenにないのは自力のブート
  • kvmはディスクのイメージを要求する
  • 「パーティションイメージ」は実は「whole disk」とゆーことに出来る

ということだ。もうちょっと具体的に説明すると、

  • kvmがブートするのに必要なのは「ディスク」
  • 「ディスク」に必要なものは/bootのパーティション
  • /はgrub.cfgの中でXenのイメージをwhole diskとして使うように指示する

ということだ。

まず、小さいdiskを用意する。この中には/bootしか入らないので、たいした大きさはいらない。

# dd if=/dev/zero of=boot.img bs=1024 count= seek=102400

まぁ、やたらにケチケチしてもしょうがないので、100MB程取った。俺ってお大尽w 中に入るのは、/bootだけなので、10MBもあれば多分お釣りが来ると思うのだが。

次に適当なブート可能なイメージを用意する。ここで必要なのは、

grubが実行出来ること

だ。だから、何か適当なdistroのrescueイメージとかそういったのでいい。作業用のちっちゃいイメージとか作っておくのも悪くない。「オレオレrescue」とか作っておくと、いろいろ便利だ。私はメンテ用にそういったのを作ってUSBメモリに入れてたりする。今回は使ってないけど。とは言え、ちょっとインチキをすれば、/bootの設定は1回だけでいいので、何もイメージとか自分で用意する必要もないかも知れない。

今回はとりあえず、元のイメージがDebian(lenny)だったので、Debianの名刺カードイメージ(debian-6.0.5-amd64-businesscard.iso)を使うことにした。これが凄く便利ってことは全くなかったので、もっと便利なものが使える人はそっちで。

どうせkvmを運用で使うには、libvirtを使うことになるので、kvmのコマンドラインで悩まないで、virshに食わせるXMLを作る。

<domain type=’kvm’>
<name>xxxx</name>
<memory>1048576</memory>
<currentMemory>1048576</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch=’x86_64′ machine=’pc’>hvm</type>
<!–boot dev=’hd’/ –>
<boot dev=’cdrom’/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>

<devices>
<emulator>/usr/bin/kvm</emulator>
<disk type=’file’ device=’disk’>
<source file=’/instance/root.img’/>
<target dev=’vda’ bus=’virtio’/>
</disk>
<disk type=’file’ device=’disk’>
<source file=’/instance/xxxx.img’/>
<target dev=’vdb’ bus=’virtio’/>
</disk>
<disk type=’file’ device=’cdrom’>
<source file=’/instance/debian-6.0.5-amd64-businesscard.iso’/>
<target dev=’vdc’ bus=’ide’/>
<readonly />
</disk>
<interface type=’bridge’>
<mac address=’52:54:10:01:00:53’/>
<model type=’virtio’/>
<target dev=’vnet0’/>
<source bridge=’br0’/>
</interface>
<interface type=’bridge’>
<mac address=’52:54:10:02:00:53’/>
<model type=’virtio’/>
<target dev=’vnet1’/>
<source bridge=’br1’/>
</interface>
<input type=’mouse’ bus=’ps2’/>
<graphics type=’vnc’ listen=’192.168.2.26′ port=’5900′ autoport=’no’ keymap=’ja’/>
</devices>
</domain>

こんな感じ。これでCD-ROMからブートさせて、grub-installをする。

元がlennyだったので、squeezeに上げたりして妙にハマったりしたのだけど、/etc/apt/sources.lstをsqueeze用にいじってapt-get updateをしたら、dist-upgradeをする前にkernelやらgrubやらをインストールしてしまい、grub-installまでやってしまう。その後、リブートが出来ることを確認してから、dist-upgradeをかければいい。

grub-installはいつもコマンドラインを忘れてしまうのだけど、

# grub-install /dev/vda

でいいと思う。

update-grub2とかやると、適当に/boot/grub/grub.cfgを作ってくれるのだけど、この時起動用のカーネルコマンドラインで、

root=/dev/vdb

ってゆーのがあることを確認しておく。これがつまり、/bootだけあるディスクイメージでブートさせて、/はXenで使っていたイメージファイルを使うとゆーことだ。

上手にやれば、大過なくXenで作ったイメージファイルをkvmで使うことが出来るようになると思う。

さて、仮想化したサーバでは、こういったVMはいっぱいあると思う。正攻法では、VMの数だけこの作業を繰り返せばいいのだけど、2つ目からはちょっと手抜きが出来る。と言うのも、同じdistroであって、同じような/を使うのであれば、/bootの内容は同じだということだ。

だから、2つ目は、1つ目で作った/bootの入っているイメージをコピーして、適当なXMLを書けば、そのままブートしてくれる。もっとも、このままだと/lib/modules以下に適当なモジュールがなかったりするので、grubとkernelくらいは入れておく。

# apt-get install linux-image-amd64 grub2

こうやると、もう一度grubの設定やら動くんだけど、こまけーこたーいーんだよ。

まぁこんな手順でやると、イメージのコピーなしでXen用のイメージからkvm用のイメージを作ることが出来る。とゆーか、「kvm用のイメージ」と言っても結局grubとかスタンドアロン用のカーネルとかとゆーXenには関係のないものを入れただけなので、もし気が変わってXenを使おうと思ったら、Xen用の起動設定を作るだけなので、「兼用」と言えなくもない。