更新导致我的 EC2 实例无法重启时,如何恢复到已知的稳定内核?
更新导致我的 Amazon Elastic Compute Cloud (Amazon EC2) 实例无法重启。我想恢复到稳定的内核。
简短描述
如果您对 EC2 Linux 实例进行了内核更新,但内核现在已损坏,则该实例将无法重启。您也无法使用 SSH 连接到受影响的实例。
要解决此问题,请使用 EC2 Serial Console 访问您的根卷。或者,创建一个临时救援实例,然后将您的 Amazon Elastic Block Store (Amazon EBS) 卷重新挂载到该救援实例上。将您的 GNU GRUB 配置为使用以前的内核,然后重启实例。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
访问实例的根卷
要访问根卷,请使用 EC2 Serial Console 或救援实例。
使用 EC2 Serial Console
**先决条件:**您必须已经配置对 EC2 Serial Console 的访问权限。如果您的实例无法访问且您尚未配置访问权限,则必须使用救援实例来访问根卷。此外,请确保遵守 Serial Console 的先决条件。
如果您为 Linux 激活了 EC2 Serial Console,请将其用于基于 Nitro 的实例类型,以解决启动、网络配置和 SSH 配置问题。
无需有效的网络连接即可使用 Serial Console 连接到您的实例。
在使用 Serial Console 之前,请在 AWS 账户级别授予其访问权限。然后,创建 AWS Identity and Access Management (IAM) 策略,向您的 IAM 用户授予访问权限。每个使用 Serial Console 的实例都必须包含至少一个基于密码的用户。
使用救援实例
**重要事项:**请勿在实例存储支持的实例上执行此过程。恢复过程需要停止并启动您的实例,因此实例的数据将会丢失。
要使用救援实例访问根卷,请完成以下步骤:
-
从受影响的实例分离 Amazon EBS 根卷(/dev/xvda 或 /dev/sda1)。记下根卷的设备名称。
**注意:**为了帮助在后续步骤中识别 EBS 卷,请在分离该卷之前对其进行标记。根设备因亚马逊机器映像 (AMI) 而异。例如,Amazon Linux 2 (AL2) 和 Amazon Linux 2023 (AL2023) 使用 /dev/xvda。但是,Ubuntu 14、16、18、CentOS 7 和 Red Hat Enterprise Linux (RHEL) 7.5 使用 /dev/sda1。 -
在快照所在的同一可用区内启动 EC2 救援实例。
注意:检查您的实例产品代码。某些产品代码要求您在相同的操作系统 (OS) 上启动 EC2 实例。例如,如果受影响的 EC2 实例是付费 RHEL AMI,则必须启动具有相同产品代码的 AMI。如果您有一个 AL2 实例,则必须创建 AL2 救援实例以避免错误。 -
将卷作为辅助设备 (/dev/sdf) 附加到救援实例。
-
要查看可用的磁盘设备,请运行以下命令:
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:0 0 15G 0 disk └─xvdf1 202:1 0 15G 0 part**注意:**基于 Nitro 的实例会将 EBS 卷显示为 NVMe 块设备,其磁盘名称为 nvme[0-26]n1。基于 Nitro 的实例的输出示例:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT nvme0n1 259:0 0 8G 0 disk └─nvme0n1p1 259:1 0 8G 0 part / └─nvme0n1p128 259:2 0 1M 0 part nvme1n1 259:3 0 100G 0 disk └─nvme1n1p1 259:4 0 100G 0 part / -
要成为根用户,请运行以下命令:
sudo -i -
要将已挂载卷的根分区挂载到 /mnt,请运行以下命令:
mount -o nouuid /dev/xvdf1 /mnt**注意:**请将 /dev/xvdf1 替换为您的卷的根分区。如果您的配置中不存在 /mnt,请运行以下命令创建一个挂载目录,然后将根分区挂载到新目录:
mkdir /mnt mount -o nouuid /dev/xvdf1 /mnt**注意:**如果您在运行上述 mount 命令时收到错误,请改为运行以下命令:
mount /dev/xvdf1 /mnt然后,使用挂载目录访问受影响实例的数据。
-
要将救援实例的 /dev、/run、/proc 和 /sys 挂载到与已挂载卷相同的路径,请运行以下命令:
for m in dev proc run sys; do mount -o bind {,/mnt}/$m; done
- 如果您有单独的 /boot 分区,请将其挂载到 /mnt/boot。
- 要切换到挂载目录,请运行以下命令:
chroot /mnt
更新 GRUB 引导加载程序中的默认内核
您可以在列表中的位置 0 处找到损坏的内核,在位置 1 处找到最后一个稳定内核。要将损坏的内核替换为稳定的内核,请根据您的发行版完成以下步骤。
适用于 Red Hat 6 的 GRUB1(旧版 GRUB)
要将 /boot/grub/grub.conf 文件中的损坏内核替换为稳定内核,请运行以下命令:
sed -i '/^default/ s/0/1/' /boot/grub/grub.conf
适用于 Ubuntu 14 LTS、16.04 和 18.04 的 GRUB2
完成以下步骤:
-
要将 /etc/default/grub 文件中损坏的 GRUB_DEFAULT=0 默认菜单项替换为稳定的 GRUB_DEFAULT=saved 值,请运行以下命令:
sed -i 's/GRUB_DEFAULT=0/GRUB_DEFAULT=saved/g' /etc/default/grub -
要确保 GRUB 识别更改,请运行以下命令:
update-grub**注意:**当您重建 grub 配置文件时,可能会收到“device-mapper: reload ioctl on osprober-linux-xvdaX failed: Device or resource busy Command failed”错误。要解决此问题,请将 GRUB_DISABLE_OS_PROBER=true 参数添加到 /etc/default/grub 文件中,然后重新运行上述命令。
-
要确保 Amazon EC2 在下次重启时加载稳定的内核,请运行以下命令:
grub-set-default 1
适用于 RHEL 7 和 AL2 的 GRUB2
完成以下步骤:
-
要将 /etc/default/grub 文件中损坏的 GRUB_DEFAULT=0 默认菜单项替换为稳定的 GRUB_DEFAULT-saved 值,请运行以下命令:
sed -i 's/GRUB_DEFAULT=0/GRUB_DEFAULT=saved/g' /etc/default/grub -
要更新 GRUB 以重新生成 /boot/grub2/grub.cfg 文件,请运行以下命令:
grub2-mkconfig -o /boot/grub2/grub.cfg**注意:**当您重建 grub 配置文件时,可能会收到“device-mapper: reload ioctl on osprober-linux-xvdaX failed: Device or resource busy Command failed”错误。要解决此问题,请将 GRUB_DISABLE_OS_PROBER=true 参数添加到 /etc/default/grub 文件中,然后重新运行上述命令。
-
要确保 Amazon EC2 在下次重启时加载稳定的内核,请运行以下命令:
grub2-set-default 1
适用于 RHEL 8 和 CentOS 8 以及 AL2023 的 GRUB2
GRUB2 使用 blscfg 文件和 /boot/loader 中的条目进行启动配置,而不是之前的 grub.cfg 格式。最佳做法是使用 grubby 工具来管理 blscfg 文件并从 /boot/loader/entries/ 检索信息。如果 blscfg 文件丢失或损坏,则 grubby 不会显示任何结果。您必须重新生成文件才能恢复功能。
要更新 GRUB2 中的默认内核,请完成以下步骤:
-
要查看当前的默认内核,请运行以下命令:
grubby --default-kernel -
要查看所有可用内核及其索引,请运行以下命令:
grubby --info=ALL输出示例:
root@ip-172-31-29-221 /]# grubby --info=ALLindex=0 kernel="/boot/vmlinuz-4.18.0-305.el8.x86_64" args="ro console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto $tuned_params" root="UUID=d35fe619-1d06-4ace-9fe3-169baad3e421" initrd="/boot/initramfs-4.18.0-305.el8.x86_64.img $tuned_initrd" title="Red Hat Enterprise Linux (4.18.0-305.el8.x86_64) 8.4 (Ootpa)" id="0c75beb2b6ca4d78b335e92f0002b619-4.18.0-305.el8.x86_64" index=1 kernel="/boot/vmlinuz-0-rescue-0c75beb2b6ca4d78b335e92f0002b619" args="ro console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto" root="UUID=d35fe619-1d06-4ace-9fe3-169baad3e421" initrd="/boot/initramfs-0-rescue-0c75beb2b6ca4d78b335e92f0002b619.img" title="Red Hat Enterprise Linux (0-rescue-0c75beb2b6ca4d78b335e92f0002b619) 8.4 (Ootpa)" id="0c75beb2b6ca4d78b335e92f0002b619-0-rescue" index=2 kernel="/boot/vmlinuz-4.18.0-305.3.1.el8_4.x86_64" args="ro console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto $tuned_params" root="UUID=d35fe619-1d06-4ace-9fe3-169baad3e421" initrd="/boot/initramfs-4.18.0-305.3.1.el8_4.x86_64.img $tuned_initrd" title="Red Hat Enterprise Linux (4.18.0-305.3.1.el8_4.x86_64) 8.4 (Ootpa)" id="ec2fa869f66b627b3c98f33dfa6bc44d-4.18.0-305.3.1.el8_4.x86_64"记下您为实例设置的默认内核路径。在上述示例中,索引 2 处的内核路径为 /boot/vmlinuz- 0-4.18.0-80.4.2.el8_1.x86_64。
-
要更改实例的默认内核,请运行以下命令:
grubby --set-default=/boot/vmlinuz-4.18.0-305.3.1.el8_4.x86_64**注意:**请将 4.18.0-305.3.1.el8_4.x86_64 替换为您的内核版本号。
-
要验证您是否正确配置了默认内核,请运行以下命令:
grubby --default-kernel
重启实例
如果您使用了 EC2 Serial Console,则 Amazon EC2 现在会加载稳定的内核。您可以重启实例。
如果您使用救援实例访问根卷,请完成以下步骤:
-
要退出 chroot,然后卸载 /dev、/run、/proc 和 /sys,请运行以下命令:
exit umount /mnt/{dev,proc,run,sys,} -
Amazon EC2 现在将加载稳定的内核。您可以重启实例。

