因操作系统问题,我的 EC2 Linux 实例的实例状态检查失败。如何解决此问题?

上次更新时间:2020 年 6 月 2 日

由于操作系统问题,我的 Amazon Elastic Compute Cloud (Amazon EC2) Linux 实例的实例状态检查失败。现在,它不能成功启动。如何解决此问题?

简短描述

您的 EC2 Linux 实例的实例状态检查可能会因以下原因失败:

  • 您已经更新了内核,而新内核无法启动。
  • /etc/fstab 中的文件系统条目不正确,或文件系统损坏。
  • 实例上的网络配置不正确。

解决方法

警告:停止并启动实例前,确保了解以下内容:

  • 当您停止和启动实例时,实例存储数据丢失。如果您的实例受实例存储支持或具有包含数据的实例存储卷,则在实例停止时数据将丢失。有关更多信息,请参阅确定实例的根设备类型
  • 如果您的实例是 Amazon EC2 Auto Scaling 组的一部分,停止实例可能会终止实例。如果您使用 Amazon EMR、AWS CloudFormation 或 AWS Elastic Beanstalk 启动实例,您的实例可能是 AWS Auto Scaling 组的一部分。在这种情况下,是否会发生实例终止取决于您的 Auto Scaling 组的实例缩减保护设置。如果您的实例是 Auto Scaling 组的一部分,则在开始执行解决步骤之前,暂时从 Auto Scaling 组中删除该实例
  • 停止和启动实例会更改实例的公共 IP 地址。在将外部流量路由到您的实例时,最佳做法是使用弹性 IP 地址而不是公有 IP 地址。如果您使用 Amazon Route 53,您可能必须在公有 IP 更改时更新 Route 53 DNS 记录
  • 如果实例的关闭行为设置为终止,则实例停止时将会终止。您可以更改实例关闭行为以避免此情况。

运行 EC2Rescue for Linux 工具

EC2Rescue for Linux 会自动诊断无法访问的实例上的操作系统问题并对其进行故障排除。有关更多信息,请参阅我的 EC2 Linux 实例不再响应或存在启动问题。如何使用 EC2Rescue for Linux 排查操作系统级问题?

使用救援实例手动纠正错误

1.    使用相同的 Amazon 系统映像 (AMI)、在与受损实例相同的可用区中,在您的 Virtual Private Cloud (VPC) 中启动新的 EC2 实例。此新实例将成为您的“救援”实例。

或者,也可以使用您可以访问的现有实例,但前提是该实例使用与受损实例相同的 AMI,并且二者位于同一可用区中。

2.    停止受损的实例

3.    从受损实例中分离 Amazon Elastic Block Store (Amazon EBS) 根卷/dev/xvda/dev/sda1)。记下根卷的设备名称(/dev/xvda/dev/sda1)。

4.    将卷作为辅助设备 (/dev/sdf) 附加到救援实例。

5.    使用 SSH 连接到您的救援实例

6.    为附加到救援实例的新卷创建挂载点目录 (/rescue):

$ sudo mkdir /rescue

7.    将该卷挂载到您在第 6 步中创建的目录:

$ sudo mount /dev/xvdf1 /rescue

注意:设备 (/dev/xvdf1) 可能会以不同的设备名称附加到救援实例。使用 lsblk 命令查看可用磁盘设备及其挂载点,以确定正确的设备名称。

8.    如果您尚未这样做,请检索实例的系统日志以确认发生了什么错误。下一步骤取决于系统日志中列出的错误消息。下面是可能导致实例状态检查失败的常见错误列表。有关其他错误,请参阅对基于 Linux 的实例进行系统日志错误排查

内核崩溃

如果系统日志中出现内核崩溃错误消息,则内核可能不具有 vmlinuz initramfs 文件。要成功启动,需要有 vmlinuz initramfs 文件。

1.    运行以下命令:

cd /rescue/boot
ls -l

2.    检查输出,以验证您打算启动的内核版本是否有对应的 vmlinuz initramfs 文件。

以下输出示例针对采用内核版本 4.14.165-131.185.amzn2.x86_64 的 Amazon Linux 2 实例。 /boot 目录中包含文件 initramfs-4.14.165-131.185.amzn2.x86_64.imgvmlinuz-4.14.165-131.185.amzn2.x86_64,因此,将会成功启动。

uname -r
4.14.165-131.185.amzn2.x86_64

cd /boot; ls -l
total 39960
-rw-r--r-- 1 root root      119960 Jan 15 14:34 config-4.14.165-131.185.amzn2.x86_64
drwxr-xr-x 3 root root     17 Feb 12 04:06 efi
drwx------ 5 root root       79 Feb 12 04:08 grub2
-rw------- 1 root root 31336757 Feb 12 04:08 initramfs-4.14.165-131.185.amzn2.x86_64.img
-rw-r--r-- 1 root root    669087 Feb 12 04:08 initrd-plymouth.img
-rw-r--r-- 1 root root    235041 Jan 15 14:34 symvers-4.14.165-131.185.amzn2.x86_64.gz
-rw------- 1 root root   2823838 Jan 15 14:34 System.map-4.14.165-131.185.amzn2.x86_64
-rwxr-xr-x 1 root root   5718992 Jan 15 14:34 vmlinuz-4.14.165-131.185.amzn2.x86_64

