ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

虚拟化镜像格式转换实战:vmdk/qcow2/raw互转与qemu-img全流程

虚拟化镜像格式转换实战:vmdk/qcow2/raw互转与qemu-img全流程

接手过虚拟化环境的人基本都碰过这种事儿:对方甩过来一个镜像文件,后缀也挺熟悉,但就是挂不到自家平台上。要么是 .vmdk 想扔进基于 KVM 的私有云,要么是 .qcow2 要导出给 VMware 用,再要么是备份下来的 raw / .img 整盘镜像,得转成 .vhdx 才能在 Hyper-V 里恢复。系统转换镜像格式这个任务,听起来像是个 strace 一下就能跑完的小活,实际上牵扯到文件格式、磁盘类型、分区表、引导方式甚至网络驱动,哪一环没对齐,转出来的镜像就是一块砖。

我这些年经手过不少这种"系统转换镜像格式"的活儿,也踩过不少坑。这篇文章就把我自己实际用的流程完整梳理一遍:格式之间的本质差异是什么、用什么工具转最稳、完整命令怎么敲、转完以后必须检查哪几件事,以及那些文档里不会写但实战里几乎必踩的细节。无论你是刚入门接触虚拟化的新人,还是要批量迁移存量镜像的运维,照着这套流程走,至少能少加一天班。

1. 为什么"转格式"不是重打包那么简单

很多人第一次接触系统转换镜像格式,第一反应是"不就是换个后缀名,或者重新封装一下"。实际完全不是这么回事。我举个自己遇到过的例子:有次要把一批 VMware 虚拟机迁到 KVM 平台,总共几十台。如果只是把 vmdk 文件后缀改成 qcow2,平台根本不会认,因为 vmdk 内部的数据组织方式、元数据结构跟 qcow2 完全不同。转换的本质是重新生成一套符合目标格式规范的文件结构,把源镜像中的扇区数据逐块读取出来,再按目标格式的写入规则落盘。

换句话说,转换过程其实就是一个"读旧盘、写新盘"的搬运过程。这也是为什么转换很吃磁盘 IO 和 CPU 资源,一台几十 GB 的机器往往要跑十几分钟到几个小时。底层逻辑懂了,后面那些参数、报错就都不难理解。

1.1 镜像格式是虚拟化生态的"方言"

常见的镜像格式基本都和特定的虚拟化产品或使用场景绑定。就好比不同地区的人说话口音不一样,虚拟机镜像的"方言"大致有这几类:

  • raw / .img:最朴素的一种,没有任何元数据,就是虚拟磁盘逐字节的裸拷贝。所有虚拟化平台都认识它,缺点是占空间大、不支持快照等高级特性。
  • qcow2:KVM/QEMU 平台的主力格式,支持精简分配、压缩、快照、加密,功能非常全。
  • vmdk:VMware 的格式,后缀还分 -flat / -sparse 等变体,ESXi 上普遍使用。
  • vhdx / vhd:微软 Hyper-V / Azure 的格式,vhdx 是 vhd 的升级版,支持更大的磁盘和日志修复。
  • vdi:VirtualBox 的格式,个人玩家经常碰到。
  • iso:光盘镜像,只读,跟磁盘镜像不是一回事,但经常有人把它跟磁盘镜像混在一起问。

这些格式之间不是简单等价的关系,而是特性集不同。比如 vmdk 有它的 split 拆分模式,qcow2 有 copy-on-write 的 CoW 机制,raw 则什么高级能力都没有。转换前最好先想清楚目标平台到底需要什么特性,不然转完发现不支持热快照就尴尬了。

1.2 精简分配还是完整分配,这是个空间问题

转换过程中最容易被忽略的,是"磁盘空间分配方式"。精简分配(thin provisioning)的意思是,镜像文件只占用实际写入数据的大小,比如一块虚拟 100GB 的盘,里面只写了 30GB 数据,那 qcow2 文件可能只有 30GB 左右。完整分配(thick provisioning)则是一开始就把 100GB 全部占上。

