将 Hyper-V Linux 机器转换为 Gen 2

Jcl*_*Jcl 6 linux hyper-v hyper-v-server-2012-r2

有什么方法可以轻松(且无需重新安装)将 Linux Hyper-V(第 1 代)虚拟机转换为第 2 代虚拟机?

我知道Convert-VMGenerationPowerShell 的 cmdlet(这个: https: //code.msdn.microsoft.com/windowsdesktop/Convert-VMGeneration-81ddafa2),但这不适用于 Linux VM。

我在 HyperV 上运行时遇到一些问题(机器停止响应一段时间等),我所看到的大部分问题在 Gen2 上都有了很大的改进(我们遵循所有 Microsoft 建议的在 Hyper-V 上运行 Linux 的做法,但是它仍然不存在,至少在第一代上)。

原始虚拟机在 Windows Server 2008 主机上运行。我们已经升级到 2012 R2 主机并且现在可以运行 Gen2,但是我找到的每个来源都说你必须为其重新安装 linux(我还没能弄清楚为什么,但我确信应该有一个原因)。

这个特定服务器(它是在 Ubuntu 14.04 上运行的 Gitlab 服务器)的安装和迁移非常麻烦,如果可能的话,我们不希望重新安装和迁移。

小智 6

由于这是我试图找到答案时的最佳结果,因此我发布了自己的解决方案,尽管问题已经过去 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 管理器中的“导出”功能

乌班图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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

之后,您应该会进入正常的操作系统实例,只需再次以 root 身份执行 sudo,然后重复上面所解释的grub-installupdate-grub

您还可以使用以下命令在 Ubuntu 上强制创建 grub.cfg 文件:

grub-mkconfig -o /boot/grub/grub.cfg
Run Code Online (Sandbox Code Playgroud)

乌班图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
Run Code Online (Sandbox Code Playgroud)

在将来的内核更新中,如果您想保留配置或其他一些选项,grub 安装程序可能会提示您。选择第一个 - 安装“包维护者”版本(假设您没有对 grub.cfg 进行手动更改,这在服务器 VM 中是不常见的)。由于 Ubuntu 是软件包维护者,因此它应该为您正确设置所有“安全默认值”。

如果您遇到困难,请查看 Ubuntu 20.04 过程及其末尾的提示。

操作系统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
Run Code Online (Sandbox Code Playgroud)

这将为您提供工作 Gen2 / EFI CentOS 7 虚拟机。与 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!
Run Code Online (Sandbox Code Playgroud)

之后,您应该会进入正常的操作系统实例,只需再次以 root 身份执行 sudo,然后重复上面所解释的grub2-installgrub2-mkconfig

包起来

我认为有些部分可以做得更好/不同,因为我发现了这个主题的很多变化,正如已经从 Ubuntu 与 CentOS 中看到的那样。

如果有人偶然发现更好的方法,请在下面的评论中告诉我。我有一整套由各种 Ubuntu/CentOS/Debian 虚拟机组成的生产服务器环境,将于 2021 年从 Gen1 转换为 Gen2。所以欢迎任何补充!

我在研究中使用的几个链接:

https://unix.stackexchange.com/questions/418401/grub-error-you-need-to-load-kernel-first

https://help.ubuntu.com/community/Installation/UEFI-and-BIOS/stable-alternative#Create_boot-loading_systems_for_external_drives

如何使用 UEFI 将 Linux 磁盘从 MBR 转换为 GPT?

https://askubuntu.com/questions/831216/how-can-i-reinstall-grub-to-the-efi-partition/1203713#1203713

https://unix.stackexchange.com/questions/152222/equivalent-of-update-grub-for-rhel-fedora-centos-systems