针对libvirt虚拟机主要有两类的快照:内部和外部,它们每一个都有它们的优势和劣势。

内部快照:在你快照后文件还是一个镜像文件,virt-manager提供了一个图形工具去管理内部快照。下面是几个内部快照的限制。

  1. 仅支持qcow2格式。
  2. 当快照时,虚拟机是暂停的。
  3. 不支持LVM存储沲。

外部快照:是基于写时复制的概念,当创建快照时,源镜象变成只读和新一个磁盘镜像层被自动创建。(不支持图形界面管理)

只介绍几个常用的磁盘格式:

  • raw: 由于这个格式没有附加的源数据源层,因此它有非常小的负载,有着较高的性能优势 。当然它缺少了个比如内部快照、压缩和其它特性。假如你运行高度的I/0密集应用,强烈建议采用这种格式 。
  • qcow2:这是专门给虚拟化,像云这些设计的。支持快照(内部和外部),压缩、加密等。也支持按需分配和预先分配的方式。

可以使用以下两种方式去看下VM disk 镜像的格式。

第一种方式:
$ sudo  file disk1
disk1: QEMU QCOW Image (v3), 1073741824 bytes

$ sudo  file disk2
diskd: data
第二种方式:
$ sudo  qemu-img info disk1
image: disk1
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false

磁盘格式转换:

RAW to QCOW2:
$ qemu-img convert -f raw -O qcow2 vm_disk1.img vm_disk1.qcow2
QCOW2 to RAW:
$ qemu-img convert -f qcow2 -O ram vm_disk2.qcow2 vm_disk2.img

内部快照:

下面我们主要介绍创建、删除、和还原(内部快照)。
仅仅qcow2的磁盘支持内部快照。如果不是这个格式 话使用qemu-img命令进行转换。

在这里我们使用的虚拟机CentOS_01来做内部快照的案例。

(1)校验我们用的主机镜像信息

$ sudo  virsh snapshot-list CentOS_01
 Name               Creation Time           State
-------------------------------------------------

(2)创建内部快照,我们这里列出和快照相关的命令简单介绍。

snapshot-create: 基于xml文件创建快照。
snapshot-create-as: 从创建的指令中创建快照。
snapshot-current: 获得或者设置当前快照。
snapshot-delete:删除一个域的快照。
snapshot-dumpxml:备份一个域的快照。
snapshot-edit:编辑快照。
snapshot-info:获取一个快照的信息。
snapshot-list: 列出这个域的快照。
snapshot-parent: 获取这个快照的父快照。
snapshot-revert: 还原快照。

创建内部快照的简单示例:

$ sudo vrish snapshot-create CentOS_01

(3)使用定义的名字和描述来创建快照。

$ sudo virsh snpahsot-create-as CentOS_01 --name "Snapshot 1" --description"Frist snapshot" --atomic

我们在创建快照时,强烈建议使用--atomic,这就相当于Mysql的事务一样。

(4)校验刚才我们创建的快照。

$ sudo virsh snapshot-list CentOS_01
 Name               Creation Time           State
----------------------------------------------------
 snapshot1          2015-08-19 08:41:23 +0530 running

(5)我们执行第三步创建多个快照,看下父子关系等。和怎么还原,创建好后结果应该如下:

$ sudo  virsh snapshot-list CentOS_01 --parenet
 Name               Creation Time             State         Parent
--------------------------------------------------------------------
 Snapshot1          2015-08-19 09:00:13 +0530 running       (null)
 Snapshot2          2015-08-19 09:00:43 +0530 running      Snapshot1
 Snapshot3          2015-08-19 09:01:00 +0530 shutoff      Snapshot2

也可以使用--tree的选项,来显示快照的间的关系 。
$ sudo virsh snaphshot-list CentOS_01 --tree

我们也可以使用qemu-img来快照硬盘的详细信息。

$ sudo  qemu-img info /var/lib/libvirt/qemu/vmdisk1.qcow2
image: /var/lib/libvirt/qemu/vmdisk1.qcow2
file format: qcow2
virtual size: 8.0G (8589934592 bytes)
disk size: 1.6G
cluster_size: 65536
Snapshot list:
ID    TAG               VM SIZE            DATE    VM CLOCK
1     1439951249        220M 2015-08-19 07:57:29   00:09:36.885
2     Snapshot1         204M 2015-08-19 09:00:13   00:01:21.284
3     Snapshot2         204M 2015-08-19 09:00:43   00:01:47.308
4     Snapshot3            0 2015-08-19 09:01:00   00:00:00.000
Format specific information:

我们也可以使用check选项来校验我们的磁盘信息。
$ sudo qemu-img check /var/lib/libvirt/qemu/vmdisk1.qcow2

还原内部快照:

还原快照的命令格式如下:
$ sudo virsh snapshot-revert <vm-name> --snapshotname "Snapshot1"

删除内部快照:

$ sudo  virsh snapshot-list CentOS_01
 Name               Creation Time             State