不同格式对这两种分配方式的支持程度不一样。raw 天然就是完整分配(因为它没有元数据来描述空洞),qcow2 默认是精简分配,vmdk 两种都能做,vhdx 默认为精简。转格式之前看一眼源镜像文件大小和虚拟磁盘容量之间的差距,就能判断它是精简还是完整的。这个差距直接决定你转换时需要的临时空间:转 raw 类格式,建议准备不小于虚拟磁盘完整容量的空余空间;转 qcow2,可以按源文件实际大小再加 20% 左右的缓冲来估算。

2. 主流转换工具的选型和对比

做系统转换镜像格式,工具选择其实不多,但每款工具适用的场景差别挺大。我用过的主要是三类:命令行工具、图形化转换器、以及最简单的 dd 裸拷贝。这里把它们的适用边界说清楚。

2.1 qemu-img:功能最全,兼容性最好

qemu-img 是所有方案里我的首选,没有之一。它是 QEMU 项目自带的磁盘镜像管理工具,能读写的格式覆盖了 raw、qcow2、qed、vmdk、vhdx、vpc、vdi 等主流格式。它不只是 KVM 用户能用,就算你的虚拟机跑在 VMware 或 Hyper-V 上,也完全可以拿它来做转换,只要两边格式它都认就行。

qemu-img 的优势有三个:第一,格式支持面非常广;第二,命令行操作便于脚本化,批量几十台机器迁移时可以写循环;第三,它的转换过程会正确处理块空洞,转到支持精简分配的格式时会自动跳过全零扇区,不会把没有数据的部分也写成完整文件。

2.2 图形化工具:适合单机少量转换

如果你只是偶尔转一个镜像,不想记一堆命令行参数,那图形化工具更适合。我用过几款 V2V 类的转换器,界面基本是"选择源格式-选择目标格式-选择输出路径"三步走,还附带一些向导式的选项,比如是否压缩、是否做完整性检查。

图形化工具的优点是门槛低,缺点是自由度低、批量能力差,而且某些老版本对 vhdx 新特性支持不完整。真要处理生产环境的重要镜像,我还是建议命令行走一遍,至少每一步做了什么自己心里有数。

2.3 dd:最原始的转 raw 方式

dd 严格来说不算"格式转换",它做的是逐字节复制。所以它只能生成 raw 镜像,或者从一个 raw 镜像复制到目标块设备。使用场景一般是这样:源环境只能提供 raw 裸盘,或者我们想把物理机整盘做镜像备份。dd 的坑在于它不感知文件系统,会把整块盘的每个扇区都读一遍,包括未使用的空间,所以既慢又费空间。

但 dd 有个不可替代的价值:当其他工具报错、格式读不出来的时候,dd 是最底层的兜底方案。我曾经碰到过一个损坏的 vmdk 文件,qemu-img 直接拒绝读取,最后用 dd 按偏移量把里面关键分区数据捞出来,才保住了数据。

我把工具选型的逻辑整理成一个简单的判断表:

场景推荐工具理由
批量转换、格式间互转qemu-img可脚本化、格式全、兼容性好
偶尔转换一两次图形化 V2V 工具上手快,界面直观
物理盘备份 / 证据保全dd / 磁盘克隆工具逐字节拷贝,不丢任何数据
VMware 转 Hyper-V特定厂商迁移工具能顺带处理虚拟硬件差异

3. qemu-img 完整转换流程:从识别到产出

这一节是全文的核心实操。我以最常见的"把 vmdk 转成 qcow2"为例,把完整流程拆开来讲。实际上换任何源格式和目标格式,思路都一样,只是参数里的格式名变一下。

3.1 第一步:摸清源镜像的底细

拿到一个镜像文件,不要急着转,先用 qemu-img 看一眼它的真实信息:

qemu-img info source.vmdk

输出类似这样:

