Linux 虚拟机启动到 GRUB 救援

适用于:✔️ Linux VM

备注

本文中引用的 CentOS 是 Linux 分发版,将达到生命周期结束(EOL)。 请相应地考虑使用和规划。 有关详细信息,请参阅 CentOS 生命周期指南

本文讨论导致 GRUB 救援问题的多个条件,并提供故障排除指南。

在启动过程中,启动加载程序会尝试找到 Linux 内核并移交启动控件。 如果无法执行此移交,虚拟机(VM)将进入 GRUB 救援控制台。 GRUB 救援控制台提示未显示在 Azure 串行控制台日志中,但可以在 Azure 启动诊断屏幕截图显示。

识别 GRUB 救援问题

在Azure 门户的 VM 启动诊断页中查看启动诊断屏幕截图。 此屏幕截图有助于诊断 GRUB 救援问题,并确定启动错误是否导致该问题。

以下文本是 GRUB 救援问题的一个示例:

error: file '/boot/grub2/i386-pc/normal.mod' not found.  
Entering rescue mode...  
grub rescue>

排查 GRUB 脱机救援问题

  1. 若要排查 GRUB 救援问题,需要救援/修复 VM。 使用 VM 修复命令 创建已附加受影响 VM OS 磁盘副本的修复 VM。 使用 chroot 在修复 VM 中装载 OS 文件系统的副本。

    备注

    或者,可以使用 Azure 门户手动创建救援 VM。 有关详细信息,请参阅通过使用 Azure 门户将 OS 磁盘附加到恢复 VM 来对 Linux VM 进行故障排除

  2. 确定 GRUB 救援问题。 遇到以下 GRUB 救援问题之一时,请转到相应的部分解决此问题:

  3. 解决 GRUB 救援问题后,执行以下作:

    1. 从救援/修复 VM 中卸载文件系统的副本。

    2. az vm repair restore运行以下命令,将修复的 OS 磁盘与 VM 的原始 OS 磁盘交换。 有关详细信息,请参阅使用 Azure 虚拟机修复命令修复 Linux VM 中的步骤 5。

    3. 查看 Azure 串行控制台还是尝试连接到 VM,检查 VM 是否可以启动。

  4. 如果整个 /boot 分区或其他重要内容缺失且无法恢复,建议从备份还原 VM。 有关详细信息,请参阅如何还原 Azure 门户 中的 Azure VM 数据。

有关详细错误、可能的原因和解决方案,请参阅以下部分。

备注

在以下部分中提到的命令中,替换为 /dev/sdX 相应的作系统(OS)磁盘设备。

使用 Azure Linux 自动修复重新安装 GRUB 并重新生成 GRUB 配置文件

Azure Linux 自动修复(ALAR)脚本是使用 Azure Linux 自动修复(ALAR)修复 Linux VM 中所述 的 VM 修复扩展的一部分。 ALAR 涵盖了多个修复方案的自动化,包括 GRUB 救援问题。

ALAR 脚本使用修复扩展 repair-button 通过指定 --button-command grubfix 第 1 代 VM 或 --button-command efifix 第 2 代 VM 来修复 GRUB 问题。 此参数触发自动恢复。 通过重新安装 GRUB 并重新生成相应的配置文件,实现以下命令来自动修复常见的 GRUB 错误:

  • 没有 UEFI 的 Linux VM(基于 BIOS - Gen1):

    az extension add -n vm-repair
    az extension update -n vm-repair
    az vm repair repair-button --button-command 'grubfix' --verbose $RGNAME --name $VMNAME
    
  • 具有 UEFI 的 Linux VM(Gen2):

    az extension add -n vm-repair
    az extension update -n vm-repair
    az vm repair repair-button --button-command 'efifix' --verbose $RGNAME --name $VMNAME
    

重要

相应地替换资源组名称和 $RGNAME VM 名称 $VMNAME

