(KVM连载)4.3.2 qemu-img命令详解

qemu-img是QEMU的磁盘管理工具,在qemu-kvm源码编译后就会默认编译好qemu-img这个二进制文件。qemu-img也是QEMU/KVM使用过程中一个比较重要的工具,本节对其用法和实践使用方法进行介绍。

qemu-img工具的命令行基本用法如下:

qemu-img command [command options]

它支持的命令分为如下几种:

(1)check [-f fmt] filename

对磁盘镜像文件进行一致性检查,查找镜像文件中的错误,目前仅支持对“qcow2”、“qed”、“vdi”格式文件的检查。其中,qcow2是QEMU 0.8.3版本引入的镜像文件格式,也是目前使用最广泛的格式。qed(QEMU enhanced disk)是从QEMU 0.14版开始加入的增强磁盘文件格式,为了避免qcow2格式的一些缺点,也为了提高性能,不过目前还不够成熟。而vdi(Virtual Disk Image)是Oracle的VirtualBox虚拟机中的存储格式。参数-f fmt是指定文件的格式,如果不指定格式qemu-img会自动检测,filename是磁盘镜像文件的名称(包括路径)。

如下命令行演示了qemu-img的check命令的使用方法。

[root@jay-linux kvm_demo]# qemu-img check rhel6u3.qcow2

No errors were found on the image.

(2)create [-f fmt] [-o options] filename [size]

创建一个格式为fmt大小为size文件名为filename的镜像文件。根据文件格式fmt的不同,还可以添加一个或多个选项(options)来附加对该文件的各种功能设置,可以使用“-o ?”来查询某种格式文件支持那些选项,在“-o”选项中各个选项用逗号来分隔。

如果“-o”选项中使用了backing_file这个选项来指定其后端镜像文件,那么这个创建的镜像文件仅记录与后端镜像文件的差异部分。后端镜像文件不会被修改,除非在QEMU monitor中使用“commit”命令或者使用“qemu-img commit”命令去手动提交这些改动。这种情况下,size参数不是必须需的,其值默认为后端镜像文件的大小。另外,直接使用“-b backfile”参数也与“-o backing_file=backfile”效果相同。

size选项用于指定镜像文件的大小,其默认单位是字节(bytes),也可以支持k(或K)、M、G、T来分别表示KB、MB、GB、TB大小。另外,镜像文件的大小(size)也并非必须写在命令的最后,它也可以被写在“-o”选项中作为其中一个选项。

对create命令的演示如下所示,其中包括查询qcow2格式支持的选项、创建有backing_file的qcow2格式的镜像文件、创建没有backing_file的10GB大小的qcow2格式的镜像文件。

[root@jay-linux kvm_demo]# qemu-img create -f qcow2 -o ? temp.qcow

Supported options:

size             Virtual disk size

compat           Compatibility level (0.10 or 1.1)

backing_file     File name of a base image

backing_fmt      Image format of the base image

encryption       Encrypt the image

cluster_size     qcow2 cluster size

preallocation    Preallocation mode (allowed values: off, metadata)

 

[root@jay-linux kvm_demo]# qemu-img create -f qcow2 -b rhel6u3.img  rhel6u3.qcow2

Formatting 'rhel6u3.qcow2', fmt=qcow2 size=8589934592 backing_file='rhel6u3.img' encryption=off cluster_size=65536

 

[root@jay-linux kvm_demo]# qemu-img create -f qcow2 -o backing_file=rhel6u3.img  rhel6u3-1.qcow2

Formatting 'rhel6u3-1.qcow2', fmt=qcow2 size=8589934592 backing_file='rhel6u3.img' encryption=off cluster_size=65536

 

[root@jay-linux kvm_demo]# qemu-img create -f qcow2 -o backing_file=rhel6u3.img,size=20G  rhel6u3-2.qcow2

Formatting 'rhel6u3-2.qcow2', fmt=qcow2 size=21474836480 backing_file='rhel6u3.img' encryption=off cluster_size=65536

 

[root@jay-linux kvm_demo]# qemu-img create -f qcow2 ubuntu.qcow2 10G

Formatting 'ubuntu.qcow2', fmt=qcow2 size=10737418240 encryption=off cluster_size=65536

 

(3)commit [-f fmt] filename

提交filename文件中的更改到后端支持镜像文件(创建时通过backing_file指定的)中去。

 

(4)convert [-c] [-f fmt] [-O output_fmt] [-o options] filename [filename2 [...]] output_filename

