在CentOS系统中,如果你升级了内核后发现系统不稳定或者某些驱动不兼容,最直接有效的回滚方式就是通过GRUB2引导加载器设置默认启动的内核版本。具体操作就是修改/etc/default/grub配置文件中的GRUB_DEFAULT参数,指向你想要启动的旧内核条目,然后重新生成grub.cfg配置文件并重启系统即可。整个过程不需要复杂的命令,几分钟就能完成,下面我会把每一步都讲透。

很多运维人员在做内核升级后遇到问题,第一反应是去卸载新内核或者重新编译,其实完全没必要。GRUB2本身就支持多内核共存和选择启动,你只需要告诉它"下次开机用哪个内核"就行。这篇文章会从查看当前内核、修改默认启动项、生成配置、验证回滚效果等完整流程来讲,同时也会覆盖一些特殊场景和常见坑。

一、先搞清楚你当前有哪些内核可以选

在动手修改之前,你必须先知道系统里装了哪些内核版本。CentOS 7和CentOS 8/Stream的内核管理方式略有不同,但查看方法都很简单。

先查看当前正在运行的内核版本:

uname -r

然后查看系统中安装了哪些内核包:

rpm -qa | grep kernel

或者更直观地看boot目录下有哪些内核镜像:

ls /boot/vmlinuz-*

你会看到类似这样的输出:

/boot/vmlinuz-3.10.0-1160.el7.x86_64
/boot/vmlinuz-3.10.0-1127.el7.x86_64
/boot/vmlinuz-5.4.0-42-generic

每一个vmlinuz文件对应一个内核版本。记住你要回滚到的那个版本号,后面要用到。如果你用的是CentOS 8或Stream,内核包名可能带有kernel-core字样,查看方式一样。

二、查看GRUB2菜单里的启动项顺序

GRUB2的启动菜单里会列出所有可用的内核,它们的排列顺序决定了默认启动哪个。你需要先看一下当前的菜单结构。

查看GRUB配置文件:

cat /boot/grub2/grub.cfg

或者在CentOS 7上:

cat /boot/grub2/grub.cfg | grep menuentry

你会看到类似这样的条目:

menuentry 'CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1160.el7.x86_64-advanced-xxx' {
    ...
}
menuentry 'CentOS Linux (3.10.0-1127.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1127.el7.x86_64-advanced-xxx' {
    ...
}

注意,这些menuentry是按顺序排列的,第一个就是默认启动项。你需要确认你要回滚的内核在菜单里的位置,是第0项、第1项还是第几项。

三、修改GRUB_DEFAULT参数设置默认内核

这是核心步骤。打开GRUB的默认配置文件:

vi /etc/default/grub

找到GRUB_DEFAULT这一行。它有几种设置方式,我逐一说明:

第一种:按索引号设置。比如你要启动菜单里的第二个内核(索引从0开始),就写:

GRUB_DEFAULT=1

第二种:按内核名称精确指定。这种方式最稳妥,不怕菜单顺序变化:

GRUB_DEFAULT="CentOS Linux (3.10.0-1127.el7.x86_64) 7 (Core)"

注意,这里的名称必须和grub.cfg里menuentry后面的标题完全一致,包括空格和括号。你可以直接从grub.cfg里复制过来。

第三种:设置为saved,配合GRUB_SAVEDEFAULT使用,这样可以在启动时临时选择一次,之后就固定用那个内核。适合你想临时测试某个内核的场景:

GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true

另外还有一个常用参数GRUB_TIMEOUT,控制菜单等待时间,单位是秒。如果你设成0或者-1,系统会直接启动默认项不显示菜单。生产环境建议设成5到10秒,方便紧急情况下手动选择:

GRUB_TIMEOUT=5

修改完成后保存退出。

四、重新生成GRUB2配置文件

改了/etc/default/grub之后,必须重新生成grub.cfg才能生效。不同系统生成方式不同。

CentOS 7(BIOS引导):

grub2-mkconfig -o /boot/grub2/grub.cfg

