在升级内核或尝试重启 EC2 Linux 实例后,我收到“内核崩溃”错误。如何解决此问题?

上次更新时间:2020 年 5 月 28 日

在完成内核或系统升级后,或者在 Amazon Elastic Compute Cloud (Amazon EC2) 实例上重启系统后,该实例无法启动,并显示以下消息:

“VFS:无法打开根设备 XXX 或未知块 (0,0)
请附加正确的“root=”启动选项;以下是可用分区:
内核崩溃 - 不同步:VFS:无法在未知块 (0,0) 上挂载根 fs”

简短描述

您的实例可能因以下原因而无法启动并显示内核崩溃错误消息:

  • /boot/grub/grub.conf 中新更新的内核配置中缺少 initramfs 或 initrd 映像。或者,/boot 目录中缺少 initrd 或 initramfs 文件。
  • 由于空间不足,在升级过程中未完全安装内核或系统软件包。
  • initrd 或 initramfs 映像中缺少第三方模块。例如,NVMe、LVM 或 RAID 模块。

解决方法

/boot/grub/grub.conf 或 /boot 目录中缺少 initramfs 或 initrd 映像

警告:

  • 此过程需要停止和启动您的 EC2 实例。请注意,如果您的实例受实例存储支持或具有包含数据的实例存储卷,则在实例停止时数据将丢失。有关更多信息,请参阅确定实例的根设备类型
  • 如果您使用 EC2 Auto Scaling 启动实例,则停止实例可能会终止该实例。某些 AWS 服务使用 EC2 Auto Scaling 启动实例,如 Amazon EMR、AWS CloudFormation 和 AWS Elastic Beanstalk。检查 Auto Scaling 组的实例缩减保护设置。如果您的实例是 Auto Scaling 组的一部分,请在开始执行解决步骤之前,暂时从 Auto Scaling 组中删除该实例
  • 停止并重启实例时,该实例的公有 IP 地址会发生更改。在将外部流量路由到您的实例时,最佳实践是使用弹性 IP 地址而不是公有 IP 地址。

1.    打开 Amazon EC2 控制台

2.    从导航窗格中选择实例,然后选择受损实例。

3.    依次选择操作实例状态停止

4.    在描述选项卡中,选择根设备,然后选择 EBS ID

注意:在继续执行步骤 5 之前,您可以创建根卷的快照作为备份。

5.    选择 操作,然后选择分离卷/dev/sda1/dev/xvda),再选择是,请分离

6.    验证以确认状态可用

7.    在与原始实例相同的可用区和操作系统中启动新的 EC2 实例。新实例是您的救援实例。

8.    启动救援实例后,从导航窗格中选择,然后选择原始实例已分离的根卷。

9.    选择操作,然后选择连接卷

10.    选择救援实例 ID (1-xxxx),然后输入 /dev/xvdf

11.    运行以下命令,以确认受损实例的根卷已成功附加到救援实例:

$ lsblk

以下是该输出的示例:

NAME    MAJ:MIN   RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0     0   15G  0 disk
└─xvda1 202:1     0   15G  0 part /
	xvdf    202:80    0  15G  0 disk
    └─xvdf1 202:0 0  15G  0 part

12.    创建挂载目录,然后在 /mnt 下进行挂载。

$ mount /dev/xvdf1 /mnt

13.    通过运行以下命令来执行并调用 chroot 环境:

$ for i in dev proc sys run; do mount -o bind /$i /mnt/$i; done

14.    在已挂载的 /mnt 文件系统上运行 chroot 命令:

$ chroot /mnt

注意:工作目录将更改为 "/"。

15.    根据您的操作系统,运行以下命令。

基于 RPM 的操作系统:

$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
$ sudo dracut -f -vvvvv

基于 Debian 的操作系统:

$ sudo update-grub && sudo update-grub2
$ sudo update-initramfs -u -vvvvv

16.    验证 initrd 或 initramfs 映像位于 /boot 目录下,并且该映像具有相应的内核映像。例如,vmlinuz-4.14.138-114.102.amzn2.x86_64initramfs-4.14.138-114.102.amzn2.x86_64.img

17.    在验证最新内核具有相应的 initrd 或 initramfs 映像后,运行以下命令以退出并清理 chroot 环境:

$ exit
$ for i in dev proc sys run; do sudo umount /mnt/$i; done

18.    从救援实例中分离根卷并将卷连接到原始实例

19.    启动原始实例。

在更新过程中未完全安装内核或系统软件包

恢复到以前的内核版本。有关恢复到以前内核的说明,请参阅当因为更新导致 Amazon EC2 实例无法成功重启时,如何恢复到已知的稳定内核?

initrd 或 initramfs 映像中缺少第三方模块

调查以确定 initrd 或 initramfs 映像中缺少哪些模块,并验证是否可以将该模块重新添加到映像中。在许多情况下,重建实例将更加容易。

以下是在 Nitro 平台上运行的 Amazon Linux 2 实例的控制台输出示例。该实例的 initramfs 映像中缺少 nvme.ko 模块:

dracut-initqueue[1180]: Warning: dracut-initqueue timeout - starting timeout scripts
dracut-initqueue[1180]: Warning: Could not boot.
[  OK  ] Started Show Plymouth Boot Screen.
[  OK  ] Reached target Paths.
[  OK  ] Reached target Basic System.
dracut-initqueue[1180]: Warning: /dev/disk/by-uuid/55da5202-8008-43e8-8ade-2572319d9185 does not exist
dracut-initqueue[1180]: Warning: Boot has failed. To debug this issue add "rd.shell rd.debug" to the kernel command line.
Starting Show Plymouth Power Off Screen...

要确定内核崩溃错误是否由缺少第三方模块所导致,请执行以下操作:

1.    按照前面 /boot/grub/grub.conf 或 /boot 目录中缺少 initramfs 或 initrd 映像部分中的步骤 1 至 14 执行操作,以在非启动实例的根卷中创建 chroot 环境。

2.    使用以下三个选项来确定 initramfs 或 initrd 映像中缺少哪些模块 :

选项 1:在 /boot 目录中运行 dracut -f -v 命令,以确定重建 initrd 或 initramfs 映像是否失败,并列出缺少的模块。
注意:dracut -f -v 命令可能会将任何缺少的模块添加到 initrd 或 intramifs 映像中。如果该命令未发现任何错误,请尝试重启实例。如果实例重启成功,则表示该命令已解决错误。

选项 2:运行 lsinitrd initramfs-4.14.138-114.102.amzn2.x86_64.img | less 命令以查看 initrd 或 initramfs 文件的内容。请将 initramfs-4.14.138-114.102.amzn2.x86_64.img 替换为您的映像的名称。

选择 3:检查 /usr/lib/modules 目录。

3.    如果您发现了缺少的模块,则可以尝试将其重新添加到内核中。有关如何获取模块并将其添加到内核的信息,请参阅特定于 Linux 发行版的文档。


这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助?