------------------------------------------------------
 Snapshot1          2015-08-19 09:00:13 +0530 running
 Snapshot2          2015-08-19 09:00:43 +0530 running
 Snapshot3          2015-08-19 09:01:00 +0530 shutoff
 snapshot4          2015-08-19 10:17:00 +0530 shutoff
$ sudo  virsh snapshot-delete CentOS_01 Snapshot2
Domain snapshot Snapshot2 deleted
$ sudo  virsh snapshot-list CentOS_01
 Name               Creation Time             State
------------------------------------------------------
 Snapshot1          2015-08-19 09:00:13 +0530 running
 Snapshot3          2015-08-19 09:00:43 +0530 running
 snapshot4          2015-08-19 10:17:00 +0530 shutoff

使用vrit-manager管理快照(略)

外部快照:

几乎所有格式的磁盘的镜像都支持外部快照。

创建外部快照:

(1)查看我们要使用做实验的虚拟机详细信息。

$ sudo  virsh domblklist Win7_01 --details
Type     Device   Target   Source
------------------------------------------------
file     disk     vda      /vmstore1/win7_01.img

(2)检查我们想要做快照的虚拟机是否在运行状态 。

$ sudo  virsh list 
 Id  Name                         State
-----------------------------------------
 4   Win7_01                      running

无论主机是否在运行状态或者是离线状态,我们都可以经主机创建外部快照。

(3)创建快照

$ sudo  virsh snapshot-create-as win7_01 snapshot1 "My First Snapshot" --disk-only --atomic
--disk-only参数是指仅仅对磁盘做快照。
--atomic: 这往往是保证数据的完整性,证明要么失败要么成功,不会停留在中间状态 。造成数据的不一致。

(4)上面的快照仅是磁盘的状态 ,不包括内存的。

$ sudo virsh snapshot-info win7_01 snapshot1

(5) 现在列出我们刚才的虚拟机的关联的磁盘。

$ sudo virsh domblklist win7_01
从上面的结果我们可以看到,我们磁盘的源改变了。

(6)我们来查看我们的源磁盘信息。

$ qemu-img info /vmstore1/win7_01.snapshot1
image: /vmstore1/win7_01.snapshot1
file format: qcow2
virtual size: 19G (20401094656 bytes)
disk size: 1.6M
cluster_size: 65536
backing file: /vmstore1/win7_01.img
backing file format: raw

从以上的信息我们看到backing file是指向/vmstore1/win7_01.img

(7)以上的信息表明了我们的新镜像/vmstore1/win7_01.snapshot1目前是可读写的,它的源镜像是/vmstore1/win7_01.img 。

vmstore1/win7_01.img = is backing file (original disk )
/vmstore1/win7_01.snapshot1 = is newly created overlay image where now all the writes are happening

(8)现在我们创建第二个快照,这次创建时,我们把它保存在不同的地方 。默认快照和磁盘是在相同的存储沲里面的。

$ sudo  virsh snapshot-create-as Win7_01 snapshot2 "Second snapshot" --disk-only --diskspec vda, snapshot=external, file=/snapshot_store/win7_01.snapshot2 --atomic
以上--diskspec这个选项是创建快照在别的位置。 这个选项要按照如下格式 :disk[,snapshot=type][,driver=type][,file=name] format.

(9)配置第三个快照

$ sudo  virsh snapshot-create-as Win7_01 snapshot3 "Third Snapshot" --disk-only --quiesce
       Domain snapshot snapshot3 created
  • quiesce: Quiesce是一个文件系统冻结的机制。它使文件系统能够进行一致的状态。假如没有这个选项的话,这个块照将不会包含脏数据。也就是说,在快照期间,可能会导致镜像的错误。需要使用该功能的话,qemu-agent也需要安装。要不然会报如下错误。
  • error: Guest agent is not responding: Guest agent not available for now

让我们看一下,各个快照 之间的链是怎么样的一个形式。

1. 列出虚拟机关联的所有快照 。

$ sudo  virsh snapshot-lsit Win7_01
 Name              Creation Time           State
----------------------------------------------------------
 snapshot1         2015-08-21 10:21:38 +0530 disk-snapshot
 snapshot2         2015-08-21 11:51:04 +0530 disk-snapshot
 snapshot3         2015-08-21 11:55:23 +0530 disk-snapshot

2. 检查对于当前磁盘而言,哪一个是活动的磁盘快照 。

$ sudo  virsh domblklist Win7_01
Target   Source
------------------------------------------------
vda      /snapshot_store/win7_01.snapshot3

(3) 使用以下命令进行查看各个间的关系。

$ qemu-img info --backing-chain /snapshot_store/win7_01.snapshot3| grep backing
backing file: /snapshot_store/win7_01.snapshot2
backing file format: qcow2
backing file: /vmstore1/win7_01.snapshot1
backing file format: qcow2
backing file: /vmstore1/win7_01.img
backing file format: raw

也可以看下面的图进行理解它们之间的关系。

从外部快照进行还原

外部快照可以在主机活动或离线状态创建,但是却没有什么内建的特去还原和删除快照。假如你使用virsh 还原外部快照的话。那么将会报错。