修复 VM 脚本与 ALAR 脚本一起临时创建资源组、修复 VM 和受影响 VM OS 磁盘的副本。 它重新安装 GRUB,重新生成相应的 GRUB 配置文件,然后将损坏的 VM 的 OS 磁盘与复制的固定磁盘交换。 最后,脚本 repair-button 会自动删除包含临时修复 VM 的资源组。

重新安装 GRUB 并手动重新生成 GRUB 配置文件

  1. 检查是否已创建救援/修复 VM。 如果未创建,请按照脱机排查 GRUB 救援问题中的步骤 1 创建 VM。 装载所有必需的文件系统,包括在//boot救援/修复 VM 中,然后进入 chroot 环境。

  2. 使用以下命令之一重新安装 GRUB 并重新生成相应的 GRUB 配置文件:

    • 没有 UEFI 的 RHEL/CentOS/Oracle 7.x/8.x/9.x Linux VM(基于 BIOS - Gen1)

      grub2-install /dev/sdX
      grub2-mkconfig -o /boot/grub2/grub.cfg
      sed -i 's/hd2/hd0/g' /boot/grub2/grub.cfg
      
    • RHEL/CentOS/Oracle 7.x/8.x/9.x Linux VM 与 UEFI (Gen2)

      yum reinstall grub2-efi-x64 shim-x64
      grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
      sed -i 's/hd2/hd0/g' /boot/efi/EFI/redhat/grub.cfg
      

      如果 VM 正在运行 CentOS,请替换为 redhatcentosgrub.cfg 文件绝对路径 /boot/efi/EFI/centos/grub.cfg。

    • SLES 12/15 Gen1 和 Gen2

      grub2-install /dev/sdX
      grub2-mkconfig -o /boot/grub2/grub.cfg
      sed -i 's/hd2/hd0/g' /boot/grub2/grub.cfg
      
    • Ubuntu Gen1 和 Gen2

      grub-install /dev/sdX
      update-grub
      
  3. 请转到排查 GRUB 救援问题脱机以交换 OS 磁盘的步骤 3

错误:未知文件系统

以下屏幕截图显示了错误消息:

grub 未知文件系统错误的屏幕截图。

此错误可能与以下问题之一相关联:

  • /boot 文件系统损坏。

    若要解决此问题,请按照修复 /启动文件系统损坏中的步骤进行作。

  • GRUB 启动加载程序指向无效的磁盘或分区。

    若要解决此问题, 请重新安装 GRUB 并手动重新生成 GRUB 配置文件。

  • 由人为错误导致的 OS 磁盘分区表问题。

    若要解决此类问题,请按照“错误”中的 步骤作:如果没有此类分区 来重新创建 /boot 分区(如果缺失或创建错误)。

修复 /启动文件系统损坏

若要修复 /boot 文件系统损坏,请执行以下步骤:

  1. 检查是否已创建救援/修复 VM。 如果未创建,请按照脱机排查 GRUB 救援问题中的步骤 1 创建 VM。

  2. 请参阅排查 Azure Linux 中的文件系统损坏错误,以解决相应 /boot 分区中的损坏问题。

  3. 请转到排查 GRUB 救援问题脱机以交换 OS 磁盘的步骤 3

错误 15:找不到文件

以下屏幕截图显示了错误消息:

找不到 grub 错误 15 文件的屏幕截图。

若要解决此问题,请按照下列步骤操作:

  1. 检查是否已创建救援/修复 VM。 如果未创建,请按照脱机排查 GRUB 救援问题中的步骤 1 创建 VM。 装载所有必需的文件系统,包括在//boot救援/修复 VM 中,然后进入 chroot 环境。

  2. /boot检查文件系统内容并确定缺少的内容。

  3. 如果缺少 GRUB 配置文件, 请重新安装 GRUB 并手动重新生成 GRUB 配置文件。

  4. 验证文件系统中的 /boot 文件权限是否正常。 可以使用运行同一 Linux 版本的另一个 VM 来比较权限。

  5. 如果缺少整个 /boot 分区或其他重要内容,并且无法恢复,建议从备份还原 VM。 有关详细信息,请参阅如何还原 Azure 门户 中的 Azure VM 数据。

  6. 解决问题后,请转到 GRUB 救援问题脱机中的步骤 3 以交换 OS 磁盘。

