镜像文件从raw格式转换为qcow2

本文最后更新于:August 23, 2024 pm

将 raw 格式转换为 qcow2 格式是 KVM 虚拟化环境中常见的操作,本文主要介绍如何使用qemu工具将虚拟机的镜像文件从raw格式转换为qcow2格式。

KVM 虚拟机硬盘文件格式

KVM 虚拟机可以使用多种格式的硬盘文件,其中 raw 和 qcow2 是两种最常用的格式。

raw 格式

工作原理:

raw 格式文件是原始磁盘镜像,它直接复制了物理硬盘的扇区数据,没有经过任何压缩或转换。因此,raw 文件的大小与它所代表的虚拟磁盘大小完全相同。

特点:

  • 优点:

    • 高性能: 由于没有额外的转换层,raw 格式文件读写速度最快。
    • 简单直接: 结构简单,易于理解和管理。
    • 兼容性好: 可以被大多数虚拟化软件和工具识别。
  • 缺点:

    • 空间占用大: 即使虚拟磁盘内部有很多空闲空间,raw 文件也会占用全部空间。
    • 不支持快照: 无法创建磁盘快照,备份和恢复操作效率低。
    • 安全性较低: raw 文件包含了所有数据,包括已删除的文件,存在数据泄露风险。

适用场景:

  • 对性能要求极高的虚拟机,例如数据库服务器。
  • 需要将虚拟磁盘镜像直接复制到物理硬盘的场景。
  • 需要与其他不支持 qcow2 格式的虚拟化软件或工具兼容的场景。

qcow2 格式

工作原理:

qcow2 格式文件是 QEMU 镜像文件格式,它是一种精简配置的磁盘镜像,采用了多种技术来提高存储效率和性能。

  • 写时复制 (Copy-on-Write): qcow2 文件初始大小很小,只有在写入数据时才会分配实际空间。
  • 压缩: qcow2 文件支持多种压缩算法,可以有效减小文件大小。
  • 快照: qcow2 文件支持创建多个磁盘快照,方便进行备份、恢复和测试。

特点:

  • 优点:

    • 节省存储空间: 只占用实际使用的磁盘空间,支持压缩。
    • 支持快照: 方便备份、恢复和测试。
    • 安全性更高: 可以加密镜像文件,保护数据安全。
    • 高级功能: 支持 AES 加密、zlib 压缩等高级功能。
  • 缺点:

    • 性能略低: 由于引入了额外的转换层,性能略低于 raw 格式。
    • 兼容性稍差: 主要用于 KVM 和 QEMU 等虚拟化软件。

适用场景:

  • 大多数 KVM 虚拟机场景。
  • 需要节省存储空间的场景。
  • 需要频繁创建快照进行备份和测试的场景。
  • 对安全性要求较高的场景。

总结:

特性 raw 格式 qcow2 格式
文件大小 与虚拟磁盘大小相同 远小于虚拟磁盘大小,按需分配
性能 最快 略慢于 raw 格式
快照 不支持 支持
压缩 不支持 支持
安全性 较低 较高
适用场景 对性能要求极高、需要直接复制到物理硬盘 大多数场景,节省空间、支持快照、安全性更高

总的来说,qcow2 格式在功能、效率和安全性方面都优于 raw 格式,除非对性能有较高的要求,不然一般推荐使用qcow2作为 KVM 虚拟机使用的硬盘文件格式。

转换格式

检查硬盘

改造前我们先进入虚拟机中检查一下硬盘的相关信息:

