概述
前些天遇到一个需求,把阿里云服务器迁移到本地 Hyper-V 虚拟机,云服务的系统是 CentOS 7.9;前后大概花了一周,踩坑无数,这里记录一下,供后来的小伙伴们参考,也欢迎交流。
如果有重来一次的机会,我一定会避开所有坑,这里先梳理一下不踩坑迁移流程,后面再记录下踩过的坑。
不踩坑迁移流程
一)下载云镜像
参考 https://blog.csdn.net/qq_50854662/article/details/128018044
进入阿里云控制台,镜像管理,导出当前服务器镜像,然后从OSS下载到本地。这个过程不用关机,导出过程后台完成,可能要半小时;如果导出没有完成,OSS上看不到文件,要耐心等待。
这个完成后,记得从阿里云控制台清理一下这个过程产生的镜像及OSS数据,留在那里可能要收费的。
二)虚拟磁盘格式转换
按上面文档说明,使用 qemu-img 转换镜像格式。qemu 是一个开源虚拟机,我们只是用它附带的一个小工具 qemu-img ,用来转换虚拟磁盘镜像,有点大材小用。
镜像文件先解压,再使用 qemu-img,把 raw 格式转换成 vmdk 格式。
set path="C:\Program Files\qemu";%path%
qemu-img convert -f raw centos79__system.raw -O vmdk centos79__system.vmdk
再用 Vmdk2Vhd 把 vmdk 格式转换 vhd 格式。Vmdk2Vhd 是另外一个小工具,功能单一,只有几十K,图形界面操作。
再用 Hyper-V 中编辑磁盘功能,把vhd 格式转换为 vhdx格式;这一步本也可以不做,Hyper-V 本身支持 vhd 格式,但这个过程可以验证前面转换出来的文件有没有问题。
看 qemu-img 说明,也支持从 raw 直接转换到 vhdx ,但测试发现,转换过程正常,没有任何报错,但转换的镜像文件后面无法使用。
三)导入Hyper-V 虚拟机
打开 Hyper-V 管理器,新建虚拟机,指定代数选项里面,选一代,使用上面转换过的磁盘镜像文件。
启动虚拟机,会发现无法正常启动;强制关机重启后,快速按键盘上下键,启动菜单选择第三项(救援模式)进入。
登陆后,使用下面命令修复:
dracut --regenerate-all -f
grub2-mkconfig -o /boot/grub2/grub.cfg
重启后发现可以正常进入系统了。
四)禁用 cloud-init
上面基本可用了,但每次启动要花费10多分钟,通过分析是 cloud-init 服务的原因。cloud-init 是一个云服务器的管理服务,主要完成云服务器的一些自动化配置工作,对我的本地虚拟机没有什么用途。
尝试直接禁用服务(systemctl disable cloud-init),发现不起作用;后来找个一个方法,在cloud-init 配置目录新建一个文件cloud-init.disabled,即可不启动 cloud-init。
简单禁用 cloud-init 命令:
touch /etc/cloud/cloud-init.disabled
四)转换为 UEFI 引导,使用Hyper-V第二代
上面其实已经完成了迁移工作,但如果你想在Hyper-V第二代上运行,需要把虚拟磁盘转换为 UEFI引导。
这一步操作有风险,建议先备份一下虚拟磁盘文件。
UEFI转换,参考 https://blog.51cto.com/jeffluo/9748058
操作完成后,新建 Hyper-V 虚拟机,选择第二代,选择上面转换过的磁盘镜像文件,安全启动选择禁用。
其实这个转换完成后,也还同时支持 BIOS 引导(第一代引导模式),但要在 grub启动菜单里面调整引导命令,
linuxefi --> linux16
initrdefi --> initrd16
或许可以在 grub.cfg 加上判断,自动选择引导命令,没有进一步研究。
注意:上面参考文档中最后一条命令有拼写错误,直接使用会到导致启动失败,需要修改为
sed -i 's/initrd16/initrdefi/g' /boot/grub2/grub.cfg
踩坑记录
下面记录下踩坑过程。
1. 虚拟磁盘格式转换问题
qemu-img 支持各种虚拟磁盘格式,尝试直接把 .raw 转换成 .vhdx格式:
qemu-img convert -f raw centos79__system.raw -O vhdx centos79__system.vhdx
转换过程没有报错,但转换的 vhdx centos79__system.vhdx 文件在 Hyper-V 上使用会报错。
2. Hyper-V无法引导
使用 Hyper-V 第一代虚拟机, 但启动过程会停止到下面画面:
网上搜索 “blk_update_request: I/O error, dev fd0, sector 0”,大概了解到是初始化虚拟机软驱出错导致。解决方法是通过修改注册表禁用Hyper-V 虚拟机软驱,尝试后无效;只能放弃一代虚拟机,改用二代虚拟机。
但二代虚拟机需要 UEFI 引导,由于无法进入系统,修改磁盘分区很困难,最后被迫使用 VirtualBox 虚拟机引导,修改为 UEFI 引导,再使用 Hyper-V 二代虚拟机。
使用二代虚拟机启动后,上面报错没有了,有另外一些报错,依旧无法启动;后来偶然发现使用救援模式可以启动。通过网上搜索,找到使用 dracut 修复内核方法,参考:
Updating the Linux boot image before migrating from VMWare to Hyper-V | MangoLassi
3. 启动慢问题
每次启动需要等待10分钟以上,后面找到方法是禁用 cloud-init,参考前面记录。
启动耗时分析命令:
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain