news 2026/10/18 3:06:06

CentOS 7离线手动升级内核全流程:从3.10到5.x的版本选型与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CentOS 7离线手动升级内核全流程:从3.10到5.x的版本选型与避坑指南

最近在帮一台生产服务器做内核升级,环境比较特殊:CentOS 7.9.2009,纯内网环境,不连外网,不能挂代理,没有本地 yum 源,一切都得手动来。折腾了一整天,踩了几个坑,最后顺利从 3.10 内核升到了 5.x。写这篇文章,把整个离线手动升级流程、版本选型思路、依赖处理方法和坑位排查经验完整记录下来,给同样被困在内网机房里的兄弟们一块垫脚石。

先交代一下背景,这台机器装的是 CentOS 7.9.2009,也就是 7 系列最后一个版本,内核停在 3.10.0-1160,这是 RHEL/CentOS 7 的老传统——内核版本极度保守。为什么非升不可?因为要在这台机器上跑一套新的容器调度平台,3.10 内核在 cgroup v2、网络命名空间、overlayfs 的稳定性上确实有点跟不上,加上新硬件的驱动也要新内核支持。所以升级内核不是赶时髦,而是业务驱动。

整个过程可以分成四大块:版本选型与准备工作、离线安装包的获取与校验、核心升级操作(含 GRUB2 调整)、升级后的验证与问题排查。下面按这个顺序展开。

1. 离线升级前的版本选型与准备工作

1.1 为什么要先想清楚升到哪个版本

很多人一上来就yum update,或者随便找一个内核 rpm 就往系统里装,这在离线环境下是很容易翻车的。离线环境跟在线环境最大的区别是:装错了或者装到一半缺依赖,你是没法临时再拉包的。每一步都得提前想清楚。

内核选型主要考虑三个因素:

第一,业务兼容性。如果你的机器是普通 web 服务器、数据库服务器,不需要太激进的内核特性,那选长期支持版本更稳。如果是要跑 Docker/K8s,或者上新的存储方案,那就得选相对新、功能全的内核分支。

第二,硬件驱动支持。新内核对新网卡、新 RAID 卡、NVMe 设备的支持肯定更好,但反过来,如果你的机器是老旧服务器,某些厂商的闭源驱动跟不上新内核版本,升完内核网卡反而掉线。这个一定要先在测试环境验证。

第三,虚拟化环境特殊要求。比如跑在云平台、虚拟化平台上的机器,升级内核后必须确认虚拟化相关驱动(比如 virtio 系列)正常加载,不然重启直接失联。

以我这次为例,业务上需要稳定优先,同时又要支持容器特性,所以我选了长期支持版本系列(对应 ELRepo 的 kernel-lt),而不是最新主线版本(kernel-ml)。主线和 LT 差异很大:主线版本更新、功能激进,但生命周期短,可能几周就更新一个版本;LT 版本更稳、维护周期长,适合生产环境长期跑。

注意:CentOS 7 默认仓库里的内核是不升级的,需要用第三方仓库(如 ELRepo)提供的内核包。离线环境下就先把 rpm 包准备好再说。

1.2 查当前内核版本和系统发行版信息

在动手之前,先把底细摸清楚,执行下面几条命令:

cat /etc/centos-release uname -r uname -m

我的环境输出是:

CentOS Linux release 7.9.2009 (Core) 3.10.0-1160.el7.x86_64 x86_64

这三个信息缺一不可:系统大版本决定 rpm 包要选 el7 的;当前内核版本用于升级前后对比;架构确定你下载 x86_64 还是 aarch64 的包。

另外建议同步检查一下/boot分区空间:

df -h /boot

内核 rpm 安装时会往 /boot 写入 vmlinuz、initramfs 等文件,每个内核大约占 30~60MB。如果 /boot 空间太小,多个内核并存会直接撑爆分区,这也是老 CentOS 7 机器很容易踩的雷。

1.3 确认升级目标与回滚策略

在离线环境下建议采用“保留旧内核、新增新内核”的策略,不要先卸载旧内核再装新的。这样就算新内核启动失败,重启后还能从 GRUB 菜单里选回旧内核,安全兜底。

我在实际操作中对 /boot 里的内核文件做了一个完整的备份清单:

ls -l /boot/vmlinuz-* ls -l /boot/initramfs-*

并确认当前使用的内核模块目录存在:

ls /lib/modules/3.10.0-1160.el7.x86_64/

这一步看似多余,但在后面删旧内核时非常有用,至少知道原始环境长什么样。

2. 离线安装包的获取与完整性校验

2.1 在联网机器上下载全部内核 rpm 包

