犬でも分かるKVM(4): 仮想マシンのスナップショット

スナップショットの機能を使うと、稼働中の仮想マシンの状態をディスクに保存することができます。そして、保存したスナップショットから、保存した時点の仮想マシンの状態に戻すことができます。調べてみると、いろいろなオプションがあって初めてのときには迷います。折角調べたので整理してみた情報を公開します。

RHEL9では内部スナップショットは非推奨

どうやらスナップショットには、内部スナップショットと外部スナップショットがあるらしく、以下の違いがあります。

種類機能
内部スナップショット仮想マシンのディスクイメージ内にスナップショットのデータを保存する。
外部スナップショット仮想マシンのディスクイメージ外に、スナップショットのデータ(差分)を保存する。

でも、RHELのページによると、内部スナップショットはRHELでは非推奨って書いてあります。サポートも提供していないと。。理由は分からないですが、サポートしないと言われてしまうとあきらめるしか仕方ありません。今回は外部スナップショットを試すことにします。

外部スナップショットにもいろいろな方式がある

外部スナップショットを試すにしても、更にその方法に選択肢があります。もう、この時点で初心者、心折れるんですけど。。分類すると以下のようになるらしい。

(1) shutdownされた仮想マシンのスナップショット
(2) 実行中の仮想マシンのスナップショット
(2-1) ディスク状態だけのスナップショット
(2-2) 一時停止してディスク状態とメモリーをスナップショット
(2-3) 実行中のままディスク状態とライブメモリーをスナップショット

運用中に仮想マシンを停止するのは難しいし、でもメモリの状態は保存しなくても良いから、(2-1)のディスク状態だけスナップショットを取りたかったんですけど、結論から言うと、スナップショットを保存した時点のディスク状態にロールバックされなかったので、(2-2)または(2-3)の方法でスナップショットを作成することにしました。

外部スナップショット(1): shutdownされた仮想マシンのスナップショット

以下のようにしてスナップショットを作成するようです。

virsh snapshot-create-as <domain名> <snapshot名> --disk-only

引数説明
<domain名>仮想マシンの名前です
<snapshot名>スナップショットに付ける名前です

仮想マシンを停止するくらいなら、仮想マシンのイメージファイルを直接コピーしてバックアップすればいいんじゃね、、と思っているので、この方法は試していません。

外部スナップショット(2-1): 実行中の仮想マシンのディスク状態だけスナップショット
①スナップショットを作成

以下のようにしてスナップショットを作成します。(1)のコマンドに「–quiesce」を付けるだけです。

virsh snapshot-create-as <domain名> <snapshot名> --disk-only –quiesce

実際に試してみました。以下の例では、「flask0」という仮想マシンにおいて「flask0-snap」という名前のスナップショットを作成しています。

# virsh snapshot-create-as flask0 flask0-snap --disk-only --quiesce
Domain snapshot flask0-snap created

作成したスナップショットの一覧は、以下の通りのコマンドで確認することができます。Stateには「disk-snapshot」と表示されます。

# virsh snapshot-list flask0  
Name          Creation Time               State
----------------------------------------------------------  
flask0-snap   2025-02-02 05:50:54 +0900   disk-snapshot

作成したスナップショットファイルは、/var/lib/libvirt/images/ に作成されます。

# ls -l /var/lib/libvirt/images/
-rw------- 1 root root     8716288 Feb  2 06:07 rockylinux_flask0.flask0-snap ★2
-rw------- 1 qemu qemu 4005953536 Feb 2 06:53 rockylinux_flask0.qcow2
★1

★1が元のイメージファイルで、★2がディスクのスナップショットファイルです。

②スナップショットからのロールバックは失敗..

保存したスナップショットから、スナップショット作成時点の状態にディスクを戻るのかをテストするために、スナップショットを作成した後に、仮想マシンの中にファイルを作ってみます。

# pwd
/root
# ls > testfile
# ls -l testfile
-rw-r--r-- 1 root root 30  2月  2 05:57 testfile

その後に、以下のコマンドでスナップショットを仮想マシンに戻します。

# virsh blockcommit flask0 vda --active --verbose --pivot
Block commit: [100.00 %]
Successfully pivoted

期待する結果は、スナップショット作成後に作成したtestfileは存在していない、という状態なのですが、期待に反してtestfileは残っていました。なんでも、virsh blockcommit を実行すると、スナップショットで作成された差分ディスクの変更を元のベースディスクに統合するけど、スナップショットの取得時点にロールバックするわけではなく、その後の変更を適用してしまうため、スナップショット取得後に作成したファイルはそのまま残る、ということのようです。
従って、ロールバックは失敗です。
ううーん、、ここであきらめました(うまくいく方法があったら、教えて…)。