CentOS 7(UEFI引导):

grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

CentOS 8 / Stream(BIOS):

grub2-mkconfig -o /boot/grub2/grub.cfg

CentOS 8 / Stream(UEFI):

grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

执行完后会看到输出类似"done"的提示,表示生成成功。你可以再cat一下grub.cfg确认你设置的内核确实排到了第一位。

五、重启验证回滚效果

配置好之后直接重启:

reboot

系统重启后,登录进去第一件事就是确认内核版本:

uname -r

如果显示的是你指定的旧内核版本,说明回滚成功。如果没有自动切换,检查一下GRUB_DEFAULT的写法是否正确,特别是引号和空格有没有问题。

还有一种情况需要注意:如果你的系统用的是UEFI引导,而且有多个引导条目(比如同时装了CentOS和其他系统),你可能需要用efibootmgr来确认引导顺序:

efibootmgr -v

确保CentOS的引导项是BootOrder里的第一项。

六、如果新内核导致系统无法启动怎么办

有些时候内核升级后直接进不了系统,连GRUB菜单都看不到。这时候你需要用救援模式或者Live CD来修复。

方法一:开机时按Esc或Shift键(UEFI下可能是F12或F2)进入GRUB菜单,手动选择旧内核启动。进去之后再按上面的步骤修改默认配置。

方法二:用CentOS安装盘进入Rescue模式,挂载原系统的根分区,然后chroot进去修改:

mount /dev/sda2 /mnt
chroot /mnt
vi /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
exit
umount /mnt
reboot

方法三:如果是UEFI系统且引导项丢失,可以在救援模式下重新注册引导:

grub2-install /dev/sda
grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

这三种方法基本能覆盖所有"内核升级后开不了机"的场景。

七、关于永久删除问题内核的补充建议

回滚成功后,你可能想把有问题的新内核删掉,避免以后误选。CentOS 7下可以用yum:

yum remove kernel-xxx

但更安全的做法是先确认旧内核工作正常,再删除新内核。删除后记得重新生成grub配置:

grub2-mkconfig -o /boot/grub2/grub.cfg

CentOS 8/Stream上用dnf:

dnf remove kernel-xxx

注意,千万不要把所有内核都删了,至少保留两个以上,防止万一某个内核也有问题时没有备用选项。

八、一些容易踩的坑和实战经验

第一,GRUB_DEFAULT设置索引号时,如果你的grub.cfg里有submenu(子菜单),索引号的计算会变复杂,建议直接用内核名称指定,最不容易出错。

第二,CentOS 8和Stream默认可能没有安装grub2-mkconfig命令,需要先装:

dnf install grub2-tools grub2-tools-efi

第三,如果你的系统是用云主机,有些云平台的镜像会自定义GRUB行为,修改后可能被覆盖。这种情况建议联系云平台技术支持或者在镜像层面做配置。

第四,做内核操作之前,强烈建议先备份grub配置:

cp /etc/default/grub /etc/default/grub.bak
cp /boot/grub2/grub.cfg /boot/grub2/grub.cfg.bak

出了问题随时能恢复。这是运维的基本素养,不管多熟练都要养成习惯。

第五,如果你经常需要在内核之间切换测试,可以考虑用grubby工具,它比手动改配置文件更方便:

grubby --set-default /boot/vmlinuz-3.10.0-1127.el7.x86_64

这个命令会自动更新grub配置,不需要你手动跑mkconfig。CentOS 7和8都支持,是生产环境里很实用的小工具。

九、总结

CentOS通过GRUB2回滚内核版本,本质上就是三步:确认目标内核、修改GRUB_DEFAULT、重新生成配置。整个过程风险很低,只要你不乱删内核文件、不改错引导项,基本不会出问题。关键是要熟悉自己系统的引导方式(BIOS还是UEFI),以及grub.cfg的结构。掌握这些,以后不管内核怎么升级,你都能快速回退到稳定状态。运维的核心能力之一就是"能升级也能回滚",别只会往前冲,留好退路才是真正的专业。