第七章 使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照
【KVM系列文章】https://blog.youkuaiyun.com/baidu_37107022/article/details/88812463
本文将梳理 QEMU/KVM 快照相关的知识,以及在 OpenStack Nova 中使用 libvirt 来对 QEMU/KVM 虚机做快照的过程。
1. QEMU/KVM 快照
1.1 概念
QEMU/KVM 快照的定义:
- 磁盘快照:磁盘的内容(可能是虚机的全部磁盘或者部分磁盘)在某个时间点上被保存,然后可以被恢复。
- 磁盘数据的保存状态:
- 在一个运行着的系统上,一个磁盘快照很可能只是崩溃一致的(crash-consistent) 而不是完整一致(clean)的,也是说它所保存的磁盘状态可能相当于机器突然掉电时硬盘数据的状态,机器重启后需要通过 fsck 或者别的工具来恢复到完整一致的状态(类似于 Windows 机器在断电后会执行文件检查)。
- 对一个非运行中的虚机来说,如果上次虚机关闭的时候磁盘是完整一致的,那么其被快照的磁盘快照也将是完整一致的。
- 磁盘快照有两种:
- 内部快照 - 使用单个的 qcow2 的文件来保存快照和快照之后的改动。这种快照是 libvirt 的默认行为,现在的支持很完善(创建、回滚和删除),但是只能针对 qcow2 格式的磁盘镜像文件,而且其过程较慢等。
- 外部快照 - 快照是一个只读文件,快照之后的修改是另一个 qcow2 文件中。外置快照可以针对各种格式的磁盘镜像文件。外置快照的结果是形成一个 qcow2 文件链:original <- snap1 <- snap2 <- snap3。http://wiki.libvirt.org/page/Qemu_guest_agent
快照还可以分为 live snapshot(热快照)和 Clod snapshot:
- Live snapshot:系统运行状态下做的快照
- Cold snapshot:系统停止状态下的快照
libvit 做 snapshot 的各个 API:
snapshot 做快照的 libvirt API 从快照恢复的 libvirt API virsh 命令 磁盘快照 virDomainSnapshotCreateXML(flags = VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY ) virDomainRevertToSnapshot virsh snapshot-create/snapshot-revert 内存(状态)快照 virDomainSave
virDomainSaveFlags
virDomainManagedSave
virDomainRestore
virDomainRestoreFlags
virDomainCreate
virDomainCreateWithFlags
virsh save/restore
系统检查点 virDomainSnapshotCreateXML virDomainRevertToSnapshot virsh snapshot-create/snapshot-revert 分别来看看这些 API 是如何工作的:
1. virDomainSnapshotCreateXML (virDomainPtr domain, const char * xmlDesc, unsigned int flags)
作用:根据 xmlDesc 指定的 snapshot xml 和 flags 来创建虚机的快照。
flags 包含 虚机处于运行状态时快照的做法 虚机处于关闭状态时快照的做法 0 创建系统检查点,包括磁盘状态和内存状态比如内存内容 保持关机时的磁盘状态 VIR_DOMAIN_SNAPSHOT_CREATE_LIVE 做快照期间,虚机将不会被 paused。这会增加内存 dump file 的大小,但是可以减少系统停机时间。部分 Hypervisor 只在做外部的系统检查点时才设置该 flag,这意味着普通快照还是需要暂停虚机。 VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY 只做指定磁盘的快照。对应运行着的虚机,磁盘快照可能是不完整的(类似于突然电源被拔了的情形)。 只做指定磁盘的快照。 其内部实现根据虚机的运行状态有两种情形:
- 对运行着的虚机,API 使用 QEMU Monitor 去做快照,磁盘镜像文件必须是 qcow2 格式,虚机的 CPU 被停止,快照结束后会重新启动。
- 对停止着的虚机,API 调用 qemu-img 方法来操作所有磁盘镜像文件。
这里有其实现代码,可见其基本的实现步骤:
static virDomainSnapshotPtr qemuDomainSnapshotCreateXML { .... call qemuDomainSnapshotCreateDiskActive { call qemuProcessStopCPUs # 停止 vCPUs for each disk call qemuDomainSnapshotCreateSingleDiskActive { call qemuMonitorDiskSnapshot # 调用 QEMU Monitor 去为每个磁盘做snapshot } call qemuProcessStartCPUs # 启动 vCPUs } .... }
2. virDomainSave 相关的几个 API
这几个API 功能都比较类似:
virDomainSave 该方法会 suspend 一个运行着的虚机,然后保存期内存内容到一个文件中。成功调用以后,domain 将不会处于 running 状态。使用 virDomainRestore 来恢复虚机。 virDomainSaveFlags 类似于 virDomainSave API,可使用几个 flags。一些 Hypervisor 在调用该方法前需要调用 virDomainBlockJobAbort() 方法来停止 block copy 操作。 virDomainManagedSave 也类似于 virDomainSave API。主要区别是 libvirt 将其内存保存到一个受 libvirt 管理的文件中,因此libvirt 可以一直跟踪 snapshot 的状态;当调用 virDomainCreate/virDomainCreateWithFlags 方法重启该 domain的时候,libvirt 会使用该受管文件,而不是一个空白的文件,这样就可以 restore 该snapshot。 Features/SnapshotsMultipleDevices 这篇文章讨论同时对多个磁盘做快照的问题。
1.2 使用 virsh 实验
1.2.1 virsh save 命令
对运行中的 domain d-2 运行 “virsh save” 命令。命令执行完成后,d-2 变成 “shut off” 状态。
看看 domain 的磁盘镜像文件和 snapshot 文件:
- 磁盘数据的保存状态: