Linux 虚拟机启动到 GRUB 救援

注意

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

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

在启动过程中,启动加载程序会尝试找到 Linux 内核并移交启动控件。 如果无法执行此切换,虚拟机 (VM) 将进入 GRUB 救援控制台。 Azure 串行控制台日志中未显示 GRUB 救援控制台提示,但可以在 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,该 VM 附加了受影响 VM 的 OS 磁盘的副本。 使用 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) 磁盘设备。

错误:未知文件系统

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

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

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

修复 /启动文件系统损坏

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

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

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

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

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

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

    • 不基于 UEFI 的 RHEL/CentOS/Oracle 7.x/8.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 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,请将 grub.cfg 文件绝对路径 /boot/efi/EFI/centos/grub.cfg 中的 替换为 redhatcentos

    • 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 18.04/20.04

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

错误 15:找不到文件

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

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

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

  1. 检查是否已创建救援/修复 VM。 如果未创建,请按照 脱机排查 GRUB 救援问题 中的步骤 1 创建 VM。 在救援/修复 VM 中装载所有必需的文件系统,包括 /和 /boot ,然后进入 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 创建一个。 在救援/修复 VM 中装载所有必需的文件系统,包括 /和 /boot,然后进入 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 的 RHEL/CentOS/Oracle 7.x/8.x Linux VM (BIOS - Gen1) 。

    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. Create grub.cfg 文件:

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

错误:无此类分区

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

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

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

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

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

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

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

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

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

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

    • GPT 分区表

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

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

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

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

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

  1. 使用以下命令重新创建 /boot 分区:

    sudo fdisk /dev/sdX
    

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

    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 文件系统。 你应该能够看到 (缺少的 /boot 分区) 的条目 /dev/sdX1

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

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

  1. 使用以下命令重新创建 /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
    

    你应该能够看到 (缺少的 /boot 分区) 的条目 /dev/sdX1

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

错误:找不到符号“grub_efi_get_secure_boot”

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

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

SLES 12 SP5) 中使用的 Linux 内核版本 4.12.14 (不支持 安全启动 选项。 因此,如果在部署 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,则此错误适用于较旧的操作系统版本, (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 反馈社区提交产品反馈。