image: source.vmdk file format: vmdk virtual size: 100 GiB (107374182400 bytes) disk size: 32 GiB cluster_size: 65536 Format specific information: cid: 1234567890 parent cid: 1234567890

这里要看的核心信息有三个:file format 确认源格式;virtual size 是虚拟磁盘的完整大小,这个数字决定目标镜像的最终上限;disk size 是文件实际占用大小,能帮你估算转换所需空间和时间。如果 virtual size 和 disk size 差距很大,说明源镜像是精简分配的,转成 qcow2 时可以继续享受精简特性,不用怕它膨胀成完整大小。

3.2 第二步:执行转换命令

信息确认无误后,执行转换:

qemu-img convert -f vmdk -O qcow2 source.vmdk target.qcow2

参数解释:

  • -f vmdk:指定源格式。如果省略,qemu-img 会尝试自动探测,但自动探测偶尔会翻车,尤其是遇到某些非标准变体,所以我会手动指定。
  • -O qcow2:指定输出格式。注意是大写 O,表示 output 格式;小写 -o 是传给目标格式的附加选项,两个参数千万别弄混,我见过有同事写错导致转换出来的格式完全不对。
  • 源文件放在前面,目标文件放在后面,顺序反了会直接报错或把现有文件覆盖掉。

转换过程没有任何进度提示的话会让人心慌,建议加上-p参数显示进度条:

qemu-img convert -p -f vmdk -O qcow2 source.vmdk target.qcow2

跑起来以后会看到百分比进度。这里的进度是总体进度,不是当前扇区,所以 99% 卡很久也正常,因为元数据收尾阶段本身就要花时间,别误以为卡死了。

3.3 第三步:转换期间能做的一些优化

如果目标格式支持压缩,可以加-c参数。qcow2 支持 zlib 压缩,压缩率通常在 10% 到 40% 之间,取决于镜像里存储的数据类型。比如一个装了数据库的镜像,日志文件和数据文件大都是可压缩内容,压缩后文件体积能小不少。代价是转换速度会下降,CPU 占用会明显升高。我的习惯是:生产环境要长期保存的镜像加压缩;临时要用的中转镜像不压缩,省时间。

还有个常用选项-o可以给目标格式设置具体参数。比如把 qcow2 的 cluster 大小设为 64K:

qemu-img convert -f vmdk -O qcow2 -o cluster_size=64K source.vmdk target.qcow2

cluster 大小的选择影响性能和占用,默认值 64K 在大多数场景下都够用,不建议没搞清楚就去调它。

# 从 qcow2 转回 raw 的典型命令 qemu-img convert -p -f qcow2 -O raw source.qcow2 disk.raw # 从 vhdx 转 vmdk 的典型命令 qemu-img convert -p -f vhdx -O vmdk source.vhdx disk.vmdk

逻辑完全一致,换个格式名就行。

4. 转完镜像之后,真正麻烦的开机适配才开始

很多人把转换命令跑完就以为任务完成了,其实这只是第一步。镜像格式转换完成后,虚拟机能不能在新平台上正常启动,才是衡量整个迁移是否成功的标准。我在这上面吃过的亏,比转换过程本身多得多。

4.1 磁盘控制器变了,引导阶段直接崩

最常见的问题,是虚拟机在新平台的默认磁盘控制器和源环境不一致。比如原来跑在 VMware 上用的是 SCSI 控制器,转到 KVM 平台后默认可能配的是 virtio-blk 或者 IDE。Linux 系统如果内核里没有对应驱动,开机就会卡在"找不到根文件系统"或者直接 panic;Windows 系统会蓝屏,报 INACCESSIBLE_BOOT_DEVICE。

这是因为引导过程中,操作系统必须加载对应磁盘设备的驱动,才能挂载根分区继续启动。驱动不匹配就等于系统找不到自己的硬盘。解决方式分两种:

  • 在新平台创建虚拟机时,手动把磁盘控制器类型改成源环境一样的类型。比如原来用 SATA 就改成 SATA,原来用 SCSI 就改成 SCSI。
  • 提前在源虚拟机里装好目标平台所需的驱动。Windows 可以先把 virtio 驱动装进去再关机迁移,Linux 则要确认内核编译时包含了对应模块。

