内核是操作系统的核心,升级内核能带来新硬件支持、新特性、安全修复和性能改进。但内核升级也是运维里风险较高的操作之一:升级后可能因为驱动不兼容、initramfs 生成失败、或者引导配置写错,导致机器起不来。对远程服务器来说,一旦进不了系统,就是一场救援行动。
所以这篇文章的重点不只是"怎么升级",更是"怎么安全地升级、怎么在出问题时回滚"。我会先讲怎么查当前内核和可用内核,再分别给出 RHEL 系(yum/dnf)和 Debian 系(apt)的升级步骤,然后重点讲回滚——保留旧内核、修改 GRUB 默认启动项、以及救援模式的处理。文中涉及的引导和 grub 操作都有风险,务必在能物理接触或有云控制台 VNC 的前提下操作,并提前做快照。
需要明确的是,本文讨论的是"发行版仓库里的内核升级"(官方维护的稳定内核),不涉及自行编译内核,后者复杂度和风险都高得多,不适合作为常规运维手段。
一、先搞清楚当前内核和可用内核
动手之前先做信息收集,这是所有变更的第一步。
# 当前正在运行的内核版本
uname -r
# 例:5.15.0-91-generic (Ubuntu) 或 5.14.0-362.el9.x86_64 (RHEL9)
# 内核的完整信息
uname -a
# 已安装的(已在磁盘上、可启动的)内核列表
# RHEL / Rocky / AlmaLinux
rpm -qa kernel # 注意:只列 kernel,不含 kernel-core 等子包
rpm -qa 'kernel*' | sort
# Debian / Ubuntu
dpkg --list | grep linux-image
ls /boot/vmlinuz-* # 磁盘上实际存在的内核镜像
# 系统发行版信息(决定升级方式)
cat /etc/os-release
cat /etc/redhat-release 2>/dev/null
lsb_release -a 2>/dev/null
# 查看可升级到的新内核版本(先看,不装)
# RHEL / Rocky / Alma
sudo dnf check-update kernel
dnf list available kernel
# Debian / Ubuntu
sudo apt update
apt list --upgradable | grep linux-image
apt-cache policy linux-image-generic # Ubuntu 的通用内核元包
一个关键概念要区分清楚:内核包和内核元包。Ubuntu 上的 linux-image-generic 是一个"元包",它本身不含内核,而是依赖当前最新的具体内核版本。你升级这个元包,它会自动把新的 linux-image-x.y.z 拉进来。RHEL 系则通常是直接升级 kernel 包。理解这一点,才能明白为什么"升级内核"有时候只是升级了个元包。
二、RHEL / Rocky / AlmaLinux 内核升级步骤
RHEL 系的内核升级相对省心,因为它默认保留旧内核,绝不会自动删掉你正在跑的那个,这为回滚提供了天然保障。
# 1. 记录当前内核,回滚时要用
uname -r
# 2. 更新元数据并查看可升级内核
sudo dnf check-update kernel
dnf list available kernel
# 3. 升级内核(只升级内核包,最小影响面)
sudo dnf update kernel -y
# 如果想连同内核相关工具一起升级:
# sudo dnf update kernel kernel-core kernel-modules kernel-devel -y
# 4. 确认新内核已安装到磁盘
rpm -qa kernel | sort
ls -l /boot/vmlinuz-*
# 5. 查看 GRUB 里现在有哪些可启动项
sudo grubby --info=ALL | grep -E 'index|title|kernel'
# 或
sudo awk -F\' '$1=="menuentry " {print i++ " : " $2}' /boot/grub2/grub.cfg
# 6. 设置默认启动内核(按需,通常不需要手动设,默认会用最新)
sudo grubby --set-default /boot/vmlinuz-<新版本>
# 7. 重建 GRUB 配置(一般 dnf 更新时已自动完成,出问题时可手动)
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
# UEFI 系统路径可能是 /boot/efi/EFI//grub.cfg
# 8. 重启
sudo reboot
重启后再次 uname -r 确认新内核已生效。
回滚方法(RHEL 系):最干净的方式是在 GRUB 菜单里选择旧内核启动,然后把它设为默认。
# 列出所有内核入口,找到旧内核的路径
sudo grubby --info=ALL
# 把默认内核改回旧版本
sudo grubby --set-default /boot/vmlinuz-<旧版本>
# 重启验证
sudo reboot
如果新内核导致系统无法正常启动,就在开机时进入 GRUB 菜单(开机时按 Esc 或 Shift),选择旧内核条目启动,进去后再执行上面的 grubby --set-default。
三、Debian / Ubuntu 内核升级步骤
Debian 系的内核由 linux-image 包提供,升级方式和普通包一样,但要注意"元包"的机制。
# 1. 记录当前内核
uname -r
# 2. 更新索引
sudo apt update
# 3. 查看可升级的内核
apt list --upgradable 2>/dev/null | grep -i linux
# 4. 升级内核
# Ubuntu 上通常升级元包即可
sudo apt install --only-upgrade linux-image-generic linux-headers-generic -y
# 或者把系统整体升级(会一并升级内核)
# sudo apt upgrade -y
# 涉及依赖变化时用 dist-upgrade/full-upgrade
# sudo apt full-upgrade -y
# 5. 确认新内核已安装
dpkg --list | grep linux-image
ls -l /boot/vmlinuz-*
# 6. 重建 initramfs(一般装包时自动触发,必要时手动)
sudo update-initramfs -u -k all
# 7. 更新 GRUB
sudo update-grub
# 8. 重启
sudo reboot
Debian/Ubuntu 默认也会保留若干旧内核(由 linux-image 的自动清理机制控制),不会立刻删掉当前内核。
回滚方法(Debian 系):同样是在 GRUB 里选旧内核,或把旧内核包重新装回并设为默认。
# 临时从 GRUB 菜单选旧内核启动
# 进入系统后,确认旧内核包还在
dpkg --list | grep linux-image
# 如果旧内核还在,直接编辑 GRUB 默认项或把默认指向旧内核
sudo grep -n 'menuentry' /boot/grub/grub.cfg | head
# 方式一:改 /etc/default/grub 默认索引
sudo vi /etc/default/grub
# 设置 GRUB_DEFAULT="1>2" 这种索引写法,或直接用旧内核的完整 title
sudo update-grub
# 方式二:如果旧内核包被卸载了,重新安装指定版本
sudo apt install linux-image-<旧版本> linux-headers-<旧版本> -y
对 Ubuntu,还可以固定版本、阻止自动升级内核(在需要绝对稳定时):
# 禁止某个内核包被自动升级
sudo apt-mark hold linux-image-generic linux-headers-generic
# 解除
sudo apt-mark unhold linux-image-generic linux-headers-generic
# ---- RHEL 系锁定内核版本(防止误升级)----
# 用 versionlock 插件
sudo dnf install -y 'dnf-command(versionlock)'
sudo dnf versionlock add kernel kernel-core kernel-modules
sudo dnf versionlock list
# 解除
sudo dnf versionlock delete kernel
四、升级前后必须做的检查和防护
内核升级的风险不在于"装不上",而在于"装上后起不来"。下面这些防护措施能让你在出事时快速恢复。
| 阶段 | 必做动作 | 目的 |
|---|---|---|
| 升级前 | 云主机打快照 / 物理机做备份 | 最坏情况能整体回滚 |
| 升级前 | 确认有 VNC / IPMI / 物理接触手段 | 起不来时能进控制台 |
| 升级前 | 记录 uname -r 和旧内核名 |
回滚时明确目标 |
| 升级前 | 确认旧内核仍在磁盘上 | 保证有可回退的启动项 |
| 升级中 | 只在 dnf/apt 正常完成后再重启 |
避免半成品状态 |
| 升级后 | 不要立即删除旧内核 | 至少观察一段时间 |
| 升级后 | 检查关键服务和驱动 | 确认业务正常 |
特别提醒几类高风险场景:
- 自定义内核模块(DKMS):比如某些网卡、RAID、加密卡、虚拟化增强驱动。新内核如果没有对应模块,可能丢网卡导致失联。升级前务必确认这些模块能在新内核上重新编译(
dkms status)。 - 云主机的增强驱动:某些云厂商的虚拟化驱动依赖特定内核,升级前查厂商兼容列表。
- 开启了 Secure Boot:第三方或自编译模块可能因签名问题加载失败。
- 内核参数 / sysctl:新内核的默认参数可能变化,留意
dmesg有无异常。
升级后建议做的验证:
# 确认运行中的内核
uname -r
# 看内核启动日志有无报错
dmesg -T | less
journalctl -k -b | less # 本次启动的内核日志
# 确认关键模块加载了
lsmod | grep <你的模块>
modinfo <模块名>
# 确认网卡、磁盘都在
ip -br a
lsblk
# 确认服务正常
systemctl --failed
五、起不来了怎么办:救援思路
即使做了准备,也可能遇到 grub 加载失败、根文件系统挂载失败、内核 panic 等情况。此时的处理顺序是:
- 通过云控制台 VNC / IPMI / 本地显示器进入 GRUB 菜单,选旧内核启动。
- 能进系统后,把 GRUB 默认项改回旧内核并重启验证。
- 如果 GRUB 本身损坏,进救援模式(rescue)重建引导。
- 如果需要更彻底处理,用安装介质进入救援系统,挂载根分区后
chroot修复。
# 救援环境里常见操作(示意,路径按实际调整)
lsblk # 找到根分区,如 /dev/vda2
mkdir -p /mnt/sysroot
mount /dev/vda2 /mnt/sysroot
mount /dev/vda1 /mnt/sysroot/boot # 若 /boot 独立
# 绑定必要目录
for d in dev proc sys run; do mount --bind /$d /mnt/sysroot/$d; done
chroot /mnt/sysroot
# 在 chroot 内重建引导(RHEL 系示例)
grub2-mkconfig -o /boot/grub2/grub.cfg
grub2-install /dev/vda
exit
umount -R /mnt/sysroot
reboot
这些操作涉及引导和分区,属于高风险动作,一定要在确认磁盘设备名正确后再执行,误对数据盘执行 grub2-install 可能破坏数据。救援模式在第 010 篇还会更详细地展开。
六、升级策略与时机建议
内核升级不是越勤越好。对生产服务器,建议遵循三个原则。第一,优先跟进安全相关的内核补丁,这类更新风险低、收益明确,官方仓库的稳定内核通常会把安全修复合并进来。第二,不追逐最新的大版本内核,除非有明确的硬件支持、性能或功能需求(新网卡、新文件系统特性、容器相关能力等),否则没必要为了版本号好看去冒启动失败的风险。第三,把升级纳入固定变更窗口,避免在业务高峰期或无人值守时段进行,并确保升级后有人能第一时间验证业务是否正常。
判断"这次要不要升",可以先读内核更新的说明,看它修了哪些 bug、是否触及你正在用的驱动或子系统,再决定是立刻更新还是排期。对稳定性要求极高的机器,可以考虑用 kpatch/Livepatch 只打安全补丁而不重启内核;对要求接近零停机的业务,则应把内核升级和高可用架构结合起来——先摘掉流量、逐台升级、验证后再放回集群,这样即便某台起不来也不影响整体可用性。
另外,无论是否升级内核,都建议定期检查 dmesg 和 journalctl -k 里有没有持续的硬件报错,比如 ECC 内存错误、磁盘 IO timeout、网卡 link flap 反复振荡。这些信号往往比内核版本更能预示一次即将到来的故障。与其纠结要不要升内核,不如先确认当前没有正在发生的硬件异常,以及监控、备份、带外控制台这些保命手段是否都还在位。
常见问题
Q1:升级内核一定要重启吗?
是的。新内核只有重启后才会被加载生效。想在不重启的情况下打内核安全补丁,需要 Livepatch/kpatch 这类热补丁方案(通常是商业订阅功能)。
Q2:怎么保留旧内核以便回滚?
RHEL 系默认保留若干个旧内核;Debian/Ubuntu 默认也会保留。不要在升级后立刻用 dnf remove kernel 或 apt autoremove 清理内核,至少要等观察期结束。
Q3:删掉了正在运行的内核会怎样?
包管理器通常会阻止删除正在运行的内核版本,但不绝对。一旦误删导致当前内核文件缺失,重启后可能起不来,只能靠救援模式恢复。操作前务必确认要删的不是 uname -r 的版本。
Q4:云主机升级内核后连不上了怎么办?
立刻登录云厂商控制台的 VNC/串口控制台,在 GRUB 里选旧内核启动,然后恢复默认启动项。多数情况下几行 grubby 或 update-grub 就能解决。
Q5:Ubuntu 上为什么升级了 linux-image-generic 数量却没变?
因为它是元包,真正的工作是把它依赖的具体内核版本拉新。用 apt list --installed | grep linux-image 看具体版本包,或用 dpkg -l | grep linux-image 确认。
总结
- 升级前先记录
uname -r、列出已安装内核、确认拥有控制台访问手段,并做好快照或备份。 - RHEL/Rocky/Alma 用
dnf update kernel,Debian/Ubuntu 用apt install --only-upgrade linux-image-generic,两者都会默认保留旧内核供回滚。 - 回滚的核心是"通过 GRUB 选回旧内核并把它设为默认":RHEL 系用
grubby --set-default,Debian 系改/etc/default/grub后update-grub。 - 高风险点是自定义驱动和云厂商增强驱动,升级前务必用
dkms status等确认新内核可用,避免失联。 - 升级后不要急着删旧内核,先观察
dmesg、systemctl --failed和业务运行情况,确认稳定后再清理。
企业QQ咨询