$ sudo  virsh snapshot-revert Win7_01 --snapshotname "snapshot3"
error: unsupported configuration: revert to external snapshot not supported yet

我们可以手动的还原:

(1)查看我们已经有的快照 。

$ sudo  virshj snapshot-list Win7_01
 Name               Creation Time           State
------------------------------------------------------------
 snapshot1          2015-08-21 10:21:38 +0530 disk-snapshot
 snapshot2          2015-08-21 11:51:04 +0530 disk-snapshot
 snapshot3          2015-08-21 11:55:23 +0530 disk-snapshot

假如我们想还原snapshot2的话,首先我们是需要关闭虚拟机,和编辑指向snapshot2磁盘的XML文件。

(1) # virsh snapshot-dumpxml Win7_01 --snapshotname snapshot2 | grep 'source file' | helad -1
  

(2) 从上面我们可以看到,快照 snapshot2关联的文件是,/snapshot_store/win7_01.snapshot2文件,校验它的完整性。

#qemu-img check /snapshot_store/win7_01.snapshot2
No errors were found on the image.
46/311296 = 0.01% allocated, 32.61% fragmented, 0.00% compressed clusters
Image end offset: 3670016

如果上面检测报错误的话,我们可以使用-r leaks/all参数来进行修复。但不能保证一定能够修复好。

(3)现在我们去操作XML文件,我们可以从XML文件/snapshot_store/win7_01.snapshot2中添加或者移除磁盘。编辑和修改磁盘的路径。可以使用virt-xml命令。

$ sudo  virt-xml Win7_01 --remove-device --disk target-=vda
$ sudo  vir-xml --add-device --disk /snapshot_store/win7_01.snapshot2,format=qcow2, bus=virtio

(4)上面的命令我们添加了win7_01.snapshot2作为我们的启动盘。通过以下的命令进行校验

$ sudo  virsh domblklist Win7_01
Target   Source
------------------------------------------------
vda      /snapshot_store/win7_01.snapshot2

(5)然后开启虚拟机,回到我们以前的snapshot2的状态了。

删除外部快照

删除快照也是一个特别麻烦的流程,我们需要手工的把原先的基本层 进行合并后,才能删除快照。针对两并快照 ,有两种方式:
blockcommit: 合并基本层的数据,这样的方式是比较快的。因为这相当于把后面的快照文件往基本的镜像文件里面去合并。
blockpull: 使用这种机制恰恰和上面的那种方式相反,会比较慢一点。这个合并的文件须是qcow2文件。

使用blcokcommit合并外部的快照:

(1)列出当前使用的活动磁盘。

$ sudo  virsh domblklist VM1
Target   Source
----------------------------
hda      /vmstore1/vm1.snap4

(2)现在列举了出后备的文件链/vmstore1/vm1.snap4

#qemu-img info --backing-chain /vmstore1/vm1.snap4 | grep  backing
backing file: /vmstore1/vm1.snap3
backing file format: qcow2
backing file: /vmstore1/vm1.snap2
backing file format: qcow2
backing file: /vmstore1/vm1.snap1
backing file format: qcow2
backing file: /vmstore1/vm1.img
backing file format: raw

3.现在合并所有的快照 镜像到基本的镜像。

#virsh blockcommit VM1 hda --verbose --pivot --active
Block Commit: [100 %]
Successfully pivoted

4. 现在检查当前活动的磁盘快设备。

$ sudo  virsh domblklist VM1
Target   Source
--------------------------
hda      /vmstore1/vm1.img

虽说我们合并完成了,但是我们查看该虚拟机的快照 时,仍然有4个快照 。如下图所示:

$ sudo  virsh snapshot-list VM1
Name                Creation Time             State
-----------------------------------------------------
 snap1              2015-08-22 09:10:56 +0530 shutoff
 snap2              2015-08-22 09:11:03 +0530 shutoff
 snap3              2015-08-22 09:11:09 +0530 shutoff
 snap4              2015-08-22 09:11:17 +0530 shutoff

移除快照使用如下命令:

$ sudo  virsh snapshot-delete VM1 snap1 --children --metadata
$ sudo  virsh snapshot-list VM1
Name               Creation Time           State
------------------------------------------------------------

使用blockpull的方式合并外部快照。

(1)列出当前活动的磁盘。
$ sudo  virsh domblklist VM2
Target   Source
----------------------------
hda      /vmstore1/vm2.snap1

(2)现在列出支持的文件链/vmstore1/vm1.snap4:

$ sudo qemu-img info --backing-chain /vmstore1/vm2.snap1 | grep  backing
backing file: /vmstore1/vm1.img
backing file format: raw

(3)合并基本的镜像到快照的镜像。

$ sudo virsh blockpull VM2 --path /vmstore1/vm2.snap1 --wait --verbose
Block Pull: [100 %]
Pull complete

(4)现在移除基本的镜像文件

$ sudo virsh snapshot-delete VM1 snap1 --metadata
我们在合并和删除快照的任务时,不需要把虚拟机停机。