スナップショットの機能を使うと、稼働中の仮想マシンの状態をディスクに保存することができます。そして、保存したスナップショットから、保存した時点の仮想マシンの状態に戻すことができます。調べてみると、いろいろなオプションがあって初めてのときには迷います。折角調べたので整理してみた情報を公開します。
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はとっても静かで消費電力も小さいので部屋で常時起動させています。



コメント