为什么我的 EC2 Linux 实例启动失败并进入紧急模式?
上次更新日期:2021 年 5 月 10 日
当我启动我的 Amazon Elastic Compute Cloud (Amazon EC2) Linux 实例时,该实例会进入紧急模式,启动过程失败。然后,该实例无法访问。如何修复此问题?
简短描述
可能导致实例在紧急模式下启动的最常见原因包括:
- 内核损坏。
- /etc/fstab 中有错误条目导致自动挂载失败。
要验证具体出现了哪种类型的错误,请查看实例的控制台输出。如果内核损坏,您可能会在控制台中输出看到一条内核故障错误消息。如果自动挂载失败,则将在控制台输出中显示依赖项失败消息。
解决方法
内核故障错误
如果 grub 配置或 initramfs文件损坏,则将出现内核故障错误消息。如果内核存在问题,您可能会在控制台输出中看到“内核故障 – 不同步: VFS: 无法在未知块 (8,1) 上挂载根 fs”错误。
要解决内核故障错误:
1. 将内核恢复到上一个稳定的内核。有关如何恢复以前内核的更多信息,请参阅当因为更新导致 Amazon EC2 实例无法成功重启时,如何恢复到已知的稳定内核?
2. 在您恢复到以前的内核后,重启实例。然后纠正损坏内核上的问题。
依赖项失败错误
/etc/fstab 文件中的语法错误导致的自动挂载失败可能会导致实例进入紧急模式。此外,如果文件中列出的 Amazon Elastic Block Store (Amazon EBS) 卷已与实例分离,则实例启动过程可能进入紧急模式。如果出现以上任意一种问题,则控制台输出会与以下类似:
-------------------------------------------------------------------------------------------------------------------
[[1;33mDEPEND[0m] Dependency failed for /mnt.
[[1;33mDEPEND[0m] Dependency failed for Local File Systems.
[[1;33mDEPEND[0m]
Dependency failed for Migrate local... structure to the new structure.
[[1;33mDEPEND[0m] Dependency failed for Relabel all filesystems, if necessary.
[[1;33mDEPEND[0m] Dependency failed for Mark the need to relabel after reboot.
[[1;33mDEPEND[0m]
Dependency failed for File System Check on /dev/xvdf.
-------------------------------------------------------------------------------------------------------------------
前面的示例日志消息显示,/mnt 挂载点在启动过程中未能成功挂载。
要防止引导顺序因挂载失败而进入紧急模式:
- 在辅助分区(上例中的 /mnt)的 /etc/fstab 文件中添加 nofail 选项。存在 nofail 选项时,引导顺序不会发生中断,即使任何卷或分区的挂载失败。
- 将 0 添加为相关挂载点的 /etc/fstab 文件最后一列。添加 0 列将会禁用文件系统检查,从而允许该实例能够成功启动。
您可以使用三方法来更正 /etc/fstab 文件。
重要提示:
方法 2 和 3 需要停止并启动实例。但应注意以下几点:
- 如果您的实例受实例存储支持或具有包含数据的实例存储卷,则在实例停止时数据将丢失。有关更多信息,请参阅确定实例的根设备类型。
- 如果您的实例是 Amazon EC2 Auto Scaling 组的一部分,则停止实例可能会终止实例。使用 Amazon EMR、AWS CloudFormation、AWS Elastic Beanstalk 启动的实例可能是 AWS Auto Scaling 组的一部分。在这种情况下,是否会发生实例终止取决于您的 Auto Scaling 组的实例缩减保护设置。如果您的实例是 Auto Scaling 组的一部分,请在开始执行解决步骤之前,暂时从 Auto Scaling 组中删除它。
- 停止和启动实例会更改实例的公共 IP 地址。在将外部流量路由到您的实例时,最佳做法是使用弹性 IP 地址,而不是公有 IP 地址。
方法 1:使用 EC2 串行控制台
如果您已为 Linux 启用 EC2 串行控制台,则可以使用它来排查受支持的基于 Nitro 的实例类型的问题。串行控制台可帮助您排查启动问题、网络配置和 SSH 配置问题。串行控制台无需网络连接即可连接到您的实例。您可以使用 Amazon EC2 控制台或 AWS 命令行界面 (AWS CLI) 访问串行控制台。
在使用串行控制台之前,请在账户层面授予对串行控制台的访问权限。然后,创建 AWS Identity and Access Management(IAM)策略,授予对 IAM 用户的访问权限。此外,每个使用串行控制台的实例都必须至少包含一个基于密码的用户。如果您的实例无法访问,并且尚未配置对串行控制台的访问权限,请按照方法 2 中的说明进行操作。有关为 Linux 配置 EC2 串行控制台的信息,请参阅配置对 EC2 串行控制台的访问权限。
注意:如果在运行 AWS CLI 命令时遇到错误,请确保您使用的是最新版本的 AWS CLI。
方法 2:运行 AWSSupport-ExecuteEC2Rescue Automation 文档
如果您的实例配置了 AWS Systems Manager,则可以运行 AWSSupport-ExecuteEC2Rescue Automation 文档以纠正启动问题。使用这种方法时不需要手动干预。有关使用 Automation 文档的更多信息,请参阅演练:在无法访问的实例上运行 EC2Rescue 工具。
方法 3:使用救援实例手动编辑文件
1. 打开 Amazon EC2 控制台。
2. 从导航窗格中选择实例,然后选择处于紧急模式的实例。
3. 停止该实例。
4. 从已停止的实例分离 Amazon EBS 根卷(/dev/xvda 或 /dev/sda1)。
5. 在受损实例所在的可用区中启动新的 EC2 实例。此新实例将成为您的“救援”实例。
6. 将您在第 4 步中分离的根卷挂载到救援实例以作为辅助设备。
注意:挂载辅助卷时可以使用不同的设备名称。
7. 使用 SSH 连接到您的救援实例。
8. 为您在第 6 步中挂载到救援实例的新卷创建挂载点目录。在下例中,挂载点目录为 /mnt/rescue。
$ sudo mkdir /mnt/rescue
9. 将该卷挂载到您在第 8 步中创建的目录。
$ sudo mount /dev/xvdf /mnt/rescue
注意:可以用不同的设备名称将设备(上例中的 /dev/xvdf)挂载到救援实例。使用 lsblk 命令查看可用磁盘设备及其挂载点,以确定正确的设备名称。
10. 挂载卷后,运行以下命令打开 /etc/fstab 文件。
$ sudo vi /mnt/rescue/etc/fstab
11. 根据需要编辑 /etc/fstab 中的条目。以下示例输出显示用 UUID 定义了三个 EBS 卷,两个辅助卷都添加了 nofail 选项,并且每个条目的最后一列都为 0。
------------------------------------------------------------------------------------------
$ cat /etc/fstab
UUID=e75a1891-3463-448b-8f59-5e3353af90ba / xfs defaults,noatime 1 0
UUID=87b29e4c-a03c-49f3-9503-54f5d6364b58 /mnt/rescue ext4 defaults,noatime,nofail 1 0
UUID=ce917c0c-9e37-4ae9-bb21-f6e5022d5381 /mnt ext4 defaults,noatime,nofail 1 0
------------------------------------------------------------------------------------------
12. 保存文件,然后运行 umount 命令来卸载卷。
$ sudo umount /mnt/rescue
13. 从临时实例分离该卷。
14. 将卷挂载到原始实例,然后启动该实例以确认其启动成功。