Linux

將 Hyper-V linux 機器轉換為 Gen 2

  • December 7, 2021

有什麼方法可以輕鬆(且無需重新安裝)將 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 的所有做法,但是它仍然不存在,至少在 Gen1 上)。

原始 VM 在 Windows Server 2008 主機上執行。我們已經升級到 2012 R2 主機,現在可以執行 Gen2,但是我發現的每個來源都說你必須為它重新安裝 linux(我無法弄清楚為什麼,但我確信應該有一個原因)。

這個特定伺服器(它是在 Ubuntu 14.04 上執行的 Gitlab 伺服器)的安裝和遷移非常麻煩,如果可能的話,我們不希望重新安裝和遷移。

由於這是我試圖找到答案時的最佳結果,因此我發布了自己的解決方案,即使問題已經 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:我建議在此過程之前備份整個 VM,例如使用 Hyper-V 管理器中的“導出”功能

Ubuntu 20.04

以下是基於我的 Ubuntu 20.04 虛擬機的說明(為此目的全新安裝,預設安裝設置):

# 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-installand 。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-installand 。grub2-mkconfig

包起來

我認為某些部分可以做得更好/不同,因為我發現該主題有很多變體,正如已經從 Ubuntu vs 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

引用自:https://serverfault.com/questions/654828