1
2
3
4
5
6
7
8
9
10
11
[root@infra-centos7 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 150G 0 disk
├─vda1 253:1 0 1G 0 part /boot
└─vda2 253:2 0 149G 0 part /
[root@infra-centos7 ~]# blkid
/dev/vda1: UUID="763539f9-fc49-443a-a246-4cedb357dc92" TYPE="xfs"
/dev/vda2: UUID="4110a890-d483-4d07-af95-dda95c600e96" TYPE="xfs"
[root@infra-centos7 ~]# df -Th | grep vda
/dev/vda2 xfs 149G 70G 80G 47% /
/dev/vda1 xfs 1014M 279M 736M 28% /boot

然后在宿主机上面查看文件信息

1
2
3
4
5
root@tiny-unraid:/mnt/user/domains/infra-centos7# qemu-img info vdisk1.img 
image: vdisk1.img
file format: raw
virtual size: 150 GiB (161061273600 bytes)
disk size: 150 GiB

转换命令

接着使用这个命令进行转换

1
root@tiny-unraid:/mnt/user/domains/infra-centos7# qemu-img convert -f raw -O qcow2 -c vdisk1.img vdisk1.qcow2

让我们逐个分析命令中的参数:

  • qemu-img convert: 这是 qemu-img 工具的子命令,用于转换磁盘镜像文件的格式。
  • -f raw: 指定源磁盘镜像文件的格式为 raw
  • -O qcow2: 指定目标磁盘镜像文件的格式为 qcow2
  • -c: 可选参数,表示在转换过程中对 qcow2 镜像进行压缩。
  • vdisk1.img: 源磁盘镜像文件的名称。
  • vdisk1.qcow2: 转换后的目标磁盘镜像文件的名称。

命令执行过程:

  1. qemu-img 读取源文件 vdisk1.img,该文件为 raw 格式。
  2. qemu-img 将 raw 格式的数据转换为 qcow2 格式。
  3. 如果使用了 -c 参数,qemu-img 会在转换过程中对 qcow2 镜像进行压缩。
  4. qemu-img 将转换后的 qcow2 格式数据写入目标文件 vdisk1.qcow2

转换完成之后我们查看qcow2文件的信息,可以看到转换前后的文件大小有非常明显的差别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@tiny-unraid:/mnt/user/domains/infra-centos7# ls -lh
total 182G
-rwxrwxr-x 1 root users 150G Jun 24 14:07 vdisk1.img*
-rw-r--r-- 1 root root 32G Jun 24 15:07 vdisk1.qcow2

root@tiny-unraid:/mnt/user/domains/infra-centos7# qemu-img info vdisk1.qcow2
image: vdisk1.qcow2
file format: qcow2
virtual size: 150 GiB (161061273600 bytes)
disk size: 31.5 GiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false

这里还需要注意,如果担心ls命令看到的文件大小并不是文件真实占用硬盘空间的大小,可以考虑使用du命令来检查

默认情况下使用dd命令来生成一个raw文件,并不会马上占用对应的硬盘大小。(例如dd一个100G大小的raw文件,实际并不会马上占用100G的硬盘,只会随着实际使用而不断增长)

但是还有一种特殊的情况就是使用rsync命令备份这些文件的时候,因为raw文件的特性,如果一个100G的raw硬盘文件,只使用了30G,实际只占用了30G硬盘,因为rsync过程中对文件的复制操作,会导致复制过后的新文件大小变为100G。

修改xml配置

修改前xml文件

qemu转换完成之后我们需要修改kvm虚拟机的xml配置文件

1
2
3
4
5
6
7
8
<disk type='file' device='disk'>
<driver name='qemu' type='raw' cache='writeback'/>
<source file='/mnt/user/domains/infra-centos7/vdisk1.img'/>
<target dev='hdc' bus='virtio'/>
<boot order='1'/>
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</disk>

解析一下上面的这段配置

1. 硬盘缓存模式 cache='writeback'

  • writeback 模式下,数据写入磁盘镜像文件时会先缓存到主机内存,稍后再写入磁盘。
  • 优点:提升写入性能。
  • 缺点:存在数据丢失风险,如果主机崩溃,缓存中的数据将丢失。

建议:

  • 除非对性能要求极高,否则建议使用更安全的缓存模式,例如:

    • cache='none':禁用缓存,每次写入都直接写入磁盘,最安全但性能较低。
    • cache='writethrough':写入数据时同时写入缓存和磁盘,兼顾性能和安全性。

2. 硬盘总线类型 bus='virtio'

  • virtio 是半虚拟化驱动,性能优于模拟设备。
  • 但需要客户机操作系统安装 virtio 驱动才能识别。

建议:

  • 确认客户机操作系统已安装 virtio 驱动,例如 Ubuntu 通常默认安装。
  • 如果客户机操作系统不支持 virtio,则需要使用模拟设备,例如 bus='ide'bus='scsi'

3. PCI 地址分配 address type='pci' ...

  • 这段配置为虚拟硬盘分配了固定的 PCI 地址。
  • 一般情况下,KVM 会自动分配 PCI 地址,无需手动指定。
  • 如果对这个配置进行了修改导致报错却又不知道如何还原,可以尝试将这段配置直接删除,删除后再次启动虚拟机一般会自动生成对应的新配置。

4. disk type

在 KVM 虚拟机配置文件中,<disk> 元素的 <driver> 子元素中的 type='raw' 指的是虚拟磁盘镜像文件的格式。

type='raw' 表示使用原始磁盘镜像格式。

  • 特点:
    • 直接映射: 虚拟磁盘文件直接映射到主机文件系统上的一个文件,没有额外的格式转换,读写性能最好。
    • 简单: 结构简单,创建和使用方便。
    • 空间占用大: 即使虚拟磁盘内部文件系统有空闲空间,镜像文件大小也不会自动缩减。

其他可用的 type 参数:

除了 raw 之外,qemu 驱动还支持其他几种虚拟磁盘镜像文件格式:

  • qcow2 (推荐):
    • QEMU 默认格式,支持许多高级功能,例如:
      • 稀疏分配: 镜像文件大小可以动态增长,只占用实际使用的空间。
      • 快照: 可以创建虚拟磁盘的时间点副本。
      • 压缩: 可以压缩镜像文件,节省存储空间。
  • qed:
    • KVM/QEMU 早期版本使用的格式,功能较少,现在已经很少使用。
  • vmdk:
    • VMware 使用的虚拟磁盘格式,KVM 可以读取和使用,但不建议创建新的 vmdk 格式镜像。

修改后xml文件

这里主要修改的是source file和type字段

1
2
3
4
5
6
7
8
9
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='writeback'/>
<source file='/mnt/user/domains/infra-centos7/vdisk1.qcow2' index='1'/>
<backingStore/>
<target dev='hdc' bus='virtio'/>
<boot order='1'/>
<alias name='virtio-disk2'/>
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</disk>

重新登录机器之后我们检查硬盘的情况

1
2
3
4
5
6
7
8
9
10
11
[root@infra-centos7 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 150G 0 disk
├─vda1 253:1 0 1G 0 part /boot
└─vda2 253:2 0 149G 0 part /
[root@infra-centos7 ~]# blkid
/dev/vda1: UUID="763539f9-fc49-443a-a246-4cedb357dc92" TYPE="xfs"
/dev/vda2: UUID="4110a890-d483-4d07-af95-dda95c600e96" TYPE="xfs"
[root@infra-centos7 ~]# df -Th | grep vda
/dev/vda2 xfs 149G 70G 80G 47% /
/dev/vda1 xfs 1014M 279M 736M 28% /boot

到这里整个转换就完成了。