错误:找不到文件“/boot/grub2/i386-pc/normal.mod”

以下屏幕截图显示了错误消息:

找不到 grub 错误 normal.mod 的屏幕截图。

  1. 检查是否已创建救援/修复 VM。 如果未创建,请按照脱机排查 GRUB 救援问题中的步骤 1 创建一个。 装载所有必需的文件系统,包括在//boot救援/修复 VM 中,然后进入 chroot 环境。

  2. 如果由于损坏错误而无法装载 /boot 文件系统, 请修复 /boot 文件系统损坏

  3. 位于 chroot 内部时,请验证目录中的内容 /boot/grub2/i386-pc 。 如果缺少内容,请从 /usr/lib/grub/i386-pc中复制内容。 为此,请使用以下命令:

    ls -l /boot/grub2/i386-pc
    cp -rp /usr/lib/grub/i386-pc /boot/grub2
    
  4. 如果分区的内容 /boot 为空,请使用以下命令重新创建它:

    备注

    以下步骤适用于没有 UEFI(基于 BIOS - Gen1)的 RHEL/CentOS/Oracle 7.x/8.x Linux VM。

    1. 在 chroot 进程下,重新安装 grub。 相应地替换为 /dev/sd[X] 附加到修复/救援 VM 的 OS 磁盘的相应副本:

      grub2-install /dev/sd[X]
      
    2. 确保 /etc/resolv.conf 具有有效的 DNS 条目,以便解析存储库的名称:

      cat /etc/resolv.conf
      
    3. 重新安装内核:

      yum reinstall $(rpm -qa | grep -i kernel)
      
    4. 创建 grub.cfg 文件:

      grub2-mkconfig -o /boot/grub2/grub.cfg
      sed -i 's/hd2/hd0/g' /boot/grub2/grub.cfg
      
  5. 继续执行步骤 3,排查 GRUB 救援问题脱机 以交换 OS 磁盘。

错误:没有此类分区

以下屏幕截图显示了错误消息:

grub 错误没有此类分区的屏幕截图。

在以下方案之一中,基于 RHEL 的 VM(Red Hat、Oracle Linux、CentOS)上出现此错误:

  • /boot分区被错误删除。
  • 使用 /boot 错误的开始和结束扇区重新创建分区。

解决方案:重新创建/启动分区

/boot如果分区缺失,请按照以下步骤重新创建分区:

  1. 检查是否已创建救援/修复 VM。 如果未创建,请按照脱机排查 GRUB 救援问题中的步骤 1 创建 VM。

  2. 使用以下命令确定分区表是否创建为 dosGPT 类型:

    sudo fdisk -l /dev/sdX
    
    • Dos 分区表

      屏幕截图显示了使用 dos 类型分区表启动。

    • GPT 分区表

      屏幕截图显示了使用 GPT 类型分区表启动。

  3. 如果分区表具有 分区表类型, 请在 dos 系统中重新创建 /启动分区。 如果分区表具有 GPT 作为分区表类型,请在 GPT 系统中重新创建 /启动分区。

  4. 请确保使用正确的磁盘安装 GRUB 启动加载程序。 可以按照重新安装 GRUB 中的 步骤手动 重新生成 GRUB 配置文件以安装并配置该文件。

  5. 继续执行步骤 3,排查 GRUB 救援问题脱机 以交换 OS 磁盘。

