qcow2とバッキングチェーン
一言でいうと
qcow2の本当の力は、圧縮や暗号化ではなく、バッキングファイルです。ゴールデンイメージ1つの上に薄いオーバーレイを載せて、VMを数十台作れます。
なぜ必要なのか
VMを100台立ち上げる必要があります。それぞれ20GBのディスクが必要です。そのままなら2TBです。ところが、その100台は同じOSイメージから出発し、実際に異なる部分は、1台あたり数百MBです。
qcow2のバッキングファイルが、この問題を解決します。読み取りはバッキングファイルから、書き込みはオーバーレイだけに行います。100台が20GBのゴールデンイメージ1つを共有し、それぞれは変更分だけを持ちます。
どう動くのか
基本操作
qemu-img create -f qcow2 base.qcow2 20G # 씬 프로비저닝: 실제 점유는 거의 0
qemu-img info base.qcow2
qemu-img info --output=json base.qcow2 # 스크립트로 파싱하기 좋다
qemu-img convert -f raw -O qcow2 in.raw out.qcow2
qemu-img check base.qcow2
qemu-img infoで見るべき値が2つあります。
- virtual size: ゲストが見るサイズ
- disk size: 実際にホストのディスクを食うサイズ
2つの差が、シンプロビジョニングです。作ったばかりの20Gのイメージのdisk sizeは、200KB程度です。モニタリングでvirtual sizeだけを見ると、オーバーコミットを見逃します。ホストのディスクが500GBなのにvirtual sizeの合計が2TBという状況は、問題なく成立し、ゲストたちが実際に埋め始めたときに壊れます。
バッキングファイル
qemu-img create -f qcow2 -b /var/lib/libvirt/base.qcow2 -F qcow2 vm01.qcow2
qemu-img info --backing-chain vm01.qcow2
-Fでバッキングファイルのフォーマットを明示する必要があります。以前は省略できましたが、今は警告が出たり拒否されたりします。フォーマットを推測させることが、セキュリティ上の問題になりうるからです。
バッキングチェーンには、ルールがあります。
- バッキングファイルは絶対に変更してはいけません。オーバーレイは「バッキングのこのブロックは変わっていない」を前提にしているので、バッキングが変わると、オーバーレイがまとめて静かに壊れます。ゴールデンイメージは読み取り専用にしておくのが慣例です。
- パスがイメージの中に記録されます。バッキングファイルを移すと、オーバーレイが見つけられません。
qemu-img rebase -u -b <새경로> <오버레이>(プレースホルダーは新しいパスとオーバーレイです)で、記録だけを直せます(-uはunsafeで、データを実際には移さず、参照だけを変えます)。 - チェーンが長くなると、読み取り性能が落ちます。1つのブロックを見つけるために、複数のファイルをさかのぼる必要があります。
qemu-img convertでフラット化(flatten)するのが、定期メンテナンスの項目です。
スナップショットの2種類
内部スナップショット(internal): qcow2ファイルの中に、複数の時点を一緒に格納します。
qemu-img snapshot -c before-upgrade disk.qcow2 # 생성
qemu-img snapshot -l disk.qcow2 # 목록
qemu-img snapshot -a before-upgrade disk.qcow2 # 적용(되돌리기)
qemu-img snapshot -d before-upgrade disk.qcow2 # 삭제
このコードブロックの4つの韓国語コメントは、順に、作成、一覧、適用(元に戻す)、削除を述べています。
ファイル1つで管理できて便利ですが、ファイルが大きくなり、VMが起動している間は、qemu-imgで触ってはいけません(実行中のイメージの変更は破損を招きます)。実行中のスナップショットは、QEMUモニターやlibvirtを経由する必要があります。
外部スナップショット(external): 現在のイメージをバッキングにする新しいオーバーレイを作ります。
qemu-img create -f qcow2 -b disk.qcow2 -F qcow2 disk.snap1.qcow2
元はその時点で凍結され、以降の書き込みは新しいファイルに行きます。バックアップツールが元を安全にコピーできるので、バックアップのワークフローでの標準です。元に戻すのは、オーバーレイを捨てるだけで終わります。その代わり、ファイルが増え、チェーンの管理が必要です。
| 項目 | 内部スナップショット | 外部スナップショット |
|---|---|---|
| ファイルの数 | 1個 | 時点ごとに1個 |
| 元に戻す | -a |
オーバーレイの削除 |
| バックアップとの相性 | 低い | 高い(元が固定される) |
| 実行中の作成 | モニター/libvirtが必要 | モニター/libvirtが必要 |
| チェーンの管理 | 不要 | 必要 |
cluster_size
qcow2の割り当て単位です。既定は64KBです。
qemu-img create -f qcow2 -o cluster_size=1M big.qcow2 100G
大きくするとメタデータが減ってシーケンシャルI/Oに有利で、小さくするとランダム書き込みでの無駄が減ります。大容量のイメージで1Mに上げるのが、よくあるチューニングです。
現場での姿
バッキングファイルを誤って変更して、VM数十台が壊れる事故。ゴールデンイメージにパッチを当てようとして直接起動した瞬間に、その上に載ったすべてのオーバーレイが整合性を失います。パッチは、ゴールデンイメージのコピーを作ってそれに適用し、新しい世代としてデプロイする必要があります。
ホストのディスクが突然いっぱいになる事故。シンプロビジョニングされたイメージが同時に大きくなると、ホストが先に死にます。VMはディスクエラーに遭い、ファイルシステムが壊れます。virtual sizeの合計と、実際の空き容量を、一緒に監視する必要があります。
次のラボですること
qcow2を作って情報を読み、変換し、バッキングチェーンを立て、rebaseでパスを直します。続くラボでは、内部/外部のスナップショットをどちらも扱って、比較表を作ります。