700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > KVM libvirt 虚拟机快照技术

KVM libvirt 虚拟机快照技术

时间:2024-07-23 03:59:39

相关推荐

KVM libvirt 虚拟机快照技术

kvm+libvirt虚拟机快照浅析

浅析snapshots, blockcommit,blockpull

作者:Kashyap Chamarthy <kchamart#>

Date: Tue, 23 Oct 15:28:06 +0530

这是一篇关于snapshots, blockpull, blockcommit的的介绍.作者和with Eric Blake, Jeff Cody,

Kevin Wolf以及很多IRC和mailing lists里面的同学大量讨论以及作者大量的特向测试的基础之上

总结出来的

作者也正在准备写一些关于blockcopy部分的文档,但这要等他完成blockcopy的测试之后.

作者欢迎评论欢迎拍砖.(我表示也欢迎)

---

docs/snapshots-blockcommit-blockpull.rst

..--------------------------------------------------------------

注意: 所有测试都是在最新的 qemu-git,libvirt-git (as of

20-Oct- 在 Fedora-18 alpha系统上倒腾出来的

..--------------------------------------------------------------

基础知识

一个虚拟机快照可被看作是虚拟机的在某个指定时间的视图(包括他的操作系统和所有的程序).

据此,某可以还原到一个之前的完整的状态,或者在guest运行的时候做个备份.所以,在我们

继续深入之前我们必须搞懂两个名词:backing files和overlays .

QCOW2 backing files 与 overlays

qcow2(qemu copy-on-write)具有创建一个base-p_w_picpath,以及在base-p_w_picpath(即backing file)

的基础上创建多个copy-on-write overlays镜像的能力.backing files和overlays十分有用,

可以迅速的创建瘦装备虚拟机的实例,特别是在开发测试的时候可以让你迅速的回滚到之前的某个

已知状态,丢弃overlay.

Figure-1

.--------------..-------------..-------------..-------------.|||||||||RootBase|<---|Overlay-1|<---|Overlay-1A<---|Overlay-1B||(raw/qcow2)||(qcow2)||(qcow2)||(qcow2)|'--------------''-------------''-------------''-------------'

上图表明rootbase是overlay-1的backing file,以此类推.

Figure-2

.-----------..-----------..------------..------------..------------.|||||||||||RootBase|<---Overlay-1|<---Overlay-1A<---Overlay-1B<---Overlay-1C||||||||||(Active)|'-----------''-----------''------------''------------''------------'^^||||.-----------..------------.|||||||'-------|Overlay-2|<---|Overlay-2A|||||(Active)||'-----------''------------'|||.-----------..------------.|||||'------------|Overlay-3|<---|Overlay-3A||||(Active)|'-----------''------------'

上图表明我们可以只用单个backing file来创建多条链.

注意: backing file 总是只读打开的. 换言之, 一旦新快照被创建,

他的后端文件就不能被修改,(快照依赖于后端文件的这种状态).

了解更多参见后面的('blockcommit' 节) .

示例:

[FedoraBase.img]-----<-[Fed-guest-1.qcow2]<-[Fed-w-updates.qcow2]<-[Fedora-guest-with-updates-1A]\\---<-[Fed-guest-2.qcow2]<-[Fed-w-updates.qcow2]<-[Fedora-guest-with-updates-2A]

(注意箭头的方向,Fed-w-updates.qcow2 的backing file是 Fed-guest-1.qcow2)

上面的示例中可以看到FedoraBase.img安装了一个fedora17系统,并作为我们的backing file.

现在这个backing file将作为模板快速的创建两个瘦装备实例,和Figure-2道理是一样的.

使用qemu-img为单个backing file来创建两个fedora的瘦装备克隆:

#qemu-imgcreate-b/export/vmp_w_picpaths/RootBase.img-fqcow2\/export/vmp_w_picpaths/Fedora-guest-1.qcow2#qemu-imgcreate-b/export/vmp_w_picpaths/RootBase.img-fqcow2\/export/vmp_w_picpaths/Fedora-guest-2.qcow2

现在,上面创建出来的两个镜像Fedora-guest-1&Fedora-guest-2都可以用来

启动一个虚拟机,继续我们的示例,现在我们需要创建一个f17的实例,但是这次我们需要

创建的是具有完整的更新的实例,这时可以创建另外一个overlay(Fedora-guest-with-updates-1A)

而这个overlay的backing file是'Fed-w-updates.qcow2'(一个包含了完整更新的镜像):

#qemu-imgcreate-b/export/vmp_w_picpaths/Fed-w-updates.qcow2-fqcow2\/export/vmp_w_picpaths/Fedora-guest-with-updates-1A.qcow2

我们可以使用qemu-img命令来查看镜像的信息,包括虚拟磁盘大小,使用大小,backing file指向:

#qemu-imginfo/export/vmp_w_picpaths/Fedora-guest-with-updates-1A.qcow2

注意: 最新版本的qemu-img可以递归查询到整条完整的链:

#qemu-imginfo--backing-chain/export/vmp_w_picpaths/Fedora-guest-with-updates-1A.qcow2

名词解释Snapshot:

内置快照(Internal Snapshots)-- 单个qcow2镜像文件存储了包括数据以及快照的状态信息,

内置快照又可以细分一下:-

Libvirt 使用'savevm' 命令来创建这种快照

Libvirt 使用 'qemu-img' 命令创建关机状态的磁盘快照.

Libvirt 使用 'savevm' 命令创建运行状态的磁盘快照.

内置磁盘快照(Internal disk snapshot):

快照点的磁盘状态,数据和快照保存在单个qcow2文件中,虚拟机运行状态和关闭状态都

可以创建.

内置系统还原点(Internal system checkpoint):

内存状态,设备状态和磁盘状态,可以为运行中的虚拟机创建,所有信息都存储在

同一个qcow2文件中,只有在运行状态才能创建内置系统还原点.

外置快照(External Snapshots)-- 当一个快照被创建时,创建时当前的状态保存在当前使用

的磁盘文件中,即成为一个backing file.

此时一个新的overlay被创建出来保存往后的数据.

这个也可以细分一下:-

Libvirt 使用 'transaction' 命令来为运行状态创建这种快照.

Libvirt 使用'qemu-img' 命令为关闭状态创建这种快照(截止目前功能还在开发中).

外置磁盘快照(External disk snapshot):

磁盘的快照被保存在一个文件中,创建时间点以后的数据被记录到一个新的qcow2文件中.

同样可以在运行和关闭状态创建.

外置系统还原点(External system checkpoint):

虚拟机的磁盘状态将被保存到一个文件中,内存和设备的状态将被保存到另外一个新的文件中,

(这个功能也还在开发中).

VM状态(VM state):

保存运行状态虚拟机的内存设备状态信息至文件,可以通过此文件恢复到保存时的状态,有点类似系统

的休眠.(注意创建VM状态保存的时候VM磁盘必须是未发生写入改动的)

Libvirt使用 'migrate' (to file)命令来完成VM状态转储.

创建snapshots

每次产生一个外置snapshot,一个 /new/ overlay 镜像就会随之生成,而前一个镜像就变成了一个快照.

diskonly内置快照创建

假如需要为名为'f17vm1'的虚拟机创建一个运行态或关闭态的内置快照snap1

#virshsnapshot-create-asf17vm1snap1snap1-desc

列出快照列表,使用*qemu-img*查看info

#virshsnapshot-listf17vm1#qemu-imginfo/home/kashyap/vmp_w_picpaths/f17vm1.qcow2

disk-only外置快照创建:

查看虚拟机磁盘列表

#virshdomblklistf17-baseTargetSource---------------------------------------------vda/export/vmp_w_picpaths/f17-base.qcow2#

创建外置disk-only磁盘快照(VM*运行态*):

#virshsnapshot-create-as--domainf17-basesnap1snap1-desc\--disk-only--diskspecvda,snapshot=external,file=/export/vmp_w_picpaths/sn1-of-f17-base.qcow2\--atomicDomainsnapshotsnap1created#*一旦上面的命令被执行,则原来的镜像f17-base将变为backingfile,一个新的镜像被创建.

现在再列表查看虚拟机磁盘,你会发现新产生的镜像已经投入使用.

#virshdomblklistf17-baseTargetSource----------------------------------------------------vda/export/vmp_w_picpaths/sn1-of-f17-base.qcow2#

快照回滚

截止写此文之时,回滚至'内置快照'(system checkpoint或disk-only)是可以使用的.

虚拟机f17vm1回滚至快照'snap1'

#virshsnapshot-revert--domainf17vm1snap1

使用snapshot-revert回滚 '外置磁盘快照' 稍微复杂些,需要涉及到稍微复杂点的问题,

需要考虑的是合并'base'至'top'还是合并'top'至'base'.

也就是说,有两种方式可以选择,外置磁盘快照链的缩短可以使用blockpullblockcommit.

截止目前上游社区仍然在努力完善这项功能.

合并快照文件

外置快照非常有用,但这里有一个问题就是如何合并快照文件来缩短链的长度,如上所述这里

有两种方式:

blockcommit: 从top合并数据到base(即合并overlays至backing files).

blockpull: 将backing file数据合并至overlay中.从basetop.

blockcommit

blockcommit可以让你将'top'镜像(在同一条backing file链中)合并至底层的'base'镜像.

一旦blockcommit执行完成,处于最上面的overlay链关系将被指向到底层的overlay或base.

这在创建了很长一条链之后用来缩短链长度的时候十分有用.

下面来个图说明下:

我们现在有一个镜像叫'RootBase',拥有4个外置快照,'Active'为当前VM写入数据的,

使用'blockcommit'可以有以下多种case :

合并Snap-1, Snap-2 and Snap-3 至 'RootBase'

只合并Snap-1 and Snap-2 至 RootBase

只合并Snap-1 至 RootBase

合并Snap-2 至 Snap-1

合并Snap-3 至 Snap-2

合并Snap-2 和 Snap-3 至 Snap-1

注: 合并'Active'层(最顶部的overlay)至backing_files的功能还在开发中.

(下图解释case (6))

Figure-3

.------------..------------..------------..------------..------------.|||||||||||RootBase<---Snap-1<---Snap-2<---Snap-3<---Snap-4||||||||||(Active)|'------------''------------''------------''------------''------------'/|/|/commitdata|/|/|/|vcommitdata|.------------..------------.<--------------------'.------------.|||||||RootBase<---Snap-1|<---------------------------------|Snap-4|||||BackingFile|(Active)|'------------''------------''------------'

举个例子,有以下场景:

当前: [base] <- sn1 <- sn2 <- sn3 <- sn4(this is active)

目标: [base] <- sn1 <- sn4 (如此来丢弃sn2,sn3)

下面有两种方式,method-a更快,method-b 慢些,但是sn2有效可用. (VM运行态).

(method-a):

# virsh blockcommit --domain f17 vda --base /export/vmp_w_picpaths/sn1.qcow2 \

--top /export/vmp_w_picpaths/sn3.qcow2 --wait --verbose

[OR]

(method-b):

#virshblockcommit--domainf17vda--base/export/vmp_w_picpaths/sn2.qcow2\

--top/export/vmp_w_picpaths/sn3.qcow2--wait--verbose#virshblockcommit--domainf17vda--base/export/vmp_w_picpaths/sn1.qcow2\

--top/export/vmp_w_picpaths/sn2.qcow2--wait--verbose

注:如果手工执行*qemu-img*命令完成的话,现在还只能用method-b.

Figure-4

.------------..------------..------------..------------..------------.|||||||||||RootBase<---Snap-1<---Snap-2<---Snap-3<---Snap-4||||||||||(Active)|'------------''------------''------------''------------''------------'/||/||/||commitdata/commitdata||/||/|commitdata|v||.------------.<----------------------|-------------'.------------.||<----------------------'|||RootBase||Snap-4|||<-------------------------------------------------|(Active)|'------------'BackingFile'------------'

上图演示了case1的blockcommit走向,现在sn4的backing file指向rootbase.

blockpull

blockpull(qemu中也称作'block stream')可以将backing合并至active,与blockcommit正好相反.

截止目前只能将backing file合并至当前使用的active中,也就是说还不支持指定top的合并.

设想一个下面的场景:

Figure-5

.------------..------------..------------..------------..------------.|||||||||||RootBase<---Snap-1<---Snap-2<---Snap-3<---Snap-4||||||||||(Active)|'------------''------------''------------''------------''------------'||\||\||\||\streamdata||streamdata\|streamdata|\||v.------------.|'--------------->.------------.||'--------------------------------->|||RootBase||Snap-4|||<----------------------------------------|(Active)|'------------'BackingFile'------------'

使用blockpull我们可以将snap-1/2/3中的数据合并至active层,最终rootbase将变成active的直接后端.

命令如下:

假设快照已经使用创建Snapshots小节中的方式完成:

如*Figure-5*中描述的-- [RootBase] <- [Active].

#virshblockpull--domainRootBase\--path/var/lib/libvirt/p_w_picpaths/active.qcow2\--base/var/lib/libvirt/p_w_picpaths/RootBase.qcow2\--wait--verbose

后续的工作是我们需要使用virsh来清理掉不用的快照

#virshsnapshot-delete--domainRootBaseSnap-3--metadata#virshsnapshot-delete--domainRootBaseSnap-2--metadata#virshsnapshot-delete--domainRootBaseSnap-1--metadata

Figure-6

.------------..------------..------------..------------..------------.|||||||||||RootBase<---Snap-1<---Snap-2<---Snap-3<---Snap-4||||||||||(Active)|'------------''------------''------------''------------''------------'|||\|||\|||\streamdata|||streamdata\|||\||streamdata|\|streamdata|'------------------>v||.--------------.|'--------------------------------->||||Snap-4|'---------------------------------------------------->|(Active)|'--------------''Standalone'(w/obackingfile)

上图表示的是将所有backing file全部合并至active

如下执行命令:(1)在我们执行合并*之前*查看一下快照的大小(注意观察'Active'):::#ls-lash/var/lib/libvirt/p_w_picpaths/RootBase.img608M-rw-r--r--.1qemuqemu1.0GOct1117:54/var/lib/libvirt/p_w_picpaths/RootBase.img#ls-lash/var/lib/libvirt/p_w_picpaths/*Snap*840K-rw-------.1qemuqemu896KOct1117:56/var/lib/libvirt/p_w_picpaths/Snap-1.qcow2392K-rw-------.1qemuqemu448KOct1117:56/var/lib/libvirt/p_w_picpaths/Snap-2.qcow2456K-rw-------.1qemuqemu512KOct1117:56/var/lib/libvirt/p_w_picpaths/Snap-3.qcow22.9M-rw-------.1qemuqemu3.0MOct1118:10/var/lib/libvirt/p_w_picpaths/Active.qcow2(2)单独检查下'Active'所指向的backingfile::#qemu-imginfo/var/lib/libvirt/p_w_picpaths/Active.qcow2p_w_picpath:/var/lib/libvirt/p_w_picpaths/Active.qcow2fileformat:qcow2virtualsize:1.0G(1073741824bytes)disksize:2.9Mcluster_size:65536backingfile:/var/lib/libvirt/p_w_picpaths/Snap-3.qcow2(3)开始**blockpull**操作.::#virshblockpull--domainptest2-base--path/var/lib/libvirt/p_w_picpaths/Active.qcow2--wait--verboseBlockPull:[100%]Pullcomplete(4)再检查下快照大小,'Active'变得很大::#ls-lash/var/lib/libvirt/p_w_picpaths/*Snap*840K-rw-------.1qemuqemu896KOct1117:56/var/lib/libvirt/p_w_picpaths/Snap-1.qcow2392K-rw-------.1qemuqemu448KOct1117:56/var/lib/libvirt/p_w_picpaths/Snap-2.qcow2456K-rw-------.1qemuqemu512KOct1117:56/var/lib/libvirt/p_w_picpaths/Snap-3.qcow21011M-rw-------.1qemuqemu3.0MOct1118:29/var/lib/libvirt/p_w_picpaths/Active.qcow2(5)检查'Active'信息,现在它已经不需要backingfile了,正如*Figure-6*所示::#qemu-imginfo/var/lib/libvirt/p_w_picpaths/Active.qcow2p_w_picpath:/var/lib/libvirt/p_w_picpaths/Active.qcow2fileformat:qcow2virtualsize:1.0G(1073741824bytes)disksize:1.0Gcluster_size:65536(6)清理现场::#virshsnapshot-delete--domainRootBaseSnap-3--metadata(7)现在还可以使用下guestfish**READ-ONLY**模式来检查下磁盘内容(*--ro*选项)::#guestfish--ro-i-a/var/lib/libvirt/p_w_picpaths/Active.qcow2

快照删除 (and 'offline commit')

删除(live/offline)状态的*内置快照*很方便 ::

# virsh snapshot-delete --domain f17vm --snapshotname snap6

[OR]

# virsh snapshot-delete f17vm snap6

libvirt现在还没有删除外置快照的功能,但是可以使用*qemu-img*命令来完成.

比如我们有这样一条链(VM*offline*状态):base <- sn1 <- sn2 <- sn3

现在删除第二个快照(sn2).有两种方式:

Method (1):base <- sn1 <- sn3(by copying sn2 into sn1)

Method (2):base <- sn1 <- sn3(by copying sn2 into sn3)

Method (1)

(by copyingsn2intosn1)

注意: 必须保证sn1没有被其他快照作为后端,不然就挂了!!

offline commit

#qemu-imgcommitsn2.qcow2

将会*commit*所有在sn2中的改动到sn2的backing file(sn1).

qemu-img commit和virsh blockcommit类似

现在把sn3的后端指向到sn1.

#qemu-imgrebase-u-bsn1.qcow2sn3.qcow2

注意: -u代表'Unsafe mode' -- 此模式下仅仅修改了指向到的backing file名字,必须谨慎操作.

现在可以直接删除sn2

#rmsn2.qcow2

Method (2)

(by copyingsn2intosn3)

合并数据,rebase后端:

#qemu-imgrebase-bsn1.qcow2sn3.qcow2

backingfile(sn1)到旧的backingfile(sn2)之间发生的差异改动都将被合并到sn3中.

未使用-u模式的rebase将把数据也一并合并过去,即sn2的数据写入到sn3.

换言之: 这里使用的'Safe mode',也是默认模式 --对sn3而言任何从

qemu-img rebase(没有-u)和和virsh blockpull类似.

现在可以删除sn2了

#rmsn2.qcow2

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。