关于重建内核及EFI引导修复
在日常Linux运维工作中,时常遇到因为升级内核、磁盘故障、人为误操作造成的引导失效问题,这里单独开篇记录一下解决思路和步骤。
0.故障现象
当故障发生时,重现故障是首要也是最重要,其次就是日志文件,在故障页面通常可以捕获提取出关键信息,而日志文件则可以帮我们追溯故障出现前发生了什么。例如下图,在系统引导过程中出现,随后系统进入PXE网卡引导或EFI Shell,通过提示我们可以判断出这里是EFI分区中的引导文件丢失了,这种故障相对来说比较容易处理,我们只需要从同版本的系统中找到相同文件拷贝到EFI分区即可。
1.救援模式
救援模式是修复工作的基础,一切后续工作都要基于它展开,救援模式类似于Windows的PE系统,它是一个独立于磁盘中我们系统文件的简化版系统,把磁盘文件挂载在救援模式中,就可以借助它纯净的系统环境和依赖,进入到我们自己的系统里,然后对被损坏的文件或配置进行修复。
首先进入BMC带外管理系统,挂载远程镜像,然后重启引导镜像选择Troubleshooting-->Rescue a *** system
2.挂载sysroot
一般进入救援模式后会有三个选项,一是使用原系统的fstab自动挂载;二是以只读模式自动挂载;三是跳过挂载,进入救援Shell。
我个人习惯进入Shell后手动挂载,因为自动挂载速度慢,而且遇到非系统盘故障时,会循环挂载造成进程假死。所以这里选三。(也有部分系统不会提示选择模式,例如Kylin和UOS是直接进入bash命令行,这种就只能手动挂载了,同上。)
进入Shell后,使用lsblk分析系统分区情况,然后对系统盘和环境进行挂载。这里注意:如果是lvm格式,则需要执行vgchange -ay命令激活lvm分区,然后使用/dev/mapper映射名称挂载。
# 假设/dev/sda3为系统根目录分区
mount /dev/sda3 /mnt/sysimage
# 假设/dev/mapper/centos-root为lvm系统根分区
# mount /dev/dev/mapper/centos-root /mnt/sysimage
# 然后依次挂载/boor和/boot/efi目录(EFI分区一般是磁盘的第一个分区,如果是legacy引导,则没有EFI分区)
mount /dev/sda2 /mnt/sysimage/boot/
mount /dev/sda1 /mnt/sysimage/boot/efi/
# 挂载救援系统环境依赖,分别是设备文件目录、进程、运行时状态和系统设备\总线目录
mount -o bind /dev /mnt/sysimage/dev
mount -o bind /proc /mnt/sysimage/proc
mount -o bind /run /mnt/sysimage/run
mount -o bind /sys /mnt/sysimage/sys
# 完成上述工作后,执行chroot命令,我们熟悉的系统就短暂复活了!
chroot /mnt/sysimage
3.配置网络
大部分救援场景下是不需要连接网络的,但部分特殊情况例如需要安装三方依赖,或需要执行较长命令,而虚拟控制台无法复制粘贴,这时候我就会配置网络和ssh,然后通过ssh进入救援模式操作。
# 查看当前网卡信息
ip addr show
# 为指定网卡配置IP地址
ip addr add 192.168.1.123/24 dev enp0s3
# 配置默认路由
ip route add default via 192.168.1.1
# 启动SSH
/usr/sbin/sshd -D &
# 配置DNS
cat /etc/resolve.conf
nameserver 114.114.114.114
4.重建内核
# 通过chroot,uname -r确定恢复的内核版本
# 使用本地镜像文件重装内核
rpm -ivh /run/install/repo/Packages/kernel-3.10.0-1160.el7.x86_64.rpm --root=/mnt/sysimage/ --force
# 在线重装内核
yum reinstall "kernel-*-$(uname -r)"
5.引导修复
grub
grub2-install /dev/sda
grub2-mkconfig -o /boot/grub2/grub.cfg
# EFI引导
# grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
efibootmgr
# 列出所有EFI引导项
efibootmgr -v
# 删除启动项
efibootmgr -b 0001 -B
# 添加启动项
efibootmgr -c -d /dev/sda -p 1 -L "rocky" -l "\EFI\rocky\grubx64.efi"
# 修改EFI引导顺序
# BootOrder=0001,0002为引导顺序
efibootmgr -o 0003,0001,0002,0000