KVMなどの仮想サーバを使って運用をする場合の一つのメリットとして、物理サーバに依存せずにマイグレーションを行える、 という点があるのだけれど、うまく行かなくてはまった事があった。
CentOS 5.5 on libvirtのHost上で動いていたqcow2のGuestイメージをCentOS 5.6のHostに移して動かしたら、どういうわけかうんともすんとも言わなくなった。
その時はどうにかこうにか対策だけはできたものの、どうしてそうなったか原因を特定しきれなかったのだが、その後自分なりに調べてみて、 最近やっと原因のコードを見つけて、対策方法とか対象になるバージョンを特定できたのでまとめた。
おそらく間違ってないと思うけど、KVMのすべてを把握してるわけじゃないので、おかしなところ等あれば突っ込み頂けるとうれしいです。
結論
経緯とかコードとかどうでもいい人のために先に結論から。
対象となる環境
以下2点の両方に当てはまる場合、適切な対策が必要。
1. Guest VMにはファイルのdisk imageを使っており、raw以外の形式(qcow2など)で運用していた。
- rawで扱っている場合には、問題は発生しない。
- (raw deviceの場合もrawなので当然発生しない。)
2. libvirt 0.8.2以前のHostで運用していたGuestを、libvirt 0.8.3以降のHostにマイグレーションした。
- CentOS (他のRedhat系は未調査)では、5.5以前から5.6以降にが該当。
- CentOS 5.6はlibvirt 0.8.2だが、該当のpatchがbackportされて当たっているため、対策が必要。
- debian leny 以前からsqeeze以降へ
- Ubuntu は10.04 以前から10.10以降へ
対策
以下の2つのパターンがある。
1. 移植時にXMLを編集し、disk deviceの中の、driverの項目にname=”qemu” type=”qcow2” などの形式を明示するようにする。
明示的にフォーマットを指定する方法。 多分こっちの方がよい。
2. /etc/libvirt/qemu.conf (CentOSの場合はこの場所) にallow_disk_format_probing = 1
の項目を設定する。
フォーマットの自動認識を有効にする方法。 ただしセキュリティ上のリスクを伴うので、極力やらないほうがよい。
経緯と原因
遭遇した状況
仮想マシンはdisk imageファイル(qcow2圧縮)上に作成されたもので、CentOS 5.5上で使っていたxmlとともに丸っとCentOS 5.6上に移した。 すると、qemu自体の起動はするもののdisk imageを正しく認識せず、エラーもでないまま応答しなくなってしまった。
原因と対処
原因は、libvirtのバージョンがあがる過程でdisk imageのデータ形式の判定に仕様変更が入ったことだった。
それまでlibvirtに食わせていたXML定義の中では、disk deviceのdriver typeを明示的に指定しておらず、kvmの自動認識に任せていた。
それが新しいバージョンのlibvirtでは「driverのtype未指定時には、デフォルトでtype=rawのパラメータを自動補完する」という仕様に変わっていたために、 qcow2のimageをrawとして読んでしまい、認識できなくなってしまった。
この点に気づいたため、前述の対策方法の通り、明示的にtype = qcow2を指定してやる事で問題は解決した。
原因になった箇所
どうしてこうなった、と思ったので、KVMのコードとgit logを追ってみて、どうやら下記の変更が原因のようだった。
libvirt.org Git - libvirt.git/commitdiff
理由について詳しくは探りきれなかったのだけれど、disk imageのファイル形式を自動認識する場合にセキュリティ的な問題があるようで、 それを防ぐためのセキュリティパッチとして、この変更を含むいくつかのFIXが行われたらしい。
そして、disk imageの形式に明示的な指定がない場合には、qemuのraw形式としてパラメータを補完してしまうように変更になった。
対策のところにのせたallow_disk_format_probing
という設定は、その名の通り上記patchのallowDiskFormatProbing
パラメータのフラグを立てるためのもので、
デフォルトではoffになっている。
この一連のpatchはlibvirt 0.8.3で取り込まれているので、問題が起きるのは0.8.2以前から移行してくる場合。 例外として、CentOS 5.6では0.8.2にこのpatch群をバックポートして当ててあるため、対象に含まれる。(srpmで確認済み。)
というわけで。
変更自体はもう結構前の物なので、今更間のある話題かもしれませんが、KVM Hostを移行するなんてそんなに頻繁にやる物でもないだろうから、誰か一人の役に立つ機会でもあれば幸いです。
しかし、libvirtって結構ログが少なくて、いつも苦労する。。。infoとか出してくれるとうれしいよね><