スナップショット作成時点に完全にロールバックするには virsh snapshot-revert を使う、という内容も見つけたので、こちらを試したいと思います。しかし、virsh snapshot-revert でロールバックできるのは、メモリ、ディスク含めたフルスナップショットが必要らしい。。そういう訳で、(2-2),(2-3)の作戦に切り換えます。

外部スナップショット(2-2): 実行中の仮想マシンを一時停止してディスク状態とメモリーをスナップショット

この方法では、スナップショット作成時に仮想マシンを一時停止するためにダウンタイムが発生します。しかし、特に負荷の高い仮想マシンの場合は、一時停止したほうが、実行中の仮想マシンのライブスナップショットを作成する (2-3の方法) よりも、確実に機能する可能性があるとのことです。

①スナップショットを作成

以下のようにしてスナップショットを作成します。「–memspec」でメモリ内容を保存するファイルを指定します。「–atomic」オプションを指定すると、スナップショットの作成中にエラーが発生した場合、すべての変更を取り消します(ロールバックする)。メモリスナップショットとディスクスナップショットの両方が成功しない限り、どちらも適用されないとのことです。従って、付けて実行することをお勧めします。

virsh snapshot-create-as <domain名> <snapshot名> --memspec <メモリのスナップショットファイル> --atomic

以下のコマンドの通り、実際に試してみました。snapshot名は「flask0-snapm」としています。

# virsh snapshot-create-as flask0 flask0-snapm --memspec /var/lib/libvirt/images/flask0-snapm.img --atomic
Domain snapshot flask0-snapm created

作成したスナップショットの一覧は、以下の通りのコマンドで確認することができます。Stateには「running」と表示されます。

# virsh snapshot-list flask0  
Name           Creation Time               State
-----------------------------------------------------  
flask0-snapm   2025-02-23 15:45:30 +0900   running

/var/lib/libvirt/images/ 配下には以下のファイルが作成されています。

# ls -l /var/lib/libvirt/images/*flask*
-rw------- 1 root root  489973051 Feb 23 15:45 /var/lib/libvirt/images/flask0-snapm.img ★3
-rw------- 1 qemu qemu     196928 Feb 23 15:45 /var/lib/libvirt/images/rockylinux_flask0.flask0-snapm ★2
-rw------- 1 qemu qemu 4026728448 Feb 23 15:42 /var/lib/libvirt/images/rockylinux_flask0.qcow2
★1

★1が元のイメージファイル、★2がディスクのスナップショットファイル、★3がメモリのスナップショットファイルです。

②スナップショットからのロールバック

保存したスナップショットから、スナップショット作成時点の状態にディスクを戻るのかをテストするために、スナップショットを作成した後に、仮想マシンの中にファイル(/root/testfile)を作ってからテストします。

以下のコマンドで保存したスナップショットから、スナップショット作成時点の状態にディスクに戻します。

# virsh snapshot-revert flask0 flask0-snapm
Domain snapshot flask0-snapm reverted

/var/lib/libvirt/images/ 配下のファイルを観察すると、以下の通りになっていました。

# ls -l /var/lib/libvirt/images/*flask*
-rw------- 1 root root  489973051 Feb 23 15:45 /var/lib/libvirt/images/flask0-snapm.img
-rw------- 1 qemu qemu    1245184 Feb 23 15:51 /var/lib/libvirt/images/rockylinux_flask0.1740293348 ★
1
-rw------- 1 qemu qemu 4026728448 Feb 23 15:42 /var/lib/libvirt/images/rockylinux_flask0.qcow2

★1は、コマンド実行前は rockylinux_flask0.flask0-snapmというファイルでした。ロールバックを行うことで、ファイル名が変わるようです。

仮想マシンにログインして/root/testfile の存在を確認すると、存在しなかったので、スナップショット作成時点のディスクの状態に正しくロールバックされていることが分かります。

外部スナップショット(2-3): 実行中の仮想マシンを実行中のままディスク状態とライブメモリーをスナップショット

この方法では、仮想マシンを一時停止せずにメモリーの内容を保存することができますが、スナップショットからロールバックをしたときに、ネットワーク接続の喪失やシステム時間の同期の欠如など、さまざまな要因によりプロセスが失敗する可能性があるとのことです。そう言われてもなあ。。。

①スナップショットを作成

(2-2)の方法に、更に「–live」オプションを付けてスナップショット作成を行います。今回のsnapshot名は「flask0-snapml」としています。

