如果我希望拍摄正在运行的 KVM 来宾的外部快照,我将运行如下命令:
# create the directory for the snapshot data
mkdir /vms/$DOMAIN/snapshots/$SNAPSHOT_NAME
# create the snapshot
virsh snapshot-create-as \
--domain $DOMAIN $SNAPSHOT_NAME \
--diskspec vda,file=/vms/$DOMAIN/snapshots/$SNAPSHOT_NAME/disk.qcow2,snapshot=external \
--memspec file=/vms/$DOMAIN/snapshots/$SNAPSHOT_NAME/mem,snapshot=external \
--atomic
如果我的虚拟机被调用vm1
并且我的快照被调用base-installation
以在全新安装后立即拍摄快照,那么我可能会有如下的文件夹结构:
/
|- vms/
|- vm1/
|- disk.qcow2
|- snapshots/
|-base-installation/
|-disk.qcow2
|-mem
现在这个结构就是我想要的样子,但不幸的disk.qcow2
是文件方向错误(需要交换)。快照文件夹disk.qcow2
中的文件实际上base-installation
是覆盖磁盘映像,用于将所有未来写入虚拟机,而不是表示拍摄快照时磁盘状态的所需只读备份文件。该文件夹正下方的disk.qcow2 文件vm1
是只读备份文件,而不是最新的覆盖磁盘映像。
问题
有没有办法更改virsh snapshot-create-as
命令,以便它将只读支持文件存储到指定的disk-spec
路径,并将覆盖指针磁盘文件保留在原来的位置?或者,是否有解决方法,例如“暂停”VM、交换磁盘文件、更新来宾的 xml 定义,然后恢复 VM?理想情况下,我不想关闭访客或导致明显的停机时间。
答案1
我设法找到了一种解决方法,方法是在从元数据中删除快照并执行“真实”快照之前执行中间“快照”和块拉入该快照,从而导致覆盖图像回到我们开始的位置,并且数据位于快照文件夹。这有点麻烦,希望将来会有更好的本机解决方案,但是,我已经详细说明了下面的步骤,如果你像我一样迫不及待。
脚步
首先适当设置您的设置:
# Your settings may vary
DOMAIN="guest1"
SNAPSHOT_NAME="base-installation"
VMS_DIR="/vms"
现在我们创建用于存储快照数据的目录。
mkdir -p $VMS_DIR/$DOMAIN/snapshots/$SNAPSHOT_NAME
现在我们创建中间快照,它将在我们刚刚创建的快照目录中创建覆盖图像。
virsh snapshot-create-as \
--domain $DOMAIN intermediary_snapshot \
--diskspec vda,file=$VMS_DIR/$DOMAIN/snapshots/$SNAPSHOT_NAME/disk.qcow2,snapshot=external \
--memspec file=$VMS_DIR/$DOMAIN/snapshots/$SNAPSHOT_NAME/mem,snapshot=external \
--atomic
笔记:我在虚拟机中运行 ping,当该命令运行时,它似乎只暂停了一秒钟。
现在,我们使用 blockpull 将数据从支持文件移动到快照目录中的活动覆盖图像中。
virsh blockpull \
--domain $DOMAIN \
--path $VMS_DIR/$DOMAIN/snapshots/$SNAPSHOT_NAME/disk.qcow2 \
--wait \
--verbose
笔记:你必须不是提供--base
该命令的参数,否则它将不执行任何操作,因为如果您指定,--base
它会使该命令将指定的基础保留为基础目录,并且只会合并中间层(我们没有),而不是基础目录本身。
上一个命令花了我大约 30 秒,但虚拟机在这段时间内愉快地运行 ping。
ls -alh
显示快照目录的disk.qcow2
映像现在大小为 2.2GB,但更重要的是,qemu-img info disk.qcow2
现在没有显示任何备份文件,因此我们知道所有数据现在都在快照目录中,并且它是一个“独立映像”。
现在,我们通过删除此中间快照步骤的知识来清理元数据。
virsh snapshot-delete \
--domain $DOMAIN \
intermediary_snapshot \
--metadata
现在,我们还删除了不再需要的原始支持文件,以及我们永远不会使用的中间 memspec 文件。
rm $VMS_DIR/$DOMAIN/disk.qcow2
rm $VMS_DIR/$DOMAIN/snapshots/$SNAPSHOT_NAME/mem
此时,我测试了关闭然后手动启动实例以检查它是否正常并且一切正常。
此时,您可以认为已经完成了所有“准备”,现在我们只需拍摄快照,但指定覆盖图像位于顶级 $DOMAIN 目录中,并且 memspec 文件位于其备份磁盘图像旁边的快照文件夹中。
virsh snapshot-create-as \
--domain $DOMAIN $SNAPSHOT_NAME \
--diskspec vda,file=$VMS_DIR/$DOMAIN/disk.qcow2,snapshot=external \
--memspec file=$VMS_DIR/$DOMAIN/snapshots/$SNAPSHOT_NAME/mem,snapshot=external \
--atomic
就是这样!
存储影响
值得注意的是,如果您不断重复上述步骤来制作许多快照,您最终会得到完全可恢复的快照,这些快照不依赖于每个快照文件夹中的任何其他文件,但这会浪费大量空间。对于后续快照,您可能希望使用参数更改命令blockpull
,--base
让每个快照使用前一个快照作为后备映像,而不是合并它。
恢复快照
如果执行快照列表,您会看到新快照。但是,您将无法执行该virsh snapshot-revert
命令,因为尚不支持恢复外部快照(至少在我使用的 ubuntu 16.04 中不支持),因此我们需要通过销毁当前活动的覆盖图像来手动执行此操作......
rm $VMS_DIR/$DOMAIN/disk.qcow2
然后从我们希望恢复的快照基础图像创建一个新的覆盖图像:
qemu-img create \
-b $VMS_DIR/$DOMAIN/snapshots/$SNAPSHOT_NAME/disk.qcow2 \
-f qcow2 \
$VMS_DIR/$DOMAIN/disk.qcow2
现在您可以启动来宾了。
sudo virsh start $DOMAIN
不幸的是,我还没有弄清楚如何使用 memspec 文件,这是这个答案中缺少的最大的东西。
参考
在试图弄清楚这一切的过程中,有一个很棒的帖子 fedorapeople.org这解释了如何合并我认为最有帮助的外部快照。