3.    如果 initramfs 和/或 vmlinuz 文件不存在,请尝试使用具有这两个文件的以前的内核启动实例。有关如何使用以前的内核启动实例的说明,请参阅当因为更新导致 Amazon EC2 实例无法成功重启时,如何恢复到已知的稳定内核?

4.    运行 unmount 命令以从您的救援实例中卸载辅助设备:

$ sudo umount /rescue

如果卸载操作不成功,您可能需要停止或重启救援实例,以实现干净卸载。

5.    将辅助卷 (/dev/sdf) 与救援实例分离,然后以 /dev/xvda(根卷)的形式将其附加到原始实例。

6.    启动实例,然后验证实例是否有响应。

有关解决内核崩溃错误的其他信息,请参阅在升级内核或尝试重启 EC2 Linux 实例后,我收到“内核崩溃”错误。如何修复此问题?

未能成功挂载或依赖项失败

如果您在系统日志中看到“未能成功挂载”或“依赖项失败”之类的错误,则 /etc/fstab 文件可能有不正确的挂载点条目。

1.    验证 /etc/fstab 中的挂载点条目正确。有关更正 /etc/fstab 文件条目的信息,请参阅我的 EC2 实例为什么没有启动,为什么进入紧急模式?自动挂载因 /etc/fstab 文件中的不正确条目而失败部分

2.    最佳实践是运行 fsck 或 xfs_repair 工具来更正文件系统错误。如果文件系统中有任何不一致性,fsck 或 xfs_repair 工具会更正它们。

注意:在运行 fsck 或 xfs_repair 工具之前创建文件系统的备份。

运行 unmount 命令以卸载您的挂载点,然后再运行 fsck 或 xfs_repair 工具:

$ sudo umount /rescue

根据您的文件系统运行 fsk 或 xfs_repair 工具。

对于 ext4 文件系统:

$ sudo fsck /dev/sdf
fsck from util-linux 2.30.2
e2fsck 1.42.9 (28-Dec-2013)
/dev/sdf: clean, 11/6553600 files,
459544/26214400 blocks

对于 XFS 文件系统:

$ sudo xfs_repair /dev/sdf
xfs_repair /dev/xvdf
Phase 1 - find and verify superblock...
Phase 2 - using internal log
        - zero log...
        - scan filesystem freespace and inode maps...
        - found root inode chunk
Phase 3 - for each AG...
        - scan and clear agi unlinked lists...
        - process known inodes and perform inode discovery...
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
        - process newly discovered inodes...
Phase 4 - check for duplicate blocks...
        - setting up duplicate extent list...
        - check for inodes claiming duplicate blocks...
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
Phase 5 - rebuild AG headers and trees...
        - reset superblock...
Phase 6 - check inode connectivity...
        - resetting contents of realtime bitmap and summary inodes
        - traversing filesystem ...
        - traversal finished ...
        - moving disconnected inodes to lost+found ...
Phase 7 - verify and correct link counts...
done

3.    将辅助卷 (/dev/sdf) 与救援实例分离,然后以 /dev/xvda(根卷)的形式将其附加到原始实例。

4.    启动实例,然后验证实例是否有响应。

调出接口 eth0:失败

如果您看到错误“调出接口 eth0:失败”,验证 ifcfg-eth0 文件拥有正确的网络条目。与主接口 eth0 对应的网络配置文件位于 /etc/sysconfig/network-scripts/ifcfg-eth0。如果您的主接口的设备名称不是 eth0,则实例的目录 /etc/sysconfig/network-scripts 中有以 ifcfg 开头的文件,后面还跟着设备名称。

1.    运行 cat 命令以查看主接口 eth0 的网络配置文件。

下面是位于 /etc/sysconfig/network-scripts/ifcfg-eth0 的网络配置文件的正确条目。

注意:用主接口的名称(如果不同)替换以下命令中的 eth0

$ sudo cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet
USERCTL=yes
PEERDNS=yes
DHCPV6C=yes
DHCPV6C_OPTIONS=-nw
PERSISTENT_DHCLIENT=yes
RES_OPTIONS="timeout:2 attempts:5"
DHCP_ARP_CHECK=no

2.    验证 ONBOOT 已设置为,如上述示例所示。如果 ONBOOT 未设置为是,则 eth0(或您的主网络接口)没有被配置为在启动时调出。

要更改 ONBOOT 值:

在编辑器中打开文件。下面的示例使用的是 vi 编辑器。

$ sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0

按下 I 以插入。

将光标滚动到 ONBOOT 条目,然后将值更改为

通过按下 :wq! 保存并退出文件。

3.    运行 unmount 命令以从您的救援实例中卸载辅助设备:

$ sudo umount /rescue

如果卸载操作不成功,您可能需要停止或重启救援实例,以实现干净卸载。

4.    将辅助卷 (/dev/sdf) 与救援实例分离,然后以 /dev/xvda(根卷)的形式将其附加到原始实例。

5.    启动实例,然后验证实例是否有响应