参考:RAW和QCOW2 两种存储设备格式区别
一、背景
当我们在KVM或者 openstack或者docker环境中,常会遇到制作vm磁盘,以此作为vm的虚拟磁盘使用。主要是RAW和QCOW2这两种磁盘格式,其实他们都是一种文件格式,做为虚拟机的磁盘使用。
这里用到一个重要工具就是 qemu-img,qemu-img是QEMU的磁盘管理工具,在qemu-kvm源码编译后就会默认同步编译好qemu-img这个二进制文件。
qcow2镜像是qemu的一种镜像格式,是'qemu copy on write'的简写。可以通过qemu-img来管理。
二、区别
raw: 裸磁盘格式(默认的虚拟磁盘格式)
纯二进制映像格式。在 支持稀疏文件的文件系统里,raw格式的映像只占用记录在其中的数据实际使用的空间。Raw格式磁盘又称为裸磁盘设备,裸设备,你随便dd一个file就可以模拟了一个raw格式的镜像。
由于裸的彻底,性能上接近物理硬盘的,性能较好。目前来看,KVM和XEN 默认的格式好像还是这个格式。因为其原始,有很多原生的特性,例如直接挂载也是一件简单的事情。 裸的好处还有就是简单, 支持转换成其它格式的虚拟机镜像对裸露的它来说还是很简单的(如果其它格式需要转换,有时候还是需要 它做为中间格式),空间使用来看,这个很像物理磁盘,使用多少就显示多少(du -h看到的大小就是使用大小)。而且, raw虚拟磁盘/映像格式很容 易扩展,即原生态,管理灵活度,与系统交互更好,但不支持snapshot,相关资料说明,可利用 版本管理软件对raw格式的文件做版本管里,通过不同的版本回滚,实现类似快照的功能。
eg1:创建一个raw的磁盘文件
dd if=/dev/zero of=c.raw bs=1024k count=4096 //创建4G的扩容空间
cat linux.img c.raw > new-linux.img //追加到原有的镜像之后,再次查看已扩容成功
$qemu-img create -f raw test.raw 10G //输出如下
Formatting ‘test.raw’, fmt=raw size=10737418240
$qemu-img info test.raw //验证,查看磁盘信息;如果虚拟磁盘文件是使用稀疏文件的存储方式,也会显示出它的本来分配的大小以及实际已占用的磁盘空间大小。如果文件中存放有客户机快照,快照的信息也会被显示出来
注:当创建虚拟磁盘后,使用它安装了OS镜像,这时,我们还可以利用它来创建派生镜像,从而生成的虚拟磁盘就可自带OS了,而不需要每次都进行OS的全新安装。
Qcow2(QEMU copy-on-write)
固定大小的 块设备磁盘。Qcow2是目前比较主流的一种虚拟化镜像格式,目前qcow2的性能上接近raw裸格式的性能,与普通的 raw 格式的镜像相比,它还有以下特性:
a)更小的空间占用,即使文件系统不支持空洞(holes);qcow2 格式的镜像比 Raw 格式文件更小,只有在虚拟机实际占用了磁盘空间时,其文件才会增长,能方便的减少迁移花费的流量,更适用于云计算系统
b)支持 写时拷贝(COW, copy-on-write),镜像文件只反映底层磁盘的变化;
c)支持 快照(snapshot),镜像文件能够包含多个快照的历史;
d)可选择基于 zlib 的 压缩方式,它允许每个簇(cluster)单独使用 zlib 压缩。
e)可以选择 AES 加密,支持使用 128 位的 AES 密钥进行加密。
官方解释,qcow2 镜像文件是由多个固定大小的单元组织构成,这些 单元被称为 (host clusters );无论是实际用户数据(guest data)还是镜像的元数据(metadata),都存储到一个 cluster 单元中。用户系统里所见到的虚拟磁盘实际是被分割成多个 同样大小的 clusters 的集合显示。
qcow2 镜像可以用来保存另一个镜像文件的变化,它并 不去修改原始镜像文件, 只记录与原始镜像文件的 不同即可,这种镜像文件就叫做 copy-on-write 镜像。虽然是一个单独的文件,但它的大部分的数据都来自原始镜像,只有跟原始镜像文件相比有变化的 cluster 才会被记录下来。快照就是原始文件本身(内部快照)。它既包含做快照之前的原始文件部分,它本身也包含可写的部分。
eg1:创建 qcow2 文件
$ qemu-img create -f qcow2 test.qcow2 10G //输出如下
Formatting ‘test.qcow2’, fmt=qcow2 size=10737418240 encryption=off cluster_size=65536 lazy_refcounts=off
eg2:openstack里创建Qcow2镜像:
$ glance image-create –name cirros –file /tmp/cirros-0.3.4-x86_64-disk.img –disk-format qcow2 –container-format bare –progress
eg3:指定固定单元大小( cluster)来创建qcow2格式虚拟磁盘:
qemu-img create -f qcow2 -o cluster_size=2M,backing_file=ubuntu14.04.raw ubuntu-nova.qcow2 40G //使用backing_file选项指定后端镜像,让生成的虚拟磁盘文件是copy-on-write的增量文件
其中:
1>上述命令使用backing_file方式利用已创建好的ubuntu14.04.raw镜像,来创建qcow2格式的派生镜像,且这里的40G并不会真正占用40G,只是限制了ubuntu-nova.qcow2文件的最大大小。
2>当raw格式文件中安装的系统是windows系列的时候,创建qcow2格式最后
文件大小需要 比raw格式大2-3倍,例如:创建一个大小为30G的win7.raw格式文件,创建qcow2格式磁盘命令如下:
qemu-img create -f qcow2 -o cluster_size=2M,backing_file=win7.raw windows-7.qcow2 60G
3>上述命令中,ubuntu-nova.qcow2文件并不是一个独立的虚拟镜像文件,在使用过程中需要与ubuntu14.04.raw磁盘一起使用,这就需要保持backing_file 绝对路径不变,而qcow2文件是可以移动的。kvm虚拟机是直接与qcow2格式的镜像文件进行交互的,qcow2格式的镜像文件中只是保存了相对raw镜像所有更改的数据,raw格式的镜像文件
中的数据不会发生任何变动,raw格式的镜像只作为backing_file,对虚拟机而言完全是透明的。
4>这么做的好处是,raw格式创建后就会占占用指定的空间,比如创建一个20G的raw格式虚拟磁盘,系统就会立即分配20G空间给该文件使用,在此基础上变化的部分写入到qcow2格式的镜像文件/虚拟磁盘中,更节省空间,因其是动态增长的,且支持加密,支持压缩,支持快照的特点。
5>-o选项(options)用来附加对该文件的各种功能设置,可以使用“-o ?”来查询某种格式文件支持那些选项,在“-o”选项中各个选项用逗号来分隔。如果“-o”选项中使用了backing_file这个选项来指定其后端镜像文件,那么这个创建的镜像文件仅记录与后端镜像文件的差异部分。后端镜像文件不会被修改,除非在QEMU monitor中使用“commit”命令或者使用“qemu-img commit”命令去手动提交这些改动。这种情况下,size参数不是必须需的,其值默认为后端镜像文件的大小。另外,直接使用“-b backfile”参数也与“-o backing_file=backfile”效果相同。
语法:qemu-img create [-f fmt] [-o options] filename [size]
size选项用于指定镜像文件的大小,其默认单位是字节(bytes),也可以支持k(或K)、M、G、T来分别表示KB、MB、GB、TB大小。另外,镜像文件的大小(size)也并非必须写在命令的最后,它也可以被写在“-o”选项中作为其中一个选项。
Raw 格式与 qcow2 转化
可借助QEMU 里的 qemu-img 工具对image 镜像进行格式转化
$ qemu-img convert -f raw -O qcow2 test.raw test.raw.qcow2
其中: -f 指定需要转换文件的文件格式;-O 指定要转换的目标格式;源文件不会被删除;
注:一般来说,输入文件格式-f fmt由qemu-img工具可自动检测到,而输出文件格式-O output_fmt需用户根据自己需要来指定,默认会被转换为raw虚拟磁盘文件格式(且默认使用稀疏文件的方式存储以节省存储空间)。加“-c”参数,可对输出的镜像文件进行压缩,不过只有qcow2和qcow格式的镜像文件才支持压缩,而且这种压缩是只读的,如果压缩的扇区被重写,则会被重写为未压缩的数据。
qcow2格式与raw转化
$ qemu-img convert -O qcow2 image-raw.raw image-raw-converted.qcow
vmdk格式与qcow2转化
$qemu-img convert -f vmdk -O qcow2 SLES11SP1-single.vmdk SLES11SP1-single.img //将VMware用的vmdk格式文件转换为qcow2文件
$qemu-img convert -f raw openwrt.img -O vmdk openwrt.vmdk //img转换vmdk
其他磁盘管理命令
1)qemu-img check -f 磁盘格式 磁盘镜像文件的名称
对磁盘镜像文件进行一致性检查,查找镜像文件中的错误,目前仅支持对“qcow2”、“qed”、“vdi”格式文件的检查。如果不指定格式qemu-img会自动检测;
eg1:#
qemu-img check test.qcow2 //输出类似如下
No errors were found on the image.
2)qemu-img commit [-f fmt] 虚拟磁盘;
用来提交虚拟磁盘文件中的更改到后端支持镜像文件(创建时通过backing_file指定的)中去。
eg1:#
3)快照管理
语法:qemu-img snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename
其中,“-l” 选项是查询并列出镜像文件中的所有快照,“-a snapshot”是让镜像文件使用某个快照,“-c snapshot”是创建一个快照,“-d”是删除一个快照。
4)修改镜像文件的后端镜像文件
语法:qemu-img rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename
注:只有qcow2和qed格式支持rebase命令。使用“-b backing_file”中指定的文件作为后端镜像,后端镜像也被转化为“-F backing_fmt”中指定的后端镜像格式。
它可以工作于两种模式之下,一种是安全模式(Safe Mode)也是默认的模式,qemu-img会去比较原来的后端镜像与现在的后端镜像的不同,进行合理的处理;另一种是非安全模式(Unsafe Mode),是通过“-u”参数来指定的,这种模式主要用于将后端镜像进行了重命名或者移动了位置之后对前端镜像文件的修复处理,由用户去保证后端镜像的一致性。
5)修改镜像文件的大小
语法:qemu-img resize filename [+ | -]size //使其不同于创建之时的大小
其中,“+”和“-”分别表示增加和减少镜像文件的大小,而size也是支持K、M、G、T等单位的使用。缩小镜像的大小之前,需要在客户机中保证里面的文件系统有空余空间,否则会数据丢失,另外,qcow2格式文件不支持缩小镜像的操作。在增加了镜像文件大小后,也需启动客户机到里面去应用“fdisk”、“parted”等分区工具进行相应的操作才能真正让客户机使用到增加后的镜像空间。不过使用resize命令时需要小心(最好做好备份),如果失败的话,可能会导致镜像文件无法正常使用而造成数据丢失。
如下命令行演示了两个镜像的大小改变:将一个8GB的qcow2镜像增加2GB的空间,将一个8GB大小的raw镜像减少1GB空间。
qemu-img resize test.qcow2 +2G
qemu-img resize test.raw -1G
raw和qcow2比较
qemu中有两种重要的镜像格式:raw和qcow2。
raw格式是一个裸的块设备,和普通的块设备操作一样。
qcow2是虚拟的块设备,存在结构的定义。
raw设备读写性能会比qcow2性能好,但qcow2也有减少存储空间,快照,加密等功能。
raw格式优缺点
raw格式文件里面的空洞,则是由宿主机的文件系统来管理的,linux下的文件系统可以很好的支持空洞的特性,所以创建了一个100G的raw格式的文件,ls可以看到这个文件是100G的,但是用du 来看这个文件会很小。但是在cp和tar压缩的时候都是按照100G进行,如果要做远程拷贝,可以转换为qcow2格式。
raw不支持动态增长空间。
qemu-img和dd都可以创建raw格式的磁盘。qemu-img创建的是稀疏文件,文件中的'空洞'在填满的时候才会占用磁盘空间。dd默认创建的不是稀疏文件,但dd可以指定seek参数也可以创建稀疏文件。
raw缺点之一:ls看起来很大,在scp的时候,这会消耗很多的网络IO,而tar这么大的文件,也是很耗时间跟 CPU的,一个解决方法是,把raw转换成qcow2的格式,能极大压缩空间。
qemu-img create -f raw raw-image.raw 2G # 创建一个空洞文件。不占用磁盘大小
dd if=/dev/zero of=dd_test count=1 bs=1G # 真实占用磁盘空间
dd if=/dev/zero of=dd_seek count=1 bs=4M seek=1000 # seek指定位置,之前的为空洞文件。只占用4M
qcow2的格式优缺点
qcow2是kvm支持的磁盘镜像格式,我们创建一个100G的qcow2磁盘之后,无论用ls来看,还是du来看,都是很小的。这说明了,qcow2本身会记录一些内部块分配的信息的。
相比raw有以下优势
更小的空间占用,即使文件系统不支持空洞(holes);
支持写时拷贝(COW, copy-on-write),镜像文件只反映底层磁盘的变化;
支持快照(snapshot),镜像文件能够包含多个快照的历史;
可选择基于 zlib 的压缩方式
可以选择 AES 加密
缺点
qcow2文件会一直增大,不会减小
qemu-img一些命令
qemu-img可以创建,查看qcow2镜像。另外还支持制作快照,镜像转换,支持父镜像(backing file)。
qemu-img create -f qcow2 test.qcow2 4G # 创建qcow2镜像
qemu-img info test.qcow2
qemu-img snapshot -c snap1 test.qcow2 # 创建快照。关机状态下创建
qemu-img snapshot -a snap2 test.qcow2 # 使用快照。
qemu-img create -b test.qcow2 -f qcow2 test_1.qcow2 # 创建基于backing file的qcow2
qemu-img convert -p -f qcow2 test_1.qcow2 -O qcow2 test_1-merge.qcow2 # 镜像脱离backing file。同时也起到压缩qcow2镜像的作用。
qemu-img rebase -u -b base.qcow2 test_1.qcow2 # 重新指定baking file
qemu-img convert test.qcow2 -O raw test.img # 转换成raw格式
文件空洞
文件空洞有什么用处?比如迅雷下载,一开始是创建了一个整体的空洞文件,可以有多个线程从不同的位置下载。
空洞文件不占用磁盘空间。块执行的null是不占用空间的。
技巧
1 lvm设备转换为qcow2
对于一个lvm设备/dev/lvm/disk,它是一个qcow2的镜像,并且有父镜像。怎样把这个块设备转换为一个qcow2文件,并保持qcow2是个二层镜像,也存在父镜像呢?
直接
dd if=/dev/lvm/disk of=abc.qcow2
是不行的,因为会把父子镜像整体看成一个盘,dd到abc.qcow2中。
直接
qemu-img convert -O qcow2
也是不行的,这个直接变成一个没有父镜像的qcow2镜像。
做法:
qemu-img info /dev/lvm/disk // 查询diskSize
然后只dd diskSize大小的数据到abc.qcow2
dd if=/dev/lvm/disk of=abc.qcow2 bs=1M count=500M
三、应用
a) kvm从qemu继承了丰富的磁盘格式, 包括裸映象(raw images), 原始qemu格式(qcow), Vmware格式等;
b) kvm虚拟机默认使用raw格式的镜像格式,性能最好,速度最快,它的缺点就是不支持一些新的功能,如支持镜像,zlib磁盘压缩,AES加密等。 要使用镜像功能,磁盘格式必须为qcow2。
raw格式的话,速度稍微快点,在高版本的qemu-kvm中,几乎不比qcow2的格式快,而qcow2格式节省空间,可动态增长,在公有云中广泛使用,建议使用qcow2。
c)qemu windwos安装包安装下载:https://qemu.weilnetz.de/w64/,之后添加系统变量;
适用于 Windows 的 QEMU 磁盘映像实用程序。可用于各种虚拟磁盘格式的转换、创建和一致性检查。它与 Hyper-V、KVM、VMware、VirtualBox 和 Xen 虚拟化解决方案兼容。
eg1:将 QCOW2、RAW、VMDK 或 VDI 映像转换为 VHDX
qemu-img.exe convert source.img -O vhdx -o subformat=dynamic dest.vhdx
eg2:将 QCOW2、RAW、VMDK 或 VDI 映像转换为 VHD
qemu-img.exe convert source.img -O vpc -o subformat=dynamic dest.vhd
qemu-img.exe check source.qcow2 //检查磁盘一致性
qemu-img.exe info image.qcow2 //查看磁盘信息