fmt格式的filename镜像文件根据options选项转换为格式为output_fmt的名为output_filename的镜像文件。它支持不同格式的镜像文件之间的转换,比如可以用VMware用的vmdk格式文件转换为qcow2文件,这对从其他虚拟化方案转移到KVM上的用户非常有用。一般来说,输入文件格式fmt由qemu-img工具自动检测到,而输出文件格式output_fmt根据自己需要来指定,默认会被转换为与raw文件格式(且默认使用稀疏文件的方式存储以节省存储空间)。

其中,“-c”参数是对输出的镜像文件进行压缩,不过只有qcow2和qcow格式的镜像文件才支持压缩,而且这种压缩是只读的,如果压缩的扇区被重写,则会被重写为未压缩的数据。同样可以使用“-o options”来指定各种选项,如:后端镜像、文件大小、是否加密等等。使用backing_file选项来指定后端镜像,让生成的文件是copy-on-write的增量文件,这时必须让转换命令中指定的后端镜像与输入文件的后端镜像的内容是相同的,尽管它们各自后端镜像的目录、格式可能不同。

如果使用qcow2、qcow、cow等作为输出文件格式来转换raw格式的镜像文件(非稀疏文件格式),镜像转换还可以起到将镜像文件转化为更小的镜像,因为它可以将空的扇区删除使之在生成的输出文件中并不存在。

下面的命令行演示了两个转换:将VMware的vmdk格式镜像转换为KVM可以使用的qcow2镜像,将一个raw镜像文件转化为qcow2格式的镜像。

[root@jay-linux kvm_demo]# qemu-img convert my-vmware.vmdk my-kvm.img

(此处并无实际存在vmdk文件,仅演示其命令行操作)

 

[root@jay-linux kvm_demo]# qemu-img convert -O qcow2 rhel6u3.img rhel6u3-a.img

 

(5)info [-f fmt] filename

展示filename镜像文件的信息。如果文件是使用稀疏文件的存储方式,也会显示出它的本来分配的大小以及实际已占用的磁盘空间大小。如果文件中存放有客户机快照,快照的信息也会被显示出来。下面的命令行演示了前面进行文件转换的输入、输出文件的信息。

[root@jay-linux kvm_demo]# qemu-img info rhel6u3.img

image: rhel6u3.img

file format: raw

virtual size: 8.0G (8589934592 bytes)

disk size: 8.0G

[root@jay-linux kvm_demo]# qemu-img info rhel6u3-a.img

image: rhel6u3-a.img

file format: qcow2

virtual size: 8.0G (8589934592 bytes)

disk size: 6.8G

cluster_size: 65536

 

(6)snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename

“-l” 选项是查询并列出镜像文件中的所有快照,“-a snapshot”是让镜像文件使用某个快照,“-c snapshot”是创建一个快照,“-d”是删除一个快照。

 

(7)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”参数来指定的,这种模式主要用于将后端镜像进行了重命名或者移动了位置之后对前端镜像文件的修复处理,由用户去保证后端镜像的一致性。

 

(8)resize filename [+ | -]size

改变镜像文件的大小,使其不同于创建之时的大小。“+”和“-”分别表示增加和减少镜像文件的大小,而size也是支持K、M、G、T等单位的使用。缩小镜像的大小之前,需要在客户机中保证里面的文件系统有空余空间,否则会数据丢失,另外,qcow2格式文件不支持缩小镜像的操作。在增加了镜像文件大小后,也需启动客户机到里面去应用“fdisk”、“parted”等分区工具进行相应的操作才能真正让客户机使用到增加后的镜像空间。不过使用resize命令时需要小心(最好做好备份),如果失败的话,可能会导致镜像文件无法正常使用而造成数据丢失。

如下命令行演示了两个镜像的大小改变:将一个8GB的qcow2镜像增加2GB的空间,也将一个8GB大小的raw镜像减少1GB空间。

[root@jay-linux kvm_demo]# qemu-img resize rhel6u3-a.img +2G

Image resized.

[root@jay-linux kvm_demo]# qemu-img info rhel6u3-a.img

image: rhel6u3-a.img

file format: qcow2

virtual size: 10G (10737418240 bytes)

disk size: 6.8G

cluster_size: 65536

 

[root@jay-linux kvm_demo]# qemu-img resize rhel6u3-b.img -1G

Image resized.

[root@jay-linux kvm_demo]# qemu-img info rhel6u3-b.img

image: rhel6u3-b.img

file format: raw

virtual size: 7.0G (7516192768 bytes)

disk size: 6.5G

2016.02.22 update: 将qcow2/raw等格式转化为vhd,记录一下 qemu-img convert source.img -O vpc -o subformat=dynamic dest.vhd