在 dos 系统中重新创建/启动分区

  1. 使用以下命令从救援/修复 VM 重新创建 /boot 分区:

    sudo fdisk /dev/sdX
    

    使用“第一个”和“最后”扇区中的默认值,以及分区类型(83)。 /boot请确保使用工具中的a选项将分区表标记为可fdisk启动,如以下输出所示:

    sudo fdisk /dev/sdc
    
    The device presents a logical sector size that is smaller than
    the physical sector size. Aligning to a physical sector (or optimal
    I/O) size boundary is recommended, or performance may be impacted.
    Welcome to fdisk (util-linux 2.23.2).
    
    Changes will remain in memory only, until you decide to write them.
    Be careful before using the write command.
    
    Command (m for help): n
    Partition type:
       p   primary (1 primary, 0 extended, 3 free)
       e   extended
    Select (default p): p
    Partition number (1,3,4, default 1): 1
    First sector (2048-134217727, default 2048):
    Using default value 2048
    Last sector, +sectors or +size{K,M,G} (2048-2099199, default 2099199):
    Using default value 2099199
    Partition 1 of type Linux and of size 1 GiB is set
    
    Command (m for help): t
    Partition number (1,2, default 2): 1
    Hex code (type L to list all codes): 83
    Changed type of partition 'Linux' to 'Linux'
    
    Command (m for help): a
    Partition number (1,2, default 2): 1
    
    Command (m for help): p
    
    Disk /dev/sdc: 68.7 GB, 68719476736 bytes, 134217728 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 4096 bytes
    I/O size (minimum/optimal): 4096 bytes / 4096 bytes
    Disk label type: dos
    Disk identifier: 0x000b7179
    
    Device Boot      Start         End      Blocks   Id  System
    /dev/sdc1   *        2048     2099199     1048576   83  Linux
    /dev/sdc2         2099200   134217727    66059264   8e  Linux LVM
    
    Command (m for help): w
    The partition table has been altered!
    
    Calling ioctl() to re-read partition table.
    
  2. 重新创建缺少 /boot 的分区后,请检查 /boot 是否检测到文件系统。 应该可以看到一个条目 /dev/sdX1 (缺少 /boot 分区)。

    sudo blkid /dev/sdX1
    
    sudo blkid /dev/sdc1
    /dev/sdc1: UUID="<UUID>" TYPE="ext4"
    
  3. /boot如果在重新创建分区后文件系统不可见blkid,这意味着/boot数据不再存在。 必须重新创建/boot文件系统(使用条目中的/etc/fstab/boot相同 UUID 和文件系统格式),然后从备份还原其内容。

在 GPT 系统中重新创建 /启动分区

  1. 使用以下命令从救援/修复 VM 重新创建 /boot 分区:

    sudo gdisk /dev/sdX
    

    使用“第一个”和“最后一个”扇区中的默认值,以及分区类型(8300),如以下输出所示:

    sudo gdisk /dev/sdc
    GPT fdisk (gdisk) version 1.0.3
    
    Partition table scan:
      MBR: protective
      BSD: not present
      APM: not present
      GPT: present
    
    Found valid GPT with protective MBR; using GPT.
    
    Command (? for help): n
    Partition number (1-128, default 1): 1
    First sector (34-134217694, default = 1026048) or {+-}size{KMGTP}:
    Last sector (1026048-2050047, default = 2050047) or {+-}size{KMGTP}:
    Current type is 'Linux filesystem'
    Hex code or GUID (L to show codes, Enter = 8300):
    Changed type of partition to 'Linux filesystem'
    
    Command (? for help): p
    Disk /dev/sdc: 134217728 sectors, 64.0 GiB
    Model: Virtual Disk
    Sector size (logical/physical): 512/4096 bytes
    Disk identifier (GUID): 6D915856-445A-4513-97E4-C55F2E1AD6C0
    Partition table holds up to 128 entries
    Main partition table begins at sector 2 and ends at sector 33
    First usable sector is 34, last usable sector is 134217694
    Partitions will be aligned on 2048-sector boundaries
    Total free space is 6076 sectors (3.0 MiB)
    
    Number  Start (sector)    End (sector)  Size       Code  Name
       1         1026048         2050047   500.0 MiB   8300  Linux filesystem
       2         2050048       134215679   63.0 GiB    8E00
      14            2048           10239   4.0 MiB     EF02
      15           10240         1024000   495.0 MiB   EF00  EFI System Partition
    
    Command (? for help): w
    
    Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
    PARTITIONS!!
    
    Do you want to proceed? (Y/N): Y
    OK; writing new GUID partition table (GPT) to /dev/sdc.
    Warning: The kernel is still using the old partition table.
    The new table will be used at the next reboot or after you
    run partprobe(8) or kpartx(8)
    The operation has completed successfully.
    
  2. 使用以下命令检查系统是否 /boot 检测到文件系统:

    sudo blkid /dev/sdX1
    

    应该可以看到一个条目 /dev/sdX1 (缺少 /boot 的分区)。

    sudo blkid /dev/sdc1
    /dev/sdc1: UUID="<UUID>" BLOCK_SIZE="4096" TYPE="xfs" PARTLABEL="Linux filesystem" PARTUUID="<PARTUUID>"
    
  3. /boot如果在重新创建分区后文件系统不可见,这意味着/boot数据不再存在。 必须重新创建/boot文件系统(使用条目中的/etc/fstab/boot同一 UUID),然后从备份还原其内容。

