在升级内核或尝试重启 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_64 和 initramfs-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: Warning: dracut-initqueue timeout - starting timeout scripts
dracut-initqueue: Warning: Could not boot.
Started Show Plymouth Boot Screen.
Reached target Paths.
Reached target Basic System.
dracut-initqueue: Warning: /dev/disk/by-uuid/55da5202-8008-43e8-8ade-2572319d9185 does not exist
dracut-initqueue: 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 发行版的文档。