4.2 Windows 的 BCD 和 Linux 的 GRUB 都得重新来

除了驱动,引导加载器的配置也经常出问题。Windows 的引导信息存在 BCD(Boot Configuration Data)里,里面记录了系统分区、引导分区的位置。如果你是从一套虚拟磁盘布局迁到另一套,分区编号或者盘符可能变了,BCD 里的记录就对不上了,结果就是开机黑屏或无限转圈。

Linux 这边则是 GRUB 的配置问题,常见场景是:你从 vmdk 转到 qcow2 后,设备名从 /dev/sda 变成了 /dev/vda,而 GRUB 配置和 /etc/fstab 里还写着老的设备路径。虽然现在很多发行版会用 UUID 代替设备名,但如果你的系统比较老或者当初配置不规范,还是会把路径写死。

解决问题的主力手段,是使用虚拟化平台提供的救援/恢复功能:把转换后的镜像挂到一台能启动的虚拟机里当作第二块硬盘,然后 chroot 进去重新生成引导配置。Windows 则可以用安装盘进修复模式执行引导修复命令。这个过程我用过很多次,基本上能解决 90% 的引导问题。

4.3 网卡型号导致的连锁故障

磁盘通了、引导过了,还有一层是网卡。原来的虚拟机用 Intel e1000 网卡,新平台默认给 virtio-net,如果系统里没有 virtio 网卡驱动,网络就不通。Linux 下很多发行版自带 virtio 驱动,问题不大;Windows 系统这个坑几乎是必踩的。

Windows 迁移后网络不通,处理起来有点麻烦:因为没有网络,远程连不上,只能通过控制台(VNC 或平台自带 Web 终端)登录,手动安装网卡驱动。所以我现在做 Windows 镜像转换前,都会提醒对方先把目标平台的 VirtIO 驱动下载好,在源机器上装好,再关机转换。这个顺序一旦反了,事后补救成本会高出至少两三倍。

5. 镜像校验和完整性检查:别让转换过程悄悄损坏数据

转换过程看起来是"读-写"两个动作,但实际在巨大的镜像文件上执行时,任何一步出错都可能造成数据损坏。尤其源文件在目标平台跑了好几年,文件系统碎片多、坏块可能性大。所以转完以后,校验是必须的动作,不是可选动作。

5.1 用 qemu-img check 检查结构完整性

qcow2 这类格式有内部的元数据和校验信息,可以用 check 子命令检查:

qemu-img check target.qcow2

正常的输出是类似这样的:

No errors were found on the image.

如果输出里出现"Leaked clusters"或者"Corrupted cluster"之类的字样,说明镜像内部有结构问题。Leaked clusters 指的是某些数据块没有被任何快照引用,属于资源浪费,多数情况下还能用;corrupted clusters 则是数据真正损坏了,需要认真对待。

一个容易忽略的细节:qemu-img check 检查的是镜像文件的内部结构一致性,不校验虚拟磁盘里的文件系统数据是否完整。也就是说,就算 check 通过,也不能保证里面的业务系统文件一个字节都没坏。

5.2 启动级验证:最实在的验收方法

结构检查通过之后,最靠谱的验证方式是把转换后的镜像实际启动一遍。我每次转完重要的生产镜像,都会先建一台测试虚拟机,用转换后的镜像启动,确认系统能进、关键服务能跑、数据文件能读,然后再交付使用。

这一步看似多花时间,实际上能救命。有一次我转一个接近 500GB 的数据库服务器镜像,qemu-img check 全绿,结果启动后文件系统被发现有损坏,原因是源镜像在转换前就已经存在问题。好在测试时及时发现,否则部署上线后数据读取异常,麻烦就大了。

