有没有什么方法可以轻松地(无需重新安装)将 Linux Hyper-V(第一代)VM 转换为第二代?
我知道Convert-VMGeneration
PowerShell 的 cmdlet(这个:https://code.msdn.microsoft.com/windowsdesktop/Convert-VMGeneration-81ddafa2),但是它不适用于 Linux VM。
我在 HyperV 上运行时遇到了一些问题(机器在一段时间内停止响应等),但我发现这些问题在 Gen2 上得到了很大改善(我们遵循 Microsoft 推荐的所有在 Hyper-V 上运行 Linux 的做法,但仍然没有解决,至少在 Gen1 上没有)。
原始虚拟机在 Windows Server 2008 主机上运行。我们已升级到 2012 R2 主机,现在可以运行 Gen2,但我发现的每个来源都说您必须为其重新安装 Linux(我无法弄清楚原因,但我确信应该有原因)。
这个特定服务器(它是在 Ubuntu 14.04 上运行的 Gitlab 服务器)的安装和迁移非常麻烦,如果可能的话,我们不想重新安装和迁移。
答案1
由于这是我尝试寻找答案时的最佳结果,因此我发布了自己的解决方案,即使距离问题提出已有 6 年多了。(顺便说一句,旧评论中的 fercasas.com 已不再可用,因此无法说它是否有帮助)
简介和注释
无论如何,真正的问题是 BIOS 与 UEFI,而 IDE 与 SCSI 并没有给我带来任何额外的影响。
所以简而言之 - 答案与将 BIOS PC 转换为 UEFI PC 相同。
下面还有更多细节。
注释#1:我在 Ubuntu 20.04、Ubuntu 16.04 和 Centos 7 上做过这个,我需要在 Ubuntu 18.04 上重复一遍,如果有重要区别我会编辑答案。
注意 #2:与往常一样,您的分区方案和磁盘名称可能与我的示例不同,请相应修改,如果您格式化错误的分区,我对数据丢失概不负责!您可以在原始操作系统中使用fdisk -l
和/或检查分区cat /etc/fstab
注意事项 #3:我建议在此过程之前备份整个虚拟机,例如使用 Hyper-V 管理器中的“导出”功能
Ubuntu 20.04
以下是基于我的 Ubuntu 20.04 VM 的说明(为此目的全新安装,默认安装设置):
# boot your Gen 1 VM
# note: all steps done as root, so sudo su first
sudo su
# install grub efi version for later use, just in case; note: it will remove other version on install
apt-get install -y grub-efi
# backup current boot files
# make /boot2 folder and copy everything from /boot to /boot2 (for backup, safe keeping, later use)
mkdir -p /boot2
cp -r /boot/* /boot2
# delete old VM in Hyper-V Manager, but keep the VHDX file(s) (also, remember to export/backup before trying this all)
# create new Gen2 VM with same settings, and attach existing VHDX file(s)
# Add DVD drive and make it first device, attach same ISO image you used to install this OS
# boot LiveCD, or server install + shell, or similar, it's important to boot in Gen2/EFI mode
# if you boot in Server installer, pick Help, Enter shell
# Prepare partitions and mounts
# format old boot partition to FAT
mkfs -t vfat /dev/sda2
# create mountpoints
mkdir -p /mnt/boot
mkdir -p /mnt/root
# mount them
mount /dev/sda2 /mnt/boot/
mount /dev/ubuntu-vg/ubuntu-lv /mnt/root/
# OR
mount /dev/mapper/ubuntu--vg-ubuntu--lv /mnt/root/
# copy files from old (BIOS) /boot2 backup, one you made before formatting
# copy backup files back to /boot
cp -r /mnt/root/boot2/* /mnt/boot/
# install EFI grub
apt-get install -y grub-efi
grub-install --force --target=x86_64-efi --boot-directory=/mnt/boot --efi-directory=/mnt/boot /dev/sda
# should reply: - No error reported
# edit fstab
nano /mnt/root/etc/fstab
# change UUIDs to what says in comments above them like "was on .... during curtin installation".. so use that "....", for example
# also /boot needs to be changed from ext2/ext4/whatever to "vfat", so like this
/dev/ubuntu-vg/ubuntu-lv / ext4 defaults 0 0
/dev/sda2 /boot vfat umask=0077 0 0
# keep other entries (eg swap) as is, or if you know what you're doing change them in similar way, or find new UUIDs, etc.
# now we can shut down VM, unmount DVD/ISO, and get it ready for normal boot
poweroff
# eject media + enter
# turn off VM
# start again by doing: Connect, Start
# after successful reboot, install and update grub, to have correct and fresh system with current mounts etc
# if you had to manually fix boot, first fix whatever was wrong (like fstab, or whatever), then do this
grub-install /dev/sda --efi-directory=/boot
update-grub
reboot
Ubuntu 20.04 基本上就是这样。我尝试按照此过程安装新内核,update-grub
重启后,我可以看到新条目。所以未来的更新也应该没问题。
如果遇到麻烦,不要绝望!如果您的第一次尝试出错并且最终得到grub >
提示,您可以通过大致如下的方式修复它:
# if you reboot to grub rescue prompt, you can still fix everything, no need to return to original export/backup files !
# enter these commands
# try this first
configfile (hd0,gpt2)/grub/grub.cfg
# if above didn't start boot, try manually like this, instead "-x.x.x-xx-generic" enter your current kernel version, use tab to autocomplete
set root=(hd0,gpt2)
insmod linux
linux /vmlinuz-x.x.x-xx-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv
initrd /initrd.img-x.x.x-xx-generic
boot
此后,您应该进入正常的操作系统实例,只需再次以 root 身份进行 sudo,然后重复上述grub-install
操作update-grub
即可。
您还可以使用以下命令在 Ubuntu 上强制创建 grub.cfg 文件:
grub-mkconfig -o /boot/grub/grub.cfg
Ubuntu 16.04
这是针对 Ubuntu 16.04 的。它很相似,实际上是一样的,但我对其进行了修改,以适应 16.04 启动 ISO 映像中可用的“救援”模式的工作流程。“救援”模式会将您置于 chroot 中,因此我不得不修改路径并删除一些不需要的步骤。
# boot your Gen 1 VM
# note: all steps done as root, so sudo su first
sudo su
# install grub efi version for later use, just in case; note: it will remove other version on install
apt-get install -y grub-efi
# backup current boot files
# make /boot2 folder and copy everything from /boot to /boot2 (for backup, safe keeping, later use)
mkdir -p /boot2
cp -r /boot/* /boot2
# delete old VM in Hyper-V Manager, but keep the VHDX file(s) (also, remember to export/backup before trying this all)
# create new Gen2 VM with same settings, and attach existing VHDX file(s)
# Add DVD drive and make it first device, attach same ISO image you used to install this OS
# boot ISO while in Gen2/EFI VM, and in grub pick "Rescue" option, then follow the questions
# when it asks, pick a correct root filesystem (something like /dev/ubuntu-vg/root if you have LVM
# it will ask to mount /boot ; skip that
# once you are in shell you have "#" at bottom of screen, start bash to make your workflow easier
bash
# Prepare partitions and mounts
# if you mounted /boot just unmount it again
umount /boot
# check which partition was your boot
fdisk -l
cat /etc/fstab
# format old boot partition to FAT
mkfs -t vfat /dev/sda1
# mount boot back
mount /dev/sda1 /boot/
# copy files from old (BIOS) /boot2 backup, one you made before formatting
# copy backup files back to /boot
cp -r /boot2/* /boot/
# install EFI grub if you did not earlier, otherwise it should be available since you are effectively in chroot of your original OS installation; you may need to setup /etc/resolv.conf temporarily
# apt-get install -y grub-efi
grub-install --force --target=x86_64-efi --boot-directory=/boot --efi-directory=/boot /dev/sda
# should reply: - No error reported
# edit fstab
nano /mnt/root/etc/fstab
# change UUIDs to what says in comments above them like "was on .... during installation".. so use that "....", for example
# also /boot needs to be changed from ext2/ext4/whatever to "vfat", and added umask, so like this
/dev/mapper/ubuntu--vg-root / ext4 errors=remount-ro 0 1
/dev/sda1 /boot vfat umask=0077 0 2
# keep other entries (eg swap) as is, or if you know what you're doing change them in similar way, or find new UUIDs, etc.
# now we can shut down VM, unmount DVD/ISO, and get it ready for normal boot
exit / exit / poweroff
# eject media + enter
# turn off / shut down VM
# start again by doing: Connect, Start
# you may get "press any key to continue" .. just press any key
# after successful reboot, install and update grub, to have correct and fresh system with current mounts etc
# if you had to manually fix boot, first fix whatever was wrong (like fstab, or whatever), then do this
sudo su
grub-install /dev/sda --efi-directory=/boot
update-grub
reboot
在将来的内核更新中,grub 安装程序可能会提示您是否要保留配置或其他一些选项。选择第一个 - 安装“软件包维护者”版本(假设您没有对 grub.cfg 进行手动更改,这在服务器 VM 中是不常见的)。由于 Ubuntu 是软件包维护者,它应该会为您正确设置所有“安全默认值”。
如果您遇到困难,请查看 Ubuntu 20.04 流程及其末尾的提示。
CentOS 7
接下来我们执行 CentOS 7 的步骤,它非常相似,因此请先阅读 Ubuntu 20.04 说明以了解一般概念和警告。
# as with Ubuntu, create Gen1 VM, with default settings, or use one you already have, just make sure to backup/export VM to prevent any data loss
# boot your Gen 1 VM
# again we either do this as root or sudo into root
sudo su
# while still in Gen1, install the following in your OS
yum install -y grub2-efi
yum install -y grub2-efi-modules
yum install -y efibootmgr
# following are optional, but won't hurt, and can be handy later
yum install -y shim
yum install -y dosfstools
yum install -y nano
# backup content of /boot to temporary /boot2 folder
mkdir -p /boot2
cp -r /boot/* /boot2/
ll /boot2/
# then shut down and export/backup your VM if you haven't already
poweroff
# after export/backup, again remove your Gen1 VM, but keep VHDX file(s)
# then recreate it as new VM with Gen2 setup, and with DVD with installer ISO attached, boot to ISO
# once booted, pick "Troubleshooting" then "Rescue a CentOS system"
# wizard/guide will ask you something, pick "1" to "Continue"
# this will mount your current OS
# once you are in shell, start bash to make your workflow easier
bash
# Prepare partitions and mounts
# check for your old boot partition
fdisk -l /dev/sda*
# format old boot partition, make sure you change to sdXn for your real situation!
umount /dev/sda1
mkfs -t vfat /dev/sda1
# chroot to your real OS instance; didn't have to do this in Ubuntu, couldn't find a way around it
# as in CentOS rescue mode yum was non operational (in my testing)
chroot /mnt/sysimage
# mount the boot partition
mount /dev/sda1 /boot
# no need to mount root as it was already mounted at /mnt/sysimage/ by Rescue guide/wizard
# copy files from old (BIOS) /boot2 backup, one you made before formatting, to /boot
cp -r /boot2/* /boot/
# install EFI grub; if you get errors then you didn't install packages with yum as instructed earlier
grub2-install --force --target=x86_64-efi --boot-directory=/boot --efi-directory=/boot /dev/sda
# should output : No error reported
# you HAVE TO regenerate grub config after reinstall, or it won't pick up everything
grub2-mkconfig -o /etc/grub2.cfg
# edit fstab
vi /etc/fstab
# OR if you installed optional packages
nano /etc/fstab
# updated fstab content is something like this
/dev/mapper/centos-root / xfs defaults 0 0
/dev/sda1 /boot vfat umask=0077 0 0
# /swap... keep as is ; same with other partitions if you have them
# instructions for vim:
# i to edit ; esc to end editing mode ; :x to save ; :q to quit ; :q! to quit without changes
# exit chroot environment
exit
# then shut down VM
poweroff
# eject media
# turn off, then you can start it again
# Connect, Start
# while booting it should provide grub menu, let it boot, then it will (re)boot again, let it do it again to get to normal login prompt, this is expected because SELinux is doing some conversion on first boot and seems to need a reboot after that!
# after reboot, install and update grub, to have correct and fresh system with current mounts etc
# if you had to manually fix boot, first fix whatever was wrong (like fstab, or whatever), then do this
grub2-install /dev/sda --efi-directory=/boot
grub2-mkconfig -o /etc/grub2.cfg
reboot
这应该可以让你使用 Gen2 / EFI CentOS 7 VM。与 Ubuntu 一样,我在此过程之后进行了内核更新,虽然我确实手动运行了grub2-mkconfig
命令,但其他一切都运行正常,并且在重新启动时我可以选择新条目grub
并正确启动到新内核。
再次强调,如果您第一次尝试时出现问题,请不要担心,您可以通过执行以下操作来修复它:
# if you reboot to grub rescue prompt, you can still fix everything, no need to return to original export/backup files !
# enter these commands
# try this first
configfile (hd0,msdos1)/grub2/grub.cfg
# if above didn't start proper boot, try manually like this, just enter your current kernel version, use tab to autocomplete
set root=(hd0,msdos1)
linux /vmlinux-(hit the Tab)
linux /vmlinuz-(your.version) ro root=/dev/mapper/centos-root
initrd /initramfs-(your.version).img
boot
# if needed repeat this 2 times until you get to normal login prompt because of SELinux is doing some conversion on first boot!
此后,您应该进入正常的操作系统实例,只需再次以 root 身份进行 sudo,然后重复上述grub2-install
操作grub2-mkconfig
即可。
包起来
我认为有些部分可以做得更好/不同,因为我发现这个主题有很多变化,正如从 Ubuntu 与 CentOS 中已经看到的那样。
如果有人偶然发现更好的方法,请在下面的评论中告诉我。我有一整套由各种 Ubuntu/CentOS/Debian VM 组成的生产服务器环境,将在 2021 年从 Gen1 转换为 Gen2。所以欢迎任何补充!
我在研究中使用的一些链接:
https://unix.stackexchange.com/questions/418401/grub-error-you-need-to-load-kernel-first
如何使用 UEFI 将我的 Linux 磁盘从 MBR 转换为 GPT?
https://askubuntu.com/questions/831216/how-can-i-reinstall-grub-to-the-efi-partition/1203713#1203713