# virsh snapshot-create-as flask0 flask0-snapml --live --memspec /var/lib/libvirt/images/flask0-snapml.img --atomic
Domain snapshot flask0-snapml created

(2-2)の処理の後に、スナップショットを作成したので、スナップショットの一覧は以下の通りの状態になります。

# virsh snapshot-list flask0  
Name            Creation Time               State
------------------------------------------------------  
flask0-snapm    2025-02-23 15:45:30 +0900   running  
flask0-snapml   2025-02-23 15:51:19 +0900   running

/var/lib/libvirt/images/ 配下には以下のファイルが作成されています。

# ls -l /var/lib/libvirt/images/*flask*
-rw------- 1 root root  489973051 Feb 23 15:45 /var/lib/libvirt/images/flask0-snapm.img
-rw------- 1 root root  491097352 Feb 23 15:51 /var/lib/libvirt/images/flask0-snapml.img ★3
-rw------- 1 qemu qemu    1245184 Feb 23 15:51 /var/lib/libvirt/images/rockylinux_flask0.1740293348
-rw------- 1 qemu qemu     524288 Feb 23 15:51 /var/lib/libvirt/images/rockylinux_flask0.flask0-snapml ★2
-rw------- 1 qemu qemu 4026728448 Feb 23 15:42 /var/lib/libvirt/images/rockylinux_flask0.qcow2
★1

★1が元のイメージファイル、★2がディスクのスナップショットファイル、★3がメモリのスナップショットファイルです。

(2-2)で作成したスナップショットのファイルも残っていますね。このように、スナップショットは複数作成することができ、また、それぞれのスナップショットを作成した時点の状態にロールバックすることができます。

②スナップショットからのロールバック

今回も仮想マシンの中にファイル(/root/testfile)を作ってからテストします。

以下のコマンドで保存したスナップショットから、スナップショット作成時点の状態にディスクに戻します。

# virsh snapshot-revert flask0 flask0-snapml
Domain snapshot flask0-snapml reverted

/var/lib/libvirt/images/ 配下のファイルを観察すると、以下の通りになっていました。

# ls -l /var/lib/libvirt/images/*flask*
-rw------- 1 root root  489973051 Feb 23 15:45 /var/lib/libvirt/images/flask0-snapm.img
-rw------- 1 root root  491097352 Feb 23 15:51 /var/lib/libvirt/images/flask0-snapml.img
-rw------- 1 qemu qemu    1245184 Feb 23 15:51 /var/lib/libvirt/images/rockylinux_flask0.1740293348
-rw------- 1 qemu qemu     196928 Feb 23 15:54 /var/lib/libvirt/images/rockylinux_flask0.1740293646 ★1
-rw------- 1 qemu qemu 4026728448 Feb 23 15:42 /var/lib/libvirt/images/rockylinux_flask0.qcow2

★1は、コマンド実行前は rockylinux_flask0.flask0-snapmlというファイルでした。(2-2)の場合と同様、ロールバックを行うことで、ファイル名が変わるようです。

仮想マシンにログインして/root/testfile の存在を確認すると、存在しなかったので、スナップショット作成時点のディスクの状態に正しくロールバックされていることが分かります。

まとめ..

KVMのスナップショット作成方法はいろいろな方式があるものの、スナップショット作成時点のディスクの状態に戻すためには、「virsh snapshot-revert」コマンドを使用する必要があり、更にそのためにスナップショット作成は、ディスク・メモリも含めたフルスナップショットをとる必要がある、という結論になりました。
ディスク・メモリも含めたフルスナップショットをとる方法には、仮想マシンを一時停止させてスナップショットをとる方法(2-2)、仮想マシンを停止させずにスナップショットをとる方法(2-3)の2つの選択がありますが、仮想マシンが高負荷にならない夜間に取得するのであれば、(2-2)の方法が良いのではないでしょうか。まあ、スナップショットからロールバックする必要があるのは、なんらかのトラブルが発生した状態であるので、メモリの状態はあまり重要ではない(例えば、ロールバックした後に、仮想マシンを再起動するようなケース)のであれば、(2-3)の方法でも良いかと思います。

(2-1)の方法が期待通りにならなかったのは残念ですが、私のやり方に間違いがあったのかもしれません。

広告主へのリンク




ミニPCのお勧め

おウチでLinuxを勉強するのに、ミニPCはどうですか。
仮想環境(KVM)使えば、仮想マシンを複数起動できますし、とても安価にシステム構築の練習ができます。ミニPCはとっても静かで消費電力も小さいので部屋で常時起動させています。

このブログにおける関連リンク

犬でも分かるKVMシリーズ

コメント

タイトルとURLをコピーしました