用libvirt为虚拟机创建快照

kvm 2018-06-11

快照的类型

kvm环境下 qcow2 的镜像支持快照,有几种类型的快照:

  • 磁盘快照:磁盘的内容(vm关联的所有磁盘)都会在给定的时间点保存,并且可以恢复到该状态。如果是正在运行的vm,磁盘快照很可能只是崩溃的(它表示突然停电时的磁盘状态)。磁盘快照可以可以放在内部也可以放在外部。
    • 按快照信息保存可以分为:内置快照和外置快照;
    • 按照vm状态可以分为:关机状态快照和运行状态快照;
    • 按磁盘数量可以分为:单盘和多盘;多盘情况具有原子性,即所有盘的快照点相同,并且创建快照时,要么都快照成功,要么都快照失败。
  • 内存状态:仅保存内存的状态以及vm正在使用的其他资源。如果在获取和恢复vm状态快照之间磁盘未被修改,则guest虚拟机将恢复一致状态;但如果在此期间磁盘被外部修改,则很可能导致数据损坏;
  • 系统检查点:所有磁盘的磁盘快照和vm内存状态的组合,可用于恢复客户机从停止位置恢复类似于休眠的状态。

libvirt 来创建快照

libvirt 可以管理所有三种类型的快照。快照可以通过底层的 virDomainSave()virDomainSaveFlags()virDomainManagedSave() 功能,这三个函数对应到 libvirt api中是 virDomain.save() 等:

class virDomain(object):
    # ...
    def save(self, to):
        """
        此方法会暂停vm,也会对内存进行快照处理,保存成功后,vm不会处于running状态。
        通过virDomainRestore()函数进行快照恢复
        """
        ret = libvirtmod.virDomainSave(self._o, to)
        if ret == -1: raise libvirtError ('virDomainSave() failed', dom=self)
        return ret

    def saveFlags(self, to, dxml=None, flags=0):
        """
        与save一样,但功能更多,如设置flags为VIR_DOMAIN_SAVE_BYPASS_CACHE,
        那么就会视图绕过文件缓存系统
        """
        ret = libvirtmod.virDomainSaveFlags(self._o, to, dxml, flags)
        if ret == -1: raise libvirtError ('virDomainSaveFlags() failed', dom=self)
        return ret

    def managedSave(self, flags=0):
        """
        也与virDomainSave()基本一样,区别在于此方法能跟踪
        保存的状态本身(如:正在运行或暂停),在恢复时候也能恢复到相同的状态,
        因此这种方式更适合持久的vm
        """
        ret = libvirtmod.virDomainManagedSave(self._o, flags)
        if ret == -1: raise libvirtError ('virDomainManagedSave() failed', dom=self)
        return ret        

snapshotCreateXML

但实际上,用的最多的最主流的其实是 virDomain.snapshotCreateXML() 函数:

    def snapshotCreateXML(self, xmlDesc, flags=0):
        ret = libvirtmod.virDomainSnapshotCreateXML(self._o, xmlDesc, flags)
        if ret is None:raise libvirtError('virDomainSnapshotCreateXML() failed', dom=self)
        __tmp = virDomainSnapshot(self,_obj=ret)
        return __tmp

该方法通过一个XML描述字符串(不是文件)和标志位创建快照的功能,常见标志位有:

  • 如果 flag = 0: vm的状态可以是正在运行的,这种情况下,快照将会是一个系统检查点,恢复后会vm会是相同的状态。
  • 如果 flag 包含 VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE ,那么快照先前的快照元数据会被删除,这个标记是为了方便迁移的,如果快照元数据仍然保留在源上,通常会失败。
  • 如果 flag 包含 VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA ,创建快照时不保存元数据;
  • 如果 flag 包含 VIR_DOMAIN_SNAPSHOT_CREATE_HALT ,那么在做快照完成之后vm将不活动;
  • 如果 flag s包含 VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY , 那么快照仅对磁盘做,不会保存vm状态,对于恢复的vm来说,这就像突然断线一样;

快照XML格式

快照xml字符串大致如下:

<domainsnapshot>
  <description>Snapshot of OS install and updates</description>
  <memory snapshot ='no'/>
  <disks>
    <disk name='/path/to/old'>
      <source file='/path/to/new'/>
    </disk>
    <disk name='vdb' snapshot='no'/>
  </disks>
</domainsnapshot>

<domainsnapshot> 是顶层标签; <memory> 是执行如何处理vm内存状态,对于不在running的vm来说,必须设置为no,因此没有保存虚拟机的状态; <disks> 来指定哪些磁盘需要做快照,如果没指定,则表示所有与vm关联的磁盘;在 <disk> 中,如果快照想外部存储,那就用 <source> 来指定目标文件。

更多格式介绍可以查看: https://libvirt.org/formatsnapshot.html


本文由 hongweipeng 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

赏个馒头吧