master

Stay hungry, stay foolish.

27 Comments

  1. 请教一个问题,我使用img.qcow2镜像启动虚拟机后,使用qemu-img snapshot -c snapshot1 img.qcow2命令创建的快照为什么显示的VMsize为0,而且好像不能正确的保存虚拟机的状态,但是使用在qemu命令里面的savevm保存的快照就是正常的?

    • 你这个问题很好,我以前也没仔细研究这东东,不过现在我看了一下,基本理解了。在客户机处于运行状态时,应该使用monitor中的savevm命令来保存快照(保存的仅是客户机内的运行状态);qemu-img snapshot -c snapshot1 img.qcow2 命令并不支持对虚拟机运行状态的保存,仅保存了当前磁盘镜像的信息,所以它的VMsize应该为0(这个大小是客户机运行状态)。由于客户机运行过程中可能有数据未从内存或缓存同步到磁盘中,所以客户机运行之时尽量别用qemu-img snapshot来保存快照。

  2. 请教一个问题: 我通过qemu-img snapshot-create 的方式创建的快照,但是会有虚拟机网络的中断,如何实现在线快照呢?

    • 你可以看一下我前面的回复#3,你好好看一下应该明白。可以将上面评论#3中的两者结合起来。另外,没遇到过网络中断的情况。
      我认为,在线时就用savevm保存快照即可,不要保存磁盘的快照,磁盘快照应该是虚拟机关闭状态下才保存。

  3. 您好,我买了您的《KVM虚拟化原理与实践》这本书,看到qemu-img这一章节有些不明白。网上一搜发现了作者你的博客,哈哈缘分啊。在此请教一个问题: qemu-img info命令下看到的virtual size和disk size有何区别及联系?为什么resize后virtual size数值变了但disk size未变?

    • 请看79页和第4章末关于”稀疏文件“的说明。virtual size时改变了,意味着该image最大的容量变化量;disk size没变,意思时当前占用的磁盘空间没变。稀疏文件,里面没有写入实际数据,就仅占用很少的磁盘空间,用于存储一些元数据(meta data)即可。

  4. 您好,我也是买了这本《KVM虚拟化原理与实践》,物理服务器E5-2407,8G内存,60GSSD装host和虚拟机,均为RHEL6.3,内核未做升级,两块500G机械盘组raid0建立各种虚拟磁盘,按照您书中做虚拟机磁盘性能测试,使用第一种方法dd的四个命令。如果我使用qemu-img create -f raw AAA.img 20G建立一个20G的镜像文件加入到虚拟机中,使用dd测试时虚拟机必会出现卡死情况,只能强行关闭虚拟机。如果使用您在书中最早演示的dd if=/dev/zero of=BBB.img bs=1M count=20k来建立一个20G镜像,就可以成功完成dd命令的测试。而且我发现虽然建立出来的两个镜像文件使用ll -h看都占用20G,但qemu-img create创建出来的是瞬间完成的。不知道这是什么原因造成的,还请不吝赐教

    • 至于你出现卡死的情况,我没遇到过,你可以考虑 -f qcow2 做image试试,或者你用新一点的qemu。那个瞬间完成的事情,是因为qemu-img那个创建的还是sparse file,你用qemu-img info看两个image,就知道他们的disk size不一样的,你看下本页前一个评论(就是讨论的这个问题)。

      • 经你提醒已经找到原因了,AAA.img使用ll -h 看有20G,但使用du命令查看时只有7G多,我存放AAA.img分区的剩余空间已经不足以支撑其扩展到20G了,因此测试时才会出现虚拟机卡死的情况,非常感谢~!

  5. 我想请问下,我有个镜像,创建时使用了backupfile,同时该镜像用qemu-img在关机状态下创建了2个snapshot,现在我想把第一个snapshot 用commit命令提交到backupfile里面去,应该如何操作?commit命令似乎没有关于选择snapshot的参数。

    • 我在博客中写到了,qemu-img snapshot -a my_snapshot 是让镜像文件使用某个快照,然后然后qemu-img commit 去提交,就是可以的。我没做过,建议你操作前,先做好备份。

  6. 你好,楼主。想问下,我的kvm 虚拟机 创建时候给的磁盘空间是50G 用了一段时间以后发现 img所占用的空间达到80G 用qemu-img info 去查看的时候发现。disk-size 比virtual-size 大也就是 80G 这个是为什么呢。

  7. 博主您好,想请教一下,我使用raw格式的镜像文件安装了一个win7,之后以它为backing_file生成了一个更大的qcow2镜像文件(qemu-img create -f qcow2 -o backing_file=/var/win7.raw /var/win7.qcow2 30G),而新生成的qcow2文件很小(是因为它是raw的增量文件吗?),之后我进入原来的那个raw的win7虚拟机中创建几个文件,为什么在后来的用win7.qcow2这个镜像文件生成的虚拟机中看不到在raw中(即backing_file中)新创建的那几个文件?

    • 看到你也邮件给我了,以回复你的邮件。

      实际win7.qcow2的实际大小只有几百K(是因为它是win7.raw的增量文件吗?)
      -- 是的;你说的没错。

      之后你改了win7.raw,在qcow2中是看不到的,qcow2的image只能看到它被create时的raw文件。
      不能随意改动backing_file那个raw文件,否则会导致与其相关的qcow2直接无法使用的;如果改了raw文件,相应的qcow2应该重新生成。

  8. 您好,我想问下,如果原始虚拟机一共大小10G,现在可用空间4.5G,现在派生一个虚拟机,那么这个派生的虚拟机在第一次打开时应该和原始虚拟机完全一样,那么查看这个派生虚拟机的可用空间应该也是4.5G吧?即使派生镜像创建时分配了15G。这点我非常困惑,希望您能给予援手!不胜感激!

    • 应该是的。你可以在虚拟机中看 'fdisk -l' 看一下磁盘大小。请看本文“(8)resize filename [+ | -]size”中的讲解,可能需要重新分区之类的,才能扩大磁盘空间。

  9. 您好,我现在想在VM中安装win764位系统,用win7.vmdk来做win7.qcow2文件,但是第一步就总是失败,启动虚拟机准备安装,屏幕总是黑的,什么都没,但是32位的都正常,想请教一下!

  10. 请教个问题:我在KVM下面创建了一个虚拟机的镜像,装RHEL7.2 的系统。可是这个镜像在Xen下面启动不起来。如果Guest 装的是 RHEL6.7 就可以了。

    • 理论上来说RHEL7.2 是支持作为Xen的guest的呀~ 不过我没搞过。具体 自己得看看报什么错了~

  11. [root@docker:~]# dd if=/dev/zero of=~/junk
    dd: writing to '/root/junk': No space left on device
    10937281+0 records in
    10937280+0 records out
    5599887360 bytes (5.6 GB, 5.2 GiB) copied, 30.219 s, 185 MB/s
    [root@docker:~]# rm junk

    [root@mitaka:/data/image]# virsh destroy docker
    [root@mitaka:/data/image]# qemu-img convert -c -O qcow2 docker_b.img docker_b_c.img
    [root@mitaka:/data/image]# qemu-img info docker_b_c.img
    image: docker_b_c.img
    file format: qcow2
    virtual size: 120G (128849018880 bytes)
    disk size: 12G
    cluster_size: 65536
    Format specific information:
    compat: 1.1
    lazy refcounts: false
    [root@mitaka:/data/image]# qemu-img info docker_b.img
    image: docker_b.img
    file format: qcow2
    virtual size: 120G (128849018880 bytes)
    disk size: 34G
    cluster_size: 65536
    Snapshot list:
    ID TAG VM SIZE DATE VM CLOCK
    1 installed docker 17.03 20G 0 2017-03-15 09:44:00 00:00:00.000
    Format specific information:
    compat: 1.1
    lazy refcounts: false
    为什么这里的快照会丢失了呢?怎么操作才会保住快照呢?多谢

    • 我看你转化前后都是qcow2格式哇,我的建议你直接cp复制一份img文件不就好了,这个很简单。

      • 我的目的是为了测试这个磁盘转换时把未用的磁盘空间用0填充后,删除,再转换后回收这部分空间,上面的例子从34G到12G。这个只是测试,我实际要在生产环境处理的的磁盘是500G,占用了480G,但是实际虚拟机内清除掉应用异常填满的日志后,只用了40G左右。磁盘有3个快照,现在还不敢操作。

  12. 你好,如果我新建的镜像文件指定的size小于后端镜像文件的size,这样新建的镜像启动会报错.
    即:
    base.img 10G
    qemu-img create -f qcow2 -b base.img new.img 5g
    kvm new.img 失败, qemu-img version 2.5.0
    请问一下这是为什么呢?对于这种情况有什么好的解决办法吗?

    • qcow2那个占用的实际空间又很小的;大小也一样大挺好的啊
      你有这种需求也是很特别的 没有什么好的办法了。

master进行回复 取消回复

邮箱地址不会被公开。 必填项已用*标注

*