ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

vmdk转qcow2避坑指南:5个高频问题与解决步骤

vmdk转qcow2避坑指南:5个高频问题与解决步骤 干虚拟化这行的人谁手里没转过几次镜像格式。尤其是VMware和KVM两套生态来回切换的时候vmdk转qcow2几乎成了标配操作。但就是这个看起来一条命令就能搞定的活坑起来是真坑。我见过转完直接开不了机的见过qcow2比vmdk膨胀好几倍的也见过转换到一半卡死最后只能删掉重来的。这篇东西就是把这些年在vmdk转qcow2上踩过的坑、填过的土一次性梳理清楚。内容包括五个最高频的问题、背后的原理、排查思路和可复现的解决步骤适合正在做VMware迁移到KVM、Proxmox VE、OpenStack的运维也适合自己在家折腾NAS和虚拟机的玩家。1. 转换前的准备先看懂vmdk再动手1.1 识别vmdk的文件形态单文件还是多文件vmdk不是只有一个固定样子的。VMware的产品线太杂Workstation、ESXi、vSphere导出的vmdk可能完全是两种物种。最常见的是单文件vmdk体积就是一个文件比如windows10.vmdk这种最简单qemu-img一把梭转换就行。但还有一种是分片存储的文件系统里会看到windows10-s001.vmdk、windows10-s002.vmdk这种一连串的文件主描述文件叫windows10.vmdk或者windows10-desc.vmdk。这种分片vmdk在转换时只认第一个描述文件qemu-img会自动沿着描述信息读取后续的分片内容。还有一种坑比较隐蔽就是从ESXi导出虚拟机的时候如果选的是“精简置备”以外的选项拿到的可能是streamOptimized格式的vmdk。这种格式是为了传输和存储优化过的很多版本的qemu-img直接不认qemu-img info会报“Unsupported VMDK version”之类的错。遇到这种我一般先拿VMware官方的vmkfstools做一次格式转换把streamOptimized先转成thin或者thick格式再拿给qemu-img处理。动手之前先到虚拟机文件所在目录ls -lh看一眼文件列表做到心里有数。别上来就qemu-img convert -f vmdk -O qcow2 xxx.vmdk xxx.qcow2万一是分片vmdk漏掉描述文件或者用通配符把分片文件名传进去转换出来的镜像要么残缺要么直接用不了。我在生产上就干过把-s001、-s002这种分片文件单独拿去转换的蠢事转出来一个几MB的qcow2启动的时候直接报磁盘不可识别白白浪费半小时。1.2 转换前的“体检”用qemu-img info看懂关键参数转换前先对源镜像做一次“体检”这是很多人跳过的步骤。qemu-img info能显示虚拟磁盘的完整状态关键的几项要会看qemu-img info windows10.vmdk输出的virtual size是这个磁盘的虚拟容量不管实际数据多少虚拟容量决定了目标qcow2的大小上限。disk size才是实际占用的物理空间。这两个数字的对比能告诉你源vmdk里有多少数据是稀疏的提前预判目标qcow2的体积。要特别留意snapshot这一项。如果vmdk里带快照直接用qemu-img转换只会转当前状态而且可能产生意料之外的体积膨胀。我的经验是先确认有没有快照有的话最好在VMware里先做一次快照删除和磁盘整理把变更数据合并干净再导出来转换。format那一项会明确告诉你是不是vmdk但有的时候写的会是vmdk实际是streamOptimized变种这时候qemu-img info可能会卡住或者报错。所以体检不只是看一眼而是要确认qemu-img能不能正确识别整个磁盘镜像的结构识别不了就提前换工具别等到转换开始之后才发现。1.3 工具选型与版本检查qemu-img也不是万能的qemu-img是转换vmdk到qcow2的主力工具但不同qemu版本对vmdk的支持程度差异很大。老的qemu版本对分片vmdk和streamOptimized的支持都不太行转换过程中可能直接报error while converting vmdk。在动手之前先查一下工具版本qemu-img --version我的建议是至少在qemu 6.0以上新的版本修了很多vmdk解析的兼容性问题。如果你的生产环境只能装老版本qemu那可以考虑用virt-v2v来做转换它对VMware格式的兼容做得更细致而且能顺便处理virtio驱动的注入和引导修复这个后面单独说。另外要注意的一点是qemu-img转换的时候会占用大量的临时空间。目标qcow2所在的文件系统剩余空间至少要大于虚拟磁盘的virtual size不是disk size。因为默认情况下qcow2是按虚拟容量稀疏分配的但转换过程中可能因为预分配策略或者快照元数据导致临时膨胀。磁盘空间不够是转换失败的低级原因我在测试环境踩过一次转一个大vmdk跑到一大半直接No space left on device前面全白干。2. 高频踩坑5个典型问题的现象、原因与处理2.1 坑一多文件vmdk漏转换只转了半个磁盘现象转换过程中没有任何报错但目标qcow2的体积远小于预期启动虚拟机发现分区表在、数据读不到或者直接提示找不到磁盘。原因这是典型的输入参数给错了。分片vmdk在磁盘描述文件里记录了所有分片的信息正确的用法是指定主描述文件比如windows10.vmdk或windows10-desc.vmdkqemu-img会自己沿着描述去加载-s001、-s002这些分片。但如果指定的是分片文件本身或者用shell通配符把多个分片一起传进去qemu-img实际上只处理了它能识别的第一个文件后面的分片被忽略转换出来的qcow2就是残缺的。处理方法# 正确姿势输入第一个描述文件 qemu-img convert -f vmdk -O qcow2 windows10.vmdk windows10.qcow2 # 如果分片是 -s001 之类的命名用引号包住防止shell展开 qemu-img convert -f vmdk -O qcow2 windows10-s001.vmdk windows10.qcow2有些特殊情况描述文件不是以.vmdk结尾而是windows10-flat.vmdk这种这说明你拿到的是ESXi的flat格式实际上没有描述信息这种需要用vmkfstools先处理。避坑心得转换之前一定先ls -lh看目录看到有分片就直接用描述文件做输入看到有-flat结尾的文件就换工具。这个习惯能帮你躲掉这个坑里至少一半的情况。2.2 坑二转换后虚拟机直接无法引导现象qcow2转完了引导虚拟机Linux卡在GRUB界面或者报disk not foundWindows直接蓝屏或者卡在Bootmgr is missing。原因这个坑的分歧点在于vmdk转qcow2只是改了磁盘格式里面操作系统的引导方式没变。从VMware平台迁移到KVM/PVE后虚拟机的磁盘控制器变了原来VMware用的是LSI Logic或者IDE控制器KVM默认给的可能是VirtIO。Linux的GRUB在启动阶段如果找不到对应的磁盘设备就会停滞Windows如果没装virtio驱动则直接在引导阶段蓝屏。处理方法如果是Linux先尝试挂载qcow2chroot进去修引导# 把qcow2挂载到本地用 qemu-nbd 的方式 modprobe nbd max_part8 qemu-nbd -c /dev/nbd0 centos7.qcow2 mkdir -p /mnt/root mount /dev/nbd0p1 /mnt/root # chroot 修复 mount --bind /dev /mnt/root/dev mount --bind /proc /mnt/root/proc mount --bind /sys /mnt/root/sys chroot /mnt/root # 重新生成grub配置并安装到磁盘 grub2-mkconfig -o /boot/grub2/grub.cfg grub2-install /dev/nbd0如果是Windows最稳妥的办法是转换之前就把virtio驱动注入到vmdk里。下载virtio-win的ISO在VMware虚拟机里先把驱动装上再导出转换。如果已经转换完了才想起来那只能挂载PE镜像进去离线注入驱动或者用virt-v2v自动处理。避坑心得我个人的习惯是不管源系统是Linux还是Windows转换完第一件事不是直接拉起虚拟机而是先查看引导配置和驱动情况。省这几分钟往往后面要多花几个小时排查。2.3 坑三转换后的qcow2体积异常膨胀现象源vmdk实际占用只有20GB转出来的qcow2一看好家伙80GB比虚拟磁盘的虚拟容量还大。磁盘空间瞬间告急。原因两个层面。第一vmdk本身是稀疏文件但qemu-img默认状态下不做压缩也不做稀疏化转换时会把源镜像中的已分配数据块原样拷贝到qcow2里源里如果存在大量已删除但还没覆写的数据块这些都会原样转入。第二如果源vmdk的分片大小和qcow2默认的cluster大小不匹配会导致数据块映射膨胀元数据开销变大。处理方法转换时直接加-c压缩选项让qemu-img在转换过程中做压缩qemu-img convert -f vmdk -O qcow2 -c windows10.vmdk windows10.qcow2这里有个取舍-c会明显增加CPU占用和转换时间但压缩后的qcow2体积可能缩小30%到50%。对存储在机械硬盘上的场景压缩带来的体积优势远大于转换多花的时间。如果是镜像已经转完了还可以用qemu-img convert再压一次或者用virt-sparsify把稀疏空间回收掉virt-sparsify --in-place windows10.qcow2避坑心得对生产环境的大镜像我一般会先转一个不做压缩的用来验证能不能启动确认没问题之后再用-c版本做正式镜像。毕竟排查启动问题和压缩转换掺在一起出了问题不好定位。2.4 坑四转换耗时极长或中途卡死现象qemu-img convert跑起来之后进度条长时间不动或者某个百分比卡住等了很多分钟还是不动最后超时或报错退出。原因最常见的是存储瓶颈。如果源vmdk放在网络存储、NAS或者共享存储上转换时qemu-img是单线程读取加写入网络延迟和带宽会直接把转换速度拖到尘埃里。另一个原因就是源vmdk的文件结构有问题比如分片描述文件损坏、快照链过长或某些数据块读取超时qemu-img在反复重试。处理方法先把源vmdk整个拷贝到本地SSD上再执行转换cp windows10.vmdk /data/tmp/ qemu-img convert -f vmdk -O qcow2 /data/tmp/windows10.vmdk windows10.qcow2拷贝看起来多了一步但对于远程存储上的大镜像本地转换的整体耗时远小于直接在共享存储上转换。如果是文件损坏导致卡死可以试试用qemu-img check先检查源vmdkqemu-img check -r all windows10.vmdk能修复就修复修复不了只能回到VMware里重新导出。避坑心得不要在生产环境的目标目录直接执行转换目标目录所在磁盘的剩余空间、I/O能力直接影响转换稳定性。我习惯在SSD暂存区完成转换确认qcow2没问题之后再搬到存储池。2.5 坑五转换后频繁I/O报错或性能雪崩现象qcow2能启动系统能进但只要读写磁盘虚拟机就卡顿、报I/O错误宿主机日志里能刷出一堆blk_update_request: I/O error。原因主要是对齐问题。vmdk的虚拟磁盘布局在VMware里可能没做4K对齐转换到qcow2之后KVM的块层面对不对齐极度敏感。分区起始扇区不是2048的整数倍读写就会出现跨块访问性能断崖式下跌。处理方法先检查分区对齐情况fdisk -l windows10.qcow2看分区起始扇区是否能被2048整除。不能整除的话说明分区没有4K对齐。这时候有两个选择。如果分区数据不多重新创建分区并恢复数据是最干净的。数据多且不想动那只能接受性能损失或者尝试用qemu-img转换时调整cluster_size来缓解qemu-img convert -f vmdk -O qcow2 -o cluster_size64k windows10.vmdk windows10.qcow2cluster_size不是越大越好。64K的cluster对随机读写更友好但对小文件频繁访问的场景可能增加元数据压力。一般我默认用64K有余力的话用fio简单压一下再定。避坑心得这个坑是最难从表面看出来的。镜像能启动不代表转换成功性能验证这步在正式上线前一定要做。如果原来是数据库或者高IO业务建议转换后至少做一轮fio读写压测确认性能达标再切换。3. 一套相对稳妥的转换流程从命令到验证3.1 基础转换命令与常用参数说明把上面踩过的坑串起来我现在执行vmdk转qcow2有一套固定的流程每一步都有明确目的。第一步准备环境确保源vmdk和目标qcow2都不在同一个磁盘的同一个分区上避免空间不足和I/O竞争df -h第二步体检源镜像qemu-img info windows10.vmdk确认磁盘格式、虚拟容量、是否有快照如果是分片vmdk确认描述文件的名字。第三步执行转换qemu-img convert -f vmdk -O qcow2 -c -p windows10.vmdk windows10.qcow2-p参数显示实时进度转换大镜像的时候能直观看到运行状态不至于干等着心慌。转换完成后qemu-img info windows10.qcow2验证一下输出重点看virtual size和disk size是否合理。3.2 转换后的引导修复与驱动检查这一步很多人忽略但恰恰是决定转换能不能用的关键。Linux系统优先处理引导Windows优先处理virtio驱动。Linux修复引导的典型操作是chroot进去重新安装GRUB前面已经给了示例命令这里补充一个重点chroot进去之后检查/etc/fstab里的分区引用方式。如果原来用的是UUID问题不大如果原来用的是/dev/sda1这种设备名转换后设备名很可能变了必须改成UUID。cp /etc/fstab /etc/fstab.bak vim /etc/fstab # 把 /dev/sda1 之类的改成 UUIDxxxxWindows虚拟机最省事的方案是用virt-v2v来做整体转换它能自动注入virtio驱动并修复引导记录virt-v2v -i vmdk windows10.vmdk -o local -os /data/images先用virt-v2v转换一次如果出现问题再用qemu-img做手动修复这套组合能覆盖绝大多数Windows场景。3.3 转换后的磁盘验证与数据一致性检查镜像能启动只是第一步数据完整性必须验证。我的习惯是转换完先挂载qcow2对关键目录做一次数据抽查qemu-nbd -c /dev/nbd0 windows10.qcow2 mount /dev/nbd0p1 /mnt/verify ls -l /mnt/verify/home umount /mnt/verify qemu-nbd -d /dev/nbd0确认挂载正常文件都在再引导虚拟机。如果源系统里跑着数据库转换前最好先停业务做一次干净关机别在线热转别拿还在写入数据的磁盘做转换这种低级错误会让数据一致性检查全部白费。4. 常用辅助工具与批量转换思路4.1 除了qemu-img还有哪些趁手工具qemu-img是主力但不是唯一选择。实际工作中我经常搭配这样几个工具virt-v2v适合大批量、自动化的虚拟机转换能处理驱动注入和引导修复尤其适合Windows迁移。virt-sparsify转换后回收qcow2的稀疏空间对瘦身很有帮助。vmkfstoolsVMware官方工具用来处理streamOptimized格式、合并快照、调整磁盘类型qemu-img处理不了的vmdk就找它。qemu-nbd把qcow2挂载为块设备方便在宿主机上直接检查修复文件系统。这几个工具组合起来大部分vmdk转换场景都能覆盖。4.2 批量转换脚本示例遇到迁移一批虚拟机的情况手工一条条敲命令效率太低我写了个简单的循环脚本#!/bin/bash for vmdk in /data/vmdk/*.vmdk; do name$(basename $vmdk .vmdk) echo Converting $vmdk ... qemu-img convert -f vmdk -O qcow2 -c $vmdk /data/qcow2/${name}.qcow2 if [ $? -eq 0 ]; then echo ${name}.qcow2 done else echo ${name}.qcow2 FAILED /data/convert_error.log fi done执行完读取convert_error.log对失败项重点排查比肉眼盯着一台台机器看进度省力得多。5. 避坑速查表与一次真实排障记录5.1 问题现象、可能原因与对应处理速查表问题现象可能原因处理方式转换产物体积远小于预期多文件vmdk漏转换输入了分片文件指定主描述文件作为输入转换后Linux无法引导磁盘控制器设备名变化、GRUB未重装挂载qcow2chroot重装GRUB改fstab为UUID转换后Windows蓝屏缺少virtio驱动转换前注入驱动或改用virt-v2vqcow2体积比vmdk大好几倍未压缩、稀疏空间未回收转换时加-c或转换后用virt-sparsify转换卡死不动源文件在网络存储、文件损坏先拷贝到本地SSDqemu-img check修复转换后I/O报错、性能差分区未4K对齐检查分区起始扇区调整cluster_size5.2 一次真实的排障过程记录有一次帮客户迁移一套Windows Servervmdk文件80GBqemu-img转qcow2用了十分钟看着挺顺利的结果虚拟机起不来蓝屏代码INACCESSIBLE_BOOT_DEVICE。第一反应是缺驱动因为这台Windows Server用的是VMware的LSI Logic SAS控制器转换到KVM后走的VirtIO驱动没加载。当时vmdk是从ESXi直接导出的没有预先装virtio驱动。临时方案是下载virtio-win驱动ISO挂载到宿主机然后通过qemu-nbd把qcow2挂载用注册表离线注入驱动的方式处理。操作思路是把viostor驱动的sys文件和inf文件复制到系统目录然后修改注册表HKLM\SYSTEM\CurrentControlSet\Services\viostor把Start改成0。处理好之后重新引导系统顺利进入桌面。这个案例里有个细节值得说如果当初从ESXi导出vmdk之后先看一眼设备签名再决定要不要预装驱动就不用来回折腾了。所以现在我的转换前检查清单里专门有一条去vmdk里查HKLM\SYSTEM\CurrentControlSet\Enum\SCSI下的设备信息看看源系统挂在哪个控制器上提前预判驱动需求。这个转换流程我用了很多次从一开始动不动翻车到现在基本能一次搞定核心是把“转换”当成一个完整的迁移项目来做而不是敲一条命令就完事。每一次踩坑都对应一个准备动作多文件就先确认描述文件Windows就先查驱动大磁盘就先算好空间。这套思路放在什么虚拟化平台上都适用。
返回列表