5.3 校验校验和:两个镜像是否一致

如果你想把转换前后的镜像做精确比对,可以用计算校验和的方式。但注意,raw 转 qcow2 这种转换,文件内容不是一一对应的:qcow2 有自己的元数据、压缩信息,所以直接用 md5sum / sha256sum 对比文件指纹没有意义。正确的做法是,使用虚拟磁盘层面的校验工具,比如对虚拟磁盘的分区做哈希比对,或者在转换前后分别挂载镜像读取相同文件比对内容。实际工作中,我更多依赖"完整启动 + 抽查关键数据文件"的组合验证方式,兼顾效率和可靠性。

6. 几个容易被忽略的坑位和我的处理建议

最后分享几个实战里反复出现、但官方文档很少提到的细节。这些都是我花过真金白银的教训换来的。

6.1 空间不足:不是报"空间不足"你才知道的

转换前一定要检查目标目录所在文件系统的剩余空间。很多人只看虚拟磁盘大小,忽略了转换过程的临时文件。raw 格式转换时,目标文件会完整占用虚拟磁盘大小;qcow2 转 raw 时更是如此。如果空间不够,转换会在中途失败,已写入的部分可能成为一个残缺的镜像文件,既不能删又不能用。

我的习惯是先把"虚拟磁盘大小"和"源镜像实际大小"两个数字都记下来,加一起再乘以 1.2 作为最低空间需求。比如源镜像 80GB,虚拟磁盘 200GB,那目标目录至少要预留 200GB 以上的空间再动手,同时保留 20% 余量用于意外膨胀。

6.2 转换过程中断:尽量用支持断点的工具链

qemu-img 的 convert 不支持断点续传。如果真的跑到一半机器断电或者磁盘满了,整个转换就得从头再来。几十 GB 甚至上百 GB 的镜像重转一次,时间成本极高。我处理大镜像的做法是先转成 raw 中转文件,成功后再转最终格式。虽然多一步,但每个步骤都可以独立重试,降低整体风险。

6.3 一定要确认三件事:格式、参数、路径

听上去像是废话,但我在实际操作中真的见过太多反例:

  • 顺序写反:convert -f qcow2 -O raw执行时把源和目标写反了,结果把源文件覆盖了。
  • 参数写错:-O和-o混淆,导致输出格式错误或选项没生效。
  • 路径带中文或空格:某些版本的工具处理特殊字符路径时会出问题,轻则报错,重则路径解析错误写到别的地方。

所以我现在都用一个固定的检查习惯:命令敲完后,先看一眼源文件是否可读、目标路径是否有同名文件(有就提前改名或备份),再执行转换。多花十秒钟,能省下一整天的恢复工作。

6.4 别忽略虚拟磁盘扩容和分区调整

转换完成后你可能会发现:目标虚拟磁盘的大小跟新平台的需求不匹配。这时可以用 resize 命令调整镜像的虚拟大小:

qemu-img resize target.qcow2 +50G

执行之后,镜像的虚拟磁盘容量变大了,但里面的分区表和文件系统并不会自动扩容。你还得进虚拟机,用分区工具和文件系统扩展工具把新增空间分配出去。这个步骤很多新手不知道,容易造成"镜像显示变大了,但系统里看不到新空间"的困惑。

另外,如果是从物理盘做镜像再转换,分区对齐问题也值得关注。老的分区表可能存在偏移,导致 SSD 和虚拟化环境下的 IO 效率下降。转换本身不会自动调整分区对齐,需要额外操作。不过这个问题主要影响性能,不影响启动,属于"可以承受但不建议长期不管"的范畴。

做系统转换镜像格式这件事,本质上是一个数据搬运和适配的过程,花的不仅是转换时间,更多是排查适配问题的精力。我经手的大多数成功案例,靠的都是"提前确认格式特性、转前清理环境、转后完整验证"这三步走。把这几个环节做扎实,任何格式的转换都不会太难。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进