ARTICLE DETAIL

资讯详情

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

VirtualBox直接使用vmdk新建虚拟机:控制器与固件设置避坑指南

VirtualBox直接使用vmdk新建虚拟机:控制器与固件设置避坑指南 同事拷给我一个装好系统的vmdk说是在VMware里正常跑着的虚拟机磁盘想放到VirtualBox里继续用。结果我照着“新建虚拟机向导”选了那个vmdk启动后黑屏、蓝屏、找不到引导盘折腾了一下午才把问题定位清楚。类似这种“VirtualBox使用vmdk新建虚拟机”的需求其实非常常见尤其是从别人手里接盘的镜像或者公司内部拷贝出来的数据盘。真正的原因往往不是vmdk文件本身坏了而是新建虚拟机时的磁盘控制器、启动固件、文件权限、UUID这些细节没对齐。这篇文章就把我这些年接手过的迁移案例完整踩一遍适合手头正好有vmdk、准备在VirtualBox里把它跑起来的人也适合那些被“别人能用我用了就报错”折磨到怀疑人生的朋友。1. 为什么直接从vmdk新建虚拟机而不是先转vdi1.1 vmdk和vdi的真实差异vmdk是VMware的虚拟磁盘格式vdi是VirtualBox的原生格式。很多人一听跨平台下意识就觉得必须先转格式于是打开命令行执行VBoxManage clonemedium或者用图形界面的“虚拟介质管理器”去转换。其实VirtualBox从很早就支持直接读写vmdk你新建虚拟机时选择“使用现有虚拟硬盘文件”直接选中vmdk就能挂载。但这两者确实不是同一个东西。vmdk不只是“一个文件”它可能是一个自描述文件加上一个-flat.vmdk数据文件的组合也可能是拆分成2GB分卷的一组文件还可能带一串快照链。vdi相对简单通常一个文件就是一块完整磁盘。VirtualBox读取vmdk时实际上是先解析那个文本形式的描述符再按描述符里的地址去定位真实数据文件。所以如果你只拷了其中一个数据文件或者把描述符文件和数据文件放到了不同目录VirtualBox就会报打不开或找不到区段。1.2 转换不能解决启动问题反而会引入新坑很多人踩坑第一步就是看见起不来赶紧去转vdi。不是不能转而是转完大概率还是起不来。为什么因为vmdk转vdi只是把磁盘的数据块格式复制了一遍分区表、引导记录、系统里的磁盘控制器驱动统统不变。如果原来Windows蓝屏是因为VirtualBox把SCSI控制器识别成了SATA那么转成vdi之后它还是被识别成SATA照样蓝屏。转换还会引入额外问题磁盘UUID变了分区挂载如果依赖旧UUID就会出问题原盘如果是动态稀疏分配转换过程中可能会撑大好几倍另外转换完你还要重新把vdi挂到虚拟机上等于多了一道出错机会。我见过一个案例用户转完vdi以后忘记删除原vmdk结果两个文件同时存在VirtualBox检测到UUID冲突连虚拟机都打不开。所以我的建议是除非你有明确理由比如为了让另一个工具只认vdi否则没必要先转换。直接挂vmdk启动不了得先找到真正的原因。2. 新建虚拟机前的准备先想清楚再下手2.1 检查vmdk文件完整性接盘vmdk之后第一步不是打开VirtualBox而是先看文件结构。单独一个vmdk文件的情况最简单但很多时候你拿到手的是一个文件夹里面有一个文本大小的描述符文件和一个特别大的-flat.vmdk。比如linux-flat.vmdk和linux.vmdk这两个必须放在同一个目录下如果只拷贝了描述符VirtualBox会提示找不到数据区段。还有一种情况是拆分成多个分卷文件名类似linux-s001.vmdk、linux-s002.vmdk。这时候要选的是第一个不带编号的linux.vmdk作为主盘千万不要直接选linux-s001.vmdk。另外建议先校验一下文件大小和哈希值。跨机器拷贝vmdk很容易因为拷贝中断导致文件不完整尤其是走U盘或网盘时。我在命令行里一般用sha256sum虚拟磁盘动辄几十GB只校验描述符文件一般不够至少要看-flat.vmdk和预期大小差不多。2.2 搞清楚原虚拟机的控制器和固件这一条是整个迁移的胜负手。vmdk文件里有一个文本描述符用记事本就能打开前几行像这样# Disk DescriptorFile version1 CIDfffffffe parentCIDffffffff createTypemonolithicSparse # Extent description RW 20971520 SPARSE linux-flat.vmdk # The Disk Data Base ddb.virtualHWVersion 11 ddb.geometry.cylinders 1305 ddb.geometry.heads 255 ddb.geometry.sectors 63 ddb.uuid xxxx ddb.adapterType lsilogic注意看最底部的ddb.adapterType这里写的是lsilogic。这就是原虚拟机在VMware里用的磁盘控制器类型对应到VirtualBox里就应该选SCSI下的LSI Logic或者SAS下的LSI Logic SAS而不是默认的SATA。如果是ide那么VirtualBox里应该挂IDE控制器。很多Windows蓝屏就是因为这个值没对齐。同时还要知道原虚拟机是BIOS引导还是UEFI引导。这个一般可以从系统安装习惯判断Win7及更早多半是BIOSMBRWin10/11和较新的Linux发行版可能是UEFIGPT。如果你不确定可以先按BIOS方式建虚拟机启动失败再勾选“启用EFI”重试。2.3 创建虚拟机的正确顺序在VirtualBox里新建虚拟机向导会让你选镜像你可以直接选vmdk。但我更推荐先创建一个完全不挂硬盘的“空壳”虚拟机然后再进设置里挂磁盘。这样做的原因是向导里直接选vmdk时VirtualBox默认会把它放到SATA控制器下如果原盘是LSI Logic这一步就已经埋雷了而手动创建虚拟机可以灵活调整控制器和端口出问题也更好排查。具体操作不复杂打开VirtualBox点击“新建”填写虚拟机名称操作系统类型和版本尽量选对应的Linux/Windows版本。内存和CPU按原系统配置填先不用管硬盘那一步选择“不添加虚拟硬盘”。创建完成后选中虚拟机点“设置”切到“存储”。在存储树里选中现有的控制器点“添加硬盘”选择“使用现有磁盘”找到vmdk。如果控制器类型不对先删除控制器重新添加一个SATA/SCSI/SAS/IDE控制器再把vmdk挂到上面。这样配置完以后启动虚拟机大部分问题在引导阶段就能看到真实报错而不是一开始就被向导“温柔地”带到坑里。3. 最常见的启动类大坑磁盘控制器和固件设置3.1 UUID冲突和“无法打开”提示新建虚拟机挂载vmdk时VirtualBox会读取vmdk描述符里的ddb.uuid。如果你之前已经把这个vmdk添加过另一台虚拟机或者系统里有同名镜像再挂载时VirtualBox会提示“UUID已经存在”甚至直接拒绝启动。这种时候不是删除重来而是给这个vmdk重新生成一个新的UUID命令是VBoxManage internalcommands sethduuid /path/to/linux.vmdk执行之后VirtualBox就会把这个文件当成一块全新的磁盘。需要注意的是这个操作修改的是描述符里的UUID不会动磁盘数据。如果你怕改坏可以先复制一份再执行。执行完以后如果提示“锁定文件已存在”那多半是另一个虚拟机还在占用这个vmdk或者上一次非法关机留下了.SXLK锁文件找到同目录下的.lck文件删掉再试。3.2 Windows蓝屏INACCESSIBLE_BOOT_DEVICE这个蓝屏绝对是vmdk迁移VirtualBox里出现概率最高的错误。原因是Windows在安装时只加载了当时磁盘控制器对应的驱动换了控制器驱动不匹配系统根本找不到启动盘。抛开各种玄学九成以上是因为原VMware虚拟机用的是LSI Logic SCSI而VirtualBox默认挂到SATAWindows一看设备变了直接蓝屏。解决办法先在文本编辑器里打开vmdk看ddb.adapterType是什么然后在VirtualBox存储设置里把磁盘挂到对应类型的控制器下。操作很方便在“设置-存储”里选中当前控制器点删除图示然后点“添加控制器”根据需要选SCSILSI Logic或者SAS再把vmdk硬盘挂到新控制器上。如果是原盘就是SATAAHCI问题就更简单控制器保持不变确认系统设置里“主板-启用EFI”是否应该关闭。如果是Windows 7这种老系统在VirtualBox 7.x上还可能遇到ACPI兼容问题这时可以试着把虚拟机设置里的“系统-主板-芯片组”从默认的ICH9改成PIIX3同时把“启用IO APIC”勾上。3.3 Linux启动时找不到根文件系统Linux迁移过去之后常见的现象不是蓝屏而是启动时卡住屏幕上出现一行错误ALERT! /dev/mapper/xxx does not exist. Dropping to a shell!或者Gave up waiting for root device.出现这类报错先别急着重装系统大概率是这些原因vmdk挂载的控制器变了导致设备名从/dev/sda变成了/dev/sdb或者grub和fstab里写的是UUID但因为某种原因UUID读取不到还有可能是内核initramfs里没有带对应磁盘控制器驱动。排查思路是按顺序来先在VirtualBox里换一下控制器类型比如原来用SATA改成SCSI或者IDE试试很多情况下换完直接就能启动。如果换完还不行就要进救援模式修改fstab或者重新生成initramfs。具体怎么修下一节会讲。3.4 引导顺序和EFI/BIOS的坑还有一种情况是有引导画面但启动完之后卡在黑屏或者提示没有可引导设备。这种多半是引导固件没设置对。VirtualBox里在“系统-主板”下有一个“启用EFI仅某些系统”选项如果原虚拟机是BIOSMBR引导你勾选了EFI它就会找不到引导项反过来原系统是UEFI引导你却没勾EFI也会有同样问题。另外一个容易被忽略的点是启动顺序。在“设置-系统-主板”最下面可以调整软驱、光驱、硬盘的启动优先级。有时候vmdk挂载到的是非启动盘位置启动时虚拟机先去读光驱或者网络转了一圈回来说没系统这时候把硬盘拖到第一启动位就能解决。还有VirtualBox 7.x默认对EFI启用了安全启动如果你的系统本身没在Secure Boot里注册过会提示Security Violation。遇到这个情况把“启用安全启动”取消掉再重启。4. vmdk能挂上但引导失败怎么急救4.1 用Live CD进去改fstab和GRUB如果vmdk在VirtualBox里始终无法正常引导但挂载动作本身没问题那就需要外部救援。拿Linux系统举例你准备一个同版本或者更新的Linux安装ISO比如Ubuntu的安装镜像挂为光驱然后把虚拟机的启动顺序改成光盘优先进入Live环境。进入Live桌面后打开终端先看分区情况sudo fdisk -l假设原来系统的根分区是/dev/sdb1那就先挂载根分区sudo mount /dev/sdb1 /mnt如果/boot是独立分区也要一并挂上sudo mount /dev/sdb2 /mnt/boot然后绑定系统运行所需的几个目录再chroot进去sudo mount --bind /dev /mnt/dev sudo mount --bind /proc /mnt/proc sudo mount --bind /sys /mnt/sys sudo chroot /mnt在chroot环境里可以根据实际情况重新安装引导grub-install /dev/sdb update-grub如果是根文件系统的UUID对不上可以查看/etc/fstab把它改成实际分区对应的UUID。很多发行版还推荐在chroot里重新生成initramfs比如Ubuntu/Debian是update-initramfs -uCentOS/RHEL是dracut -f。这一步往往能把缺失的磁盘驱动打进去。4.2 Windows系统用bootrec和bcdboot修复引导Windows迁移后卡在引导问题一般有两种情况一是干脆无法引导黑屏提示找不到系统二是引导进恢复环境但进不了桌面。如果能看到“自动修复”界面可以直接进“疑难解答-高级选项-命令提示符”。先执行以下命令修复MBR和启动记录bootrec /fixmbr bootrec /fixboot bootrec /rebuildbcd如果系统是UEFI引导还需要用bcdboot重新生成引导配置。首先用diskpart确认系统分区和EFI分区盘符diskpart list disk select disk 0 list volume exit假设Windows系统分区是C:EFI引导分区是S:那么执行bcdboot C:\Windows /s S: /f UEFI注意如果蓝屏是因为磁盘控制器不匹配bootrec根本没机会拯救你因为它修复的是引导记录不是驱动。这种情况还是要回到控制器选型上去。所以修复引导前先确认vmdk描述符里的adapterType和VirtualBox里的控制器设置一致。4.3 修复完还是不行检查磁盘是否被只读锁死经常有这种情况在Live环境或者命令提示符里改了一堆配置重启之后发现改动根本没生效。这时候要检查的不是系统文件而是vmdk文件本身的写入权限。如果vmdk所在目录是root权限的或者另一个虚拟机还开着这个磁盘VirtualBox会以只读方式挂载它。你在系统里做出的修改写回了磁盘但下次启动时VirtualBox依然没有写权限自然一切恢复原样。检查方法很简单看VirtualBox主界面下方是不是提示“只读”或者在启动时点击“设置-存储”看硬盘图标上有没有锁标记。解决办法是退出所有占用这个vmdk的虚拟机然后给文件设置当前用户的读写权限chmod 666 /path/to/linux.vmdk chmod 666 /path/to/linux-flat.vmdk如果宿主是Linux还要确保当前用户是文件所有者或者至少属于有写权限的组。用chown把属主改成当前登录用户更省心sudo chown $(whoami) /path/to/linux.vmdk5. 三个容易被忽略的vmdk文件细节5.1 文件权限和宿主侧访问权限接盘vmdk最常见的一个坑是从别人那里拿过来以后文件权限乱七八糟。尤其是通过企业内网、NAS或者U盘拷贝的文件可能所有者是另一个用户Windows下还可能出现只读属性。VirtualBox是普通用户进程如果读不了这个文件虚拟机根本启动不了如果只有读权限没有写权限启动会极其缓慢因为每次写磁盘都报错重试。这个问题的排查也比较简单在虚拟介质管理器里找到这个vmdk右键“属性”看是不是显示只读。如果显示只读用文件管理器或者chmod命令改掉。另外建议把vmdk和它配套的-flat.vmdk放在同一个目录下不要放在系统盘Program Files这种需要管理员权限的目录里免得VirtualBox每次启动都要提权。5.2 VMware快照产生的多文件vmdkVMware里做过快照之后磁盘就会分裂成多个文件基本盘变成只读新数据写入快照盘文件名类似linux-Snapshot1.vmdk。这种盘拿到VirtualBox里是最容易出问题的。如果你只拷了基础盘linux.vmdk那启动时看到的还是做快照之前的状态快照之后的数据全部丢失。如果你只拷了linux-Snapshot1.vmdkVirtualBox会提示找不到父盘。最稳妥的做法是在VMware里先删除快照让虚拟机磁盘合成一个完整的vmdk再拷出来用。如果已经没办法回到原VMware环境那只能把基础盘和所有快照文件全部放在同一目录然后在VirtualBox里尝试选择最新的快照描述符文件。VirtualBox对VMware快照链的支持有限常常会报错所以我的建议就一句先整合再迁移别拿快照链硬扛。5.3 固定大小、动态大小和不可变属性vmdk在创建时可以选固定大小或动态扩展大小。固定大小的vmdk通常是descriptor加-flat.vmdk的结构拷贝时两个都得带动态扩展的常见为单文件monolithicSparse或者拆分的splitSparse。挂载到VirtualBox之后在“存储-硬盘”里还能看到“固态驱动器”选项如果这个vmdk本身是机械盘模拟出来的建议不要勾选这个选项否则文件系统可能频繁进行Trim性能反而不稳定。另外VirtualBox会把某些vmdk识别为“不可变”这意味着你启动后对磁盘的写入不会保存所有修改在关机后丢失。挂载vmdk时如果弹出问你是否固定记得选“可写”或者用命令行指定类型为normalVBoxManage storageattach vm-name --storagectl SATA --port 0 --device 0 --type hdd --medium /path/to/disk.vmdk --mtype normal如果发现启动后安装的软件、改的配置文件关机就没了一定回头看看这里。6. 虚拟机创建成功后建议顺手做的调整6.1 网络适配器变了系统连不上网vmdk里装好的系统网络配置大概率还停留在VMware的环境里比如VMnet8的NAT网段、原来的MAC地址。迁到VirtualBox后网卡类型换成了Intel PRO/1000或者virtio系统里的网卡名称和连接配置都会变。Linux系统会看到eth0变成ens33或enp0s3之类Windows会遇到“未识别的网络”。解决办法不是重装系统而是进入系统后删掉旧网卡配置重新启用DHCP或者按VirtualBox的网络类型重新配置静态IP。在Linux里可以用nmcli快速搞定nmcli device status nmcli device reapply ens33如果系统用的Netplan编辑/etc/netplan下的yaml文件改成DHCP就行。然后netplan apply。6.2 安装增强功能和调整硬件参数跨平台迁移之后显卡驱动、鼠标指针融合、共享文件夹这些功能基本都没有。VirtualBox的增强功能Guest Additions可以从设备菜单里加载安装后虚拟机和宿主之间的交互会顺畅很多。一些老系统在迁过来后性能很差多半是CPU虚拟化设置不合理。VirtualBox默认会启用嵌套分页但如果你运行的是Windows 7这种老系统试着把“显示-显存大小”调到128MB并勾选“3D加速”效果会明显一些。如果启动过程卡在某个驱动加载步骤可以尝试把“系统-处理器-启用PAE/NX”勾上有时老内核不识别高内存地址就会挂住。6.3 用VBoxManage命令批量处理更省心图形界面能做的操作VBoxManage命令行基本都能做而且更适合批量处理。如果你要同时迁移好几个vmdk或者想避免鼠标在图形界面里连续点错可以直接用命令脚本来创建虚拟机VBoxManage createvm --name migrated-vm --ostype Ubuntu_64 --register VBoxManage modifyvm migrated-vm --memory 4096 --cpus 2 --boot1 disk --boot2 dvd VBoxManage storagectl migrated-vm --name SAS --add sas --controller LsiLogicSas VBoxManage storageattach migrated-vm --storagectl SAS --port 0 --device 0 --type hdd --medium /path/to/linux.vmdk其中createvm的--ostype可以先执行VBoxManage list ostypes来查选一个接近原系统的类型。挂载完磁盘后直接VBoxManage startvm migrated-vm启动。这样即使以后需要换控制器、改动配置也可以快速用命令重新来一遍。命令行模式下错误信息更明确不会像图形界面一样弹个笼统对话框。7. 常见问题速查表现象可能原因解决办法提示Could not open the medium xxx.vmdk文件权限不足、被其他进程占用关闭占用虚拟机的进程chmod/chown授予当前用户权限提示UUID已存在同一vmdk被多个虚拟机注册VBoxManage internalcommands sethduuid 重新生成UUIDWindows蓝屏INACCESSIBLE_BOOT_DEVICE磁盘控制器类型不匹配打开vmdk看ddb.adapterType改成对应控制器比如LSI LogicLinux卡在ALERT! /dev/mapper/... does not exist根设备名变化或initramfs缺驱动用Live CD chroot改fstab重新生成initramfs启动黑屏无引导界面EFI/BIOS设置与原系统不符“系统-主板”中切换“启用EFI”启动提示Security ViolationVirtualBox 7.x安全启动开启但系统不支持取消“启用安全启动”找不到启动设备启动顺序不对把硬盘设为第一启动项提示找不到某个-s001.vmdk分卷分卷文件没拷全或者不在同一目录将所有分卷和描述符文件放同目录加了快照的vmdk只拷了快照盘父盘缺失、快照链断开在VMware里删除快照整合成一个盘启动后系统里修改都保存不了vmdk被设置为不可变或只读用storageattach --mtype normal或改文件权限Windows网络变“未识别网络”VMnet网卡配置变了进入系统重新配置网络DHCP或手动重配磁盘空间和原来对不上thin provisioning动态扩展未完全识别在系统内扩展分区或用VBoxManage modifymedium --resize这张表整理的是我实际遇到的最高频问题基本覆盖了从“打不开文件”到“系统起来但用不爽”的全过程。你可以把这张表存下来遇到对应报错直接对照排查。8. 最后一点个人经验这几年没少跟vmdk打交道最大的体会是别一上来就怪VirtualBox也别一听别人说转vdi就跟着转。vmdk只是一个磁盘容器真正决定能不能启动的是控制器类型、启动固件和文件权限这些周边配置。你花5分钟用记事本打开vmdk看一眼ddb.adapterType比在网上盲搜一个下午高效得多。我自己的固定流程是先检查文件完整性再读描述符确认adapterType然后建一个空壳虚拟机手动挂盘启动之前先看固件和启动顺序。如果蓝屏或找不到根分区优先调控制器调完不行再上救援盘改配置。按这个顺序走下来成功率非常高。最后再分享一个小技巧如果你手头有多个同样的vmdk别把它们都注册到VirtualBox里同一个虚拟磁盘被多个虚拟机同时使用很容易引发写冲突和UUID问题。宁可需要用的时候再挂载用完了就卸载保持虚拟介质管理器干净清爽。这样不光避免踩坑后续排查问题也会轻松很多。
返回列表