离线环境不是没有电脑,而是服务器不能联网。我们可以找一台能联网的同架构机器(比如办公电脑、跳板机)先把调和好依赖的内核 rpm 包全部下载下来,再拷贝到内网服务器上安装。

这里推荐用 yumdownloader 的--resolve参数,它会把指定包及其所有依赖一次性拉下来。命令如下(在联网机器上执行):

# 先安装 yum-utils yum install -y yum-utils # 启用 ELRepo 源 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm # 下载 kernel-lt 及其所有依赖到指定目录 mkdir -p /data/kernel-rpms cd /data/kernel-rpms yumdownloader --resolve kernel-lt kernel-lt-devel kernel-lt-headers

这里有个细节:kernel-lt-devel是内核头文件和开发包,如果你只是单纯跑步业务,其实可以不装;但后面如果要编译第三方内核模块(比如某个网卡驱动、安全 agent 的 kernel module),就必须装。我这次装了,防止后续临时要用却没有包。

如果你选择主线版本,把包名换成 kernel-ml 就行:

yumdownloader --resolve kernel-ml kernel-ml-devel kernel-ml-headers

下载完成后,检查目录内容:

ls -lh /data/kernel-rpms/

正常会看到类似这样的文件:

kernel-lt-5.4.275-1.el7.elrepo.x86_64.rpm kernel-lt-devel-5.4.275-1.el7.elrepo.x86_64.rpm kernel-lt-headers-5.4.275-1.el7.elrepo.x86_64.rpm

如果某些依赖需要单独补(比如 abrt、dracut 版本太老),yumdownloader 也会一并拉下来,这一步不要跳过--resolve。

2.2 校验包完整性与签名

把 rpm 包传到内网机器之前,建议至少做一次完整性校验。在联网机器上还没装包之前,可以用 rpm 命令检查签名:

cd /data/kernel-rpms rpm -K *.rpm

理论上每个包会显示:

digests signatures OK

如果以前导入过 ELRepo 的公钥,签名校验会直接通过;如果显示MISSING KEY,那只是没导入公钥,不影响包本身完整性,但建议先在联网机器上导入公钥再校验,避免内网机器上缺少信任链导致后续安装异常。

对于纯离线环境,内网机器上一般也不会有 ELRepo 公钥,那安装时加上--nogpgcheck即可:

rpm -Uvh --nogpgcheck kernel-lt-*.rpm

这个参数在离线装内核时非常常用,内部系统不要求强制验签的情况下基本都会用到。但要注意:如果你们内部对 rpm 审计有强制要求,还是要提前把 GPG 公钥文件一并拷贝进去统一管理,不能直接跳过。

2.3 上传到内网机器

这一步用 U 盘、内网共享目录或者直接scp都行,但要注意路径尽量简单。我放到/root/kernel-upgrade/下:

scp /data/kernel-rpms/*.rpm root@内网机器IP:/root/kernel-upgrade/

到内网机器上确认文件完整:

cd /root/kernel-upgrade/ ls -lh *.rpm

对比一下文件大小,跟联网机器上一致就说明传输没丢数据。有条件的话再跑一遍 md5sum 比对,更稳妥。

3. 离线安装内核与 GRUB2 调整实操

3.1 安装前的最后检查

内网机器上,先做一次试安装检测依赖,这一步非常重要。rpm 提供了--test参数,可以预演安装过程而不真正写入系统:

cd /root/kernel-upgrade/ rpm -Uvh --test --nogpgcheck kernel-lt-*.rpm

如果输出类似:

error: Failed dependencies: xxx is needed by kernel-lt-5.4.275-1.el7.x86_64

那就说明还有依赖没补齐。这时候去联网机器上把缺失的依赖包也拉下来,再传上来。这一步在离线环境下务必执行,不要为了省事跳过,不然装到一半报错再补包,麻烦的是自己。

正常情况--test会安静通过,没有输出或者只显示准备信息。这时候才能开始正式安装。

3.2 执行内核安装

正式安装命令:

cd /root/kernel-upgrade/ rpm -Uvh --nogpgcheck kernel-lt-*.rpm

这里用-U(upgrade)而不是-i(install),因为在有旧内核的情况下,-U会保留旧内核的同时安装新内核,并自动生成新内核的 initramfs。观察输出,关键部分是:

Installing: kernel-lt-5.4.275-1.el7.x86_64 ... Generating grub configuration file ... ... Installing: kernel-lt-devel-5.4.275-1.el7.x86_64 kernel-lt-headers-5.4.275-1.el7.x86_64

看到 “Generating grub configuration file” 说明安装脚本已经自动执行了 grub2-mkconfig。但装完不要高兴太早,还要手动确认默认引导项是否指向了新内核。

安装完成后验证 /boot 目录:

ls -l /boot/vmlinuz-*

正常情况下会同时存在老内核(3.10.0-1160)和新内核(5.4.275),两个内核文件都在,说明回滚能力还保留着。

3.3 调整 GRUB2 默认启动项

CentOS 7 使用 GRUB2 引导,默认启动项由/boot/grub2/grubenv文件控制。新内核安装后,默认项未必是新内核,必须手动检查设置。

查看当前菜单中所有内核条目:

grep menuentry /boot/grub2/grub.cfg

输出示例:

menuentry 'CentOS Linux (5.4.275-1.el7.x86_64) 7 (Core)' --class centos ... menuentry 'CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core)' --class centos ... menuentry 'CentOS Linux (0-rescue-...) 7 (Core)' --class centos ...

新内核的菜单条目默认会排在第一位(因为 rpm 安装脚本生成 grub.cfg 时把最新的放最前),但为了保险,还是手动执行:

grub2-set-default 0 grub2-mkconfig -o /boot/grub2/grub.cfg

grub2-set-default 0的意思是设置默认启动第一条菜单项。如果新内核不在第一位,可以先记录菜单条目的编号(从0开始数),再grub2-set-default 对应编号。

随后检查 grubenv:

cat /boot/grub2/grubenv

看到saved_entry=0就已经生效了。这里补充一句:CentOS 7 的 grub2-mkconfig 输出信息里可能会有一行警告,比如 “GRUB_DISABLE_OS_PROBER is not set”,只要你不是多系统共存,一般不影响。

3.4 重启进入新内核

重启前再做一次必要的落盘检查:

sync

然后执行:

reboot

重启后第一时间确认内核版本:

uname -r

如果输出是新内核版本号(如 5.4.275-1.el7.x86_64),说明升级成功。如果输出还是旧内核,不要慌,很可能是没重启成功或者 GRUB 默认项没生效,再reboot一次,或者检查 grubenv。

另外强烈建议重启后立刻检查负载和 dmesg:

uptime dmesg | grep -i error

至少观察几分钟,确认网络、磁盘、容器服务都恢复正常再继续下一步。

4. 升级后的清理、验证与常见问题速查

4.1 确认新内核模块加载并清理旧内核

进入新内核后,执行下面几条验证命令:

# 查看当前加载的内核模块数量 lsmod | wc -l # 检查网络模块是否能正常加载 ip a # 检查容器相关功能 docker info 2>/dev/null || systemctl status docker 2>/dev/null

如果网络不通,大概率是新内核缺少对应网卡驱动,常见场景是某些老服务器的闭源网卡驱动没有适配新内核。这时候先别急着清理旧内核,用旧内核回滚再研究模块。

确认一切正常后,可以用 package-cleanup(yum-utils 提供)清理旧内核:

package-cleanup --oldkernels --count=2

这条命令会保留最近 2 个内核,删除更旧的。我建议保留 2 个(新内核 + 上一个旧内核),不要直接--count=1,给自己留一条退路。

如果没有 yum-utils,也可以手动删除:

rpm -e kernel-3.10.0-1160.el7.x86_64

手动删除要注意:必须连带删掉/lib/modules/3.10.0-1160.el7.x86_64/和 /boot 下对应的 vmlinuz、initramfs,并且删除后重新生成 grub.cfg:

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

4.2 常见问题排查实录

按真实踩坑概率排序,整理几个高频问题:

问题一:重启后仍进入旧内核

这个我遇到过,原因是 grub2-set-default 生效了,但 BIOS 里默认从另一块硬盘启动,或者 GRUB 菜单里 rescue 条目排在前面。处理办法:重启时进入 GRUB 菜单,手动选择新内核条目;进入系统后重新grub2-set-default并确认 grubenv。

问题二:系统启动进入 dracut 紧急模式

典型表现是开机卡住,出现Entering emergency mode的提示。多数情况是 initramfs 没有正确包含根文件系统所在磁盘的驱动。处理办法:在 dracut 模式下用旧内核启动,然后重新生成 initramfs:

dracut -f /boot/initramfs-5.4.275-1.el7.x86_64.img 5.4.275-1.el7.x86_64

-f是强制覆盖。但频繁手动重建 initramfs 不是好习惯,出现这种情况一般是根分区用的文件系统模块没进 initramfs,更稳妥的方式是在旧内核启动后检查/etc/dracut.conf.d/里有没有特殊配置,或者确认 grub 的root=内核参数是否正确。

问题三:升级后磁盘挂载异常

CentOS 7 默认文件系统是 xfs。旧内核 3.10 对应的 xfs 特性较老,新内核的 xfs 直接挂载没问题,反过来就不行——如果升完级再降回去,新内核写入的数据旧内核可能读不了。所以升级后如果发现挂载报错,先dmesg | grep xfs,再确认日志里的具体报错,一般进入旧内核能解决。总之,新内核稳定运行几天后,就不要轻易回滚到旧内核了,xfs 文件系统对新内核生成的元数据可能无法在旧内核下兼容。

问题四:docker/容器服务启动失败

由于 cgroup v2 和 iptables 规则的变化,docker 在老内核配置下能跑,切到新内核可能遇到iptables -t nat报错或者 cgroup 挂载失败。这个问题我在测试环境也遇到过,一般升级 docker 或者重启 docker 服务能让它重新适配新内核。离线环境下 docker 升级可能比较麻烦,升级内核前先确认 docker 版本是否兼容目标内核。

问题五:第三方内核模块缺失

最常见的就是杀毒 agent、监控 agent、某些虚拟化平台的 guest tools。这些工具在旧内核下编译的内核模块,到新内核里 100% 不能加载。解决办法是先去厂商官网/内网补丁包下载区找适配新内核的版本,装好 agent 再升级内核。顺序千万不能反,不然新内核启动后 agent 直接拉不起来,监控和安全体系同时失效。

4.3 离线环境特有的坑位总结

离线环境最大的特点是:出了问题,你不可能临时拉包、临时看文档。所以整个升级过程里,我反复强调的其实就两件事:备份和保留旧内核。

我这次的实际操作顺序是:

  • 在联网机器下载所有 rpm 包
  • 上传到内网服务器后,先rpm --test验证依赖
  • 安装新内核,不删除旧的
  • 修改 GRUB2 默认启动项
  • 验证新内核稳定性
  • 等稳定运行一周后,清理旧内核

整个过程最花时间的不是装内核本身,而是依赖匹配和包传输。rpm 安装两分钟搞定,传包可能花半小时,找依赖包又来回折腾了一个多小时。如果你们内网有 Nginx 代理或者内部 yum 仓库,可以把 rpms 放进本地仓库,下次装其他机器就快多了。

最后分享一个小技巧:离线环境升级内核前,可以先把当前内核的 modules 目录完整打包备份:

tar czf /root/modules-backup-3.10.tar.gz /lib/modules/3.10.0-1160.el7.x86_64/

万一新内核装坏了、旧内核也出了问题,这套 modules 是你最完整的底牌。我个人建议每个运维兄弟在动手前都做一次这个备份,成本极低,价值无限。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 3:02:46

SINR自适应波束形成器MVDR Matlab仿真:强干扰下阵列信号处理

简介:这是一份用于无线通信与雷达信号处理的自适应波束形成器MATLAB实现,核心算法基于最大信干噪比(SINR)准则,解决阵列天线在强干扰与噪声环境下期望信号接收质量不佳的问题,适合通信工程、信号处理方向的…

作者头像 李华
网站建设 2026/10/18 3:01:37

分光计实验仿真软件:从粗调到最小偏向角测量的完整操作指南

简介:这份资源是面向高校物理实验学习者与教学者的分光计仿真实验软件,适合光学课程配套练习、远程教学及实验预习复习。软件以虚拟环境还原分光计操作,涵盖光源设置与调节、光栅或棱镜的选择使用、波长测量、误差分析及数据处理与报告撰写等…

作者头像 李华
网站建设 2026/10/18 3:01:01

消息队列多线程消费如何精准保序?四套生产级方案详解

1. 这不是“能不能”而是“在哪一层保证”的问题你看到这个标题的第一反应,很可能是:“Kafka 不是天生乱序的吗?RocketMQ 不是靠队列锁保序的吗?多线程一上,顺序不就崩了?”——这恰恰说明你已经踩进了绝大…

作者头像 李华
网站建设 2026/10/18 2:59:45

SpringBoot+Thymeleaf后台管理CRUD实战:从数据流转到表单校验

1. 动手前先想清楚的事:这套方案到底解决什么问题“增删改查”这四个字,在简历上出现频率很高,但真正能用SpringBootThymeleaf把它做成一个可交付、可扩展、页面好看的后台管理模块,很多人其实是卡住的。问题往往不在“会不会写代…

作者头像 李华
网站建设 2026/10/18 2:58:31

多模态集成实战:从视觉编码器到指令微调

多模态集成这件事,我在实际项目里折腾了小半年,踩过不少坑,也总结出一些能直接落地的经验。所谓"将多模态数据集成到大型语言模型中",说白了就是让一个原本只会读文字的模型,能同时看懂图片、听清音频、理解…

作者头像 李华