错误:找不到符号“grub_efi_get_secure_boot”

以下屏幕截图显示了错误消息:

找不到 grub 错误“grub_efi_get_secure_boot”的屏幕截图。

Linux 内核版本 4.12.14(在 SLES 12 SP5 中使用的)不支持 安全启动 选项。 因此,如果在部署 VM 期间启用了安全启动(即 “安全类型 ”字段设置为 “受信任的启动虚拟机”),则尝试在 Gen2 VM 映像上使用此 SUSE 内核版本启动时,虚拟机会通过控制台生成安全启动错误。

解决方案

若要解决启动错误,请执行以下步骤:

  1. 检查是否已创建救援/修复 VM。 如果未创建,请按照脱机排查 GRUB 救援问题中的步骤 1 创建 VM。 装载所有必需的文件系统,包括 //boot,然后输入 chroot 环境。

  2. 在 chroot 环境中运行以下 YaST 命令:

    yast2 bootloader
    
  3. “启用安全启动支持 ”选项中清除“x”,然后选择 F10 保存更改。

    SUSE 控制台中 YaST2 启动加载程序设置的屏幕截图。

  4. 请按照脱机排查 GRUB 救援问题中的步骤 3 交换 OS 磁盘。

其他 GRUB 救援错误

以下屏幕截图显示了错误消息:

另一个 grub 救援问题的屏幕截图。

在以下情况之一中触发此类错误:

  • 缺少 GRUB 配置文件。
  • 使用了错误的 GRUB 配置。
  • 分区 /boot 或其内容缺失。

若要解决此错误,请按照下列步骤操作:

  1. 检查是否已创建救援/修复 VM。 如果未创建,请按照脱机排查 GRUB 救援问题中的步骤 1 创建 VM。 装载所有必需的文件系统,包括 //boot,然后输入 chroot 环境。

  2. 确保 /etc/default/grub 配置了配置文件。 认可的 Azure Linux 映像已具有所需的配置。 有关详细信息,请参阅以下文章:

  3. 重新安装 GRUB 并手动重新生成 GRUB 配置文件。

    备注

    如果缺少文件 /boot/grub/menu.lst,则此错误适用于较旧的 OS 版本(RHEL 6.x、Centos 6.x 和 Ubuntu 14.04)。 命令将有所不同,因为 GRUB 版本 1 用于这些系统。 本文未介绍 GRUB 版本 1。

  4. 如果缺少整个 /boot 分区,请按照错误中的 步骤作:没有此类分区

  5. 解决问题后,请转到 GRUB 救援问题脱机中的步骤 3 以交换 OS 磁盘。

后续步骤

如果特定的启动错误不是 GRUB 救援问题,请参阅排查 Azure Linux 虚拟机启动错误以获取进一步故障排除选项。

第三方信息免责声明

本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 对这些产品的性能和可靠性不作任何明示或默示担保。

第三方联系人免责声明

Microsoft 会提供第三方联系信息来帮助你查找有关本主题的其他信息。 此联系信息可能会更改,恕不另行通知。 Microsoft 不保证第三方联系信息的准确性。

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区