资讯动态

内网离线升级Linux内核完整指南:依赖处理、引导配置与安全回滚

发布时间:2026/10/14 23:29:13 来源:尧图企业网站定制
1. 为什么内网环境下的内核升级值得单独拿出来讲很多人第一次遇到离线升级内核这个需求都是在一种比较被动的场景里机房里的服务器跑着某个关键业务突然发现当前内核版本对某款新上的硬件支持不全或者某个安全补丁必须通过升级内核才能覆盖而这台机器又完全没有外网出口。这时候你手里只有一台能上网的笔记本、一个U盘以及一台等着你把它救活的生产机。这件事听起来简单——不就是下载几个包然后装上去吗但真正动过手的人都知道离线升级内核的坑远比在线升级密集得多。在线环境下yum update kernel或者apt install linux-image-xxx一条命令就能搞定的事一旦断了网依赖关系、包版本匹配、引导配置、固件缺失、回滚预案每一个环节都可能让你在机房里耗到凌晨。我写这篇东西的目的很明确把离线升级内核这件事从碰运气变成有章法。不管你是运维、嵌入式开发还是单纯维护几台内网服务器的技术负责人只要你的机器不能直接连外网这套思路都能直接拿去用。文章会覆盖从版本确认、依赖梳理、包下载、介质制作到实际安装、引导修复、失败回滚的完整链路并且重点讲清楚每一步为什么这么做而不是只丢给你一堆命令。需要先说明一点内核升级本身是一个对系统影响极大的操作它直接关系到机器能不能正常启动。所以下面所有内容我都会把可回滚作为一条贯穿始终的底线来对待。你可以在心里先记住一句话——升级内核的第一原则不是升成功而是升失败之后还能退回来。2. 动手之前必须锁定的几个关键信息2.1 先搞清楚当前系统到底跑的是什么离线升级最忌讳的就是我以为。你以为机器是 CentOS 7结果人家是 Rocky Linux你以为内核是 3.10结果uname -r出来一个带自定义后缀的版本。所以第一步永远是确认现状而且要确认得足够细。uname -r cat /etc/os-release uname -m这三条命令分别告诉你当前运行的内核版本、发行版信息、CPU 架构。为什么要三个都看因为内核包是强绑定发行版和架构的。同样是 5.4 内核给 Ubuntu 用的.deb和给 CentOS 用的.rpm完全不是一回事同样是 x86_64某些发行版还会细分x86_64和amd64的命名差异。除了这三条我建议再补两条ls /boot rpm -qa | grep kernel # RedHat 系 dpkg -l | grep linux-image # Debian 系ls /boot能让你看到当前/boot分区里已经有哪些内核和 initramfs 文件这直接决定了你后面有没有空间放新内核。我见过/boot只给了 200MB 结果新内核装到一半空间不足的案例最后引导直接损坏。rpm -qa或dpkg -l则是为了搞清楚当前装了哪些内核相关的包避免升级后出现新旧包混装的混乱局面。2.2 目标内核版本怎么选不是越新越好确定要升到哪个版本是离线升级里最需要克制的一步。在线环境下你可以随便试反正大不了重装离线环境下你每换一个版本就意味着重新走一遍下载和介质制作流程。我的经验是遵循够用且稳定原则具体分三种情况为了硬件兼容比如新上的网卡、RAID 卡在旧内核里识别不了那就去查这款硬件的驱动是从哪个内核版本开始合入主线的选那个版本或者稍高一点的稳定版即可没必要追最新。为了安全补丁这种情况优先选发行版官方仓库里为你的系统版本提供的最新内核因为发行版会把安全补丁回移到他们维护的内核版本上兼容性最有保障。为了新特性比如需要某个 cgroup v2 的新行为或者某个文件系统的新功能那就得看该特性具体在哪个版本引入同样选引入版本附近的稳定版。这里有个很多人忽略的点发行版官方维护的内核和 kernel.org 上的主线内核是两条不同的路线。前者经过发行版大量回移和测试和你的系统其他组件比如 glibc、systemd、驱动模块配合得最好后者虽然版本号新但可能和你的用户态工具链存在兼容问题。离线环境下我强烈建议优先走发行版官方路线除非你有明确的理由必须上主线。2.3 依赖关系是离线升级最大的拦路虎在线安装时包管理器会自动帮你解决依赖。离线时这个自动没了你得自己把依赖树理清楚。内核包的依赖通常包括kernel-firmware或linux-firmware各种硬件的固件缺了它某些设备可能起不来。dracut或initramfs-tools用来生成 initramfs 的工具版本太旧可能生成不出新内核需要的镜像。grub2或grub引导程序新内核可能需要更新版的 grub 才能正确引导。kmod、binutils、gcc等某些情况下编译内核模块需要。在 RedHat 系上你可以用yum deplist kernel查看依赖需要能连仓库的机器在 Debian 系上apt-cache depends linux-image-xxx是同样的作用。关键技巧是在一台和离线机系统版本完全一致的联网机器上做依赖分析把依赖树完整导出来然后一次性把所有需要的包都下载齐。千万不要在离线机上装一个下一个那样一旦中途缺包系统可能处于半升级状态非常危险。3. 在一台联网机器上把包准备齐全3.1 找一台系统版本完全一致的联网机这一步是整个离线升级成败的关键。所谓完全一致指的是发行版、大版本号、架构三者都相同。比如离线机是 CentOS 7.9 x86_64那联网机最好也是 CentOS 7.9 x86_64。小版本号7.9 里的 .9如果能一致更好不一致通常问题不大但大版本必须一致。为什么这么强调因为不同大版本之间的包依赖和库版本差异很大你在 CentOS 8 上下载的包拿到 CentOS 7 上很可能因为 glibc 版本不匹配而装不上。我吃过这个亏当时图省事用了一台 CentOS 8 的机器下载结果一堆包依赖libc.so.6(GLIBC_2.28)而目标机只有 GLIBC_2.17全部报错。如果实在找不到完全一致的机器退而求其次的办法是用容器。比如用docker run -it centos:7.9.2009 bash起一个和目标机同版本的容器在容器里做下载。这个方法的优点是环境干净、可复现缺点是要注意容器里的仓库配置和真实机器可能略有差异。3.2 用 downloadonly 把依赖树一次性拉全RedHat 系最省事的做法是用yum的downloadonly插件yum install -y yum-plugin-downloadonly yum install --downloadonly --downloaddir/tmp/kernel-pkgs kernel kernel-devel kernel-headers如果你还想把依赖也一起下下来可以配合--resolve新版 dnf 支持dnf download --resolve --alldeps --destdir/tmp/kernel-pkgs kernelDebian 系则用apt-get的-d参数配合--print-urisapt-get install -d --reinstall linux-image-5.4.0-xx-generic # 包会下载到 /var/cache/apt/archives/或者更彻底一点用apt-get download配合apt-rdepends把整棵依赖树都拉下来apt-rdepends linux-image-5.4.0-xx-generic | grep -v ^ | sort -u deps.txt这里有个实操心得下载完之后一定要核对包的数量和完整性。我习惯用ls -l看文件大小再用md5sum或sha256sum生成校验清单。因为介质在拷贝过程中损坏是很常见的事尤其是用 U 盘反复插拔的时候。到了离线机上先校验一遍能省掉很多装到一半报错的麻烦。3.3 别忘了固件和引导相关的包很多人下载内核时只盯着kernel这一个包结果装完发现网卡不工作、或者引导菜单里根本没有新内核选项。原因就是漏了固件包和引导工具包。对于 RedHat 系建议至少下这几个kernel内核本体kernel-devel、kernel-headers如果你后续要编译驱动linux-firmware固件grub2、grub2-tools引导相关dracut生成 initramfsDebian 系对应的是linux-image-xxx内核镜像linux-headers-xxx头文件linux-firmware固件initramfs-toolsinitramfs 工具grub-common、grub-pc或grub-efi引导把这些包和内核包放在同一个目录里后面安装时一起处理能避免很多装完起不来的尴尬。4. 制作离线介质与传输过程中的细节4.1 介质选择U盘、移动硬盘还是内网共享介质选择看起来是小事但实际影响很大。我的排序是内网共享 移动硬盘 U盘。如果离线机和某台联网机在同一个内网里只是离线机自己不能出外网那最省事的方式是在联网机上起一个临时的 HTTP 服务或者 SMB 共享离线机直接通过内网拉取。这样既避免了物理介质拷贝的损坏风险速度也快得多。# 联网机上在包目录里起一个临时 HTTP 服务 python3 -m http.server 8000 # 离线机上直接下载 wget http://联网机IP:8000/kernel-pkgs.tar.gz如果必须用物理介质移动硬盘比 U 盘可靠因为 U 盘的文件系统尤其是 FAT32对单个大文件和权限位支持不好。如果非要用 U 盘建议格式化成 ext4 或者 exFAT并且打包成 tar 再拷贝而不是直接拷散文件。打包的好处是保留了权限和目录结构也方便校验。tar czvf kernel-pkgs.tar.gz /tmp/kernel-pkgs/ sha256sum kernel-pkgs.tar.gz kernel-pkgs.tar.gz.sha256把.sha256文件也一起拷过去到离线机上先sha256sum -c校验确认无误再解压。这一步花不了两分钟但能帮你排除掉介质损坏这个最常见的故障源。4.2 挂载和本地仓库的搭建包传到离线机之后不要急着直接rpm -ivh或dpkg -i。更稳妥的做法是在离线机上搭一个本地仓库然后用包管理器来装。这样做的好处是包管理器会自动处理依赖顺序比手动一个个装可靠得多。RedHat 系搭本地仓库mkdir -p /mnt/localrepo tar xzvf kernel-pkgs.tar.gz -C /mnt/localrepo createrepo /mnt/localrepo cat /etc/yum.repos.d/local.repo EOF [local] nameLocal Repo baseurlfile:///mnt/localrepo enabled1 gpgcheck0 EOFDebian 系搭本地仓库稍微麻烦一点可以用dpkg-scanpackagescd /mnt/localrepo dpkg-scanpackages . /dev/null | gzip -9c Packages.gz echo deb [trustedyes] file:///mnt/localrepo ./ /etc/apt/sources.list.d/local.list apt-get update搭好本地仓库之后安装就变成了yum install kernel或apt-get install linux-image-xxx依赖问题交给包管理器你只需要盯着输出看有没有报错就行。注意搭本地仓库时gpgcheck0或trustedyes是为了跳过签名校验因为离线环境下你没法联网获取 GPG key。这在受控的内网环境里是可以接受的但你要清楚这意味着放弃了包的来源验证所以包的来源必须是可信的。5. 实际安装与引导配置的完整链路5.1 安装顺序和 initramfs 的生成包管理器安装内核时通常会自动触发 initramfs 的生成。但离线环境下如果dracut或initramfs-tools版本不匹配这一步可能静默失败导致新内核没有对应的 initramfs 文件引导时直接 panic。所以安装完之后一定要手动确认 initramfs 是否生成成功ls -l /boot/initramfs-$(uname -r 对应的新版本).img # RedHat 系 ls -l /boot/initrd.img-新版本 # Debian 系如果没有手动生成dracut -f /boot/initramfs-新版本.img 新版本 # RedHat 系 update-initramfs -c -k 新版本 # Debian 系这里有个细节dracut生成 initramfs 时会读取/etc/dracut.conf里的配置如果你的配置里指定了某些模块或者排除了某些模块新内核的 initramfs 可能和旧的不一样。升级前最好把/etc/dracut.conf和/etc/dracut.conf.d/下的内容看一眼确认没有针对特定内核版本的硬编码。5.2 GRUB 配置更新与默认启动项内核装好、initramfs 生成好之后接下来是让引导程序认识新内核。RedHat 系通常会自动更新 grub 配置但离线环境下我建议手动确认一遍grub2-mkconfig -o /boot/grub2/grub.cfg # BIOS 引导 grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg # UEFI 引导路径按发行版调整Debian 系则是update-grub更新完之后用grep确认新内核的菜单项确实写进去了grep -i 新内核版本 /boot/grub2/grub.cfg关键的一步是设置默认启动项。默认情况下grub 会启动菜单里的第一个项而新装的内核通常排在前面。但为了保险我建议显式指定默认启动的内核并且保留旧内核作为备选# 查看所有菜单项 grub2-editenv list awk -F\ $1menuentry {print $2} /boot/grub2/grub.cfg # 设置默认启动项按菜单项名称或索引 grub2-set-default 新内核菜单项名称Debian 系可以用grub-set-default配合菜单索引或者直接编辑/etc/default/grub里的GRUB_DEFAULT。提示设置默认启动项时务必确认旧内核的菜单项还在。这样万一新内核起不来你还能在 grub 菜单里手动选旧内核进系统。这是离线升级最重要的安全网。5.3 重启前的最后检查清单重启是开弓没有回头箭的操作重启前我习惯过一遍这个清单检查项命令预期结果新内核包已安装rpm -qa | grep kernel或dpkg -l | grep linux-image能看到新版本initramfs 已生成ls /boot/initramfs-*或ls /boot/initrd.img-*有新版本对应文件grub 配置已更新grep 新版本 /boot/grub2/grub.cfg能找到菜单项旧内核仍在ls /boot/vmlinuz-*旧版本文件还在/boot 空间充足df -h /boot使用率低于 80%默认启动项正确grub2-editenv list指向预期内核这个清单看起来啰嗦但每一条都对应着我或者身边人踩过的真实坑。尤其是/boot空间和旧内核保留这两条前者导致过引导损坏后者导致过新内核起不来又退不回去的绝境。6. 重启失败时的排查与回滚6.1 新内核起不来先别慌新内核启动失败的表现有很多种卡在 grub、卡在 initramfs、kernel panic、或者起来了但某个硬件不工作。不同的表现对应不同的排查方向。如果是卡在 grub 阶段通常是 grub 配置问题。可以在 grub 菜单里按e编辑启动项手动指定旧内核的vmlinuz和initrd路径先进系统再说。如果是卡在 initramfs 阶段多半是 initramfs 里缺了关键模块比如根文件系统所在的存储驱动。这种情况可以在 grub 编辑界面给内核命令行加上rd.debug或breakpremount进入调试模式看具体卡在哪。如果是kernel panic注意看 panic 信息里的最后几行通常会提示是哪个模块或者哪个设备出了问题。常见的是根设备找不到VFS: Cannot open root device这往往和 initramfs 里缺存储驱动有关。6.2 用旧内核回滚的标准流程只要旧内核还在回滚其实很简单。在 grub 菜单里选中旧内核的菜单项启动进系统之后把默认启动项改回旧内核grub2-set-default 旧内核菜单项名称 grub2-mkconfig -o /boot/grub2/grub.cfg然后可以选择把新内核的包卸载掉或者先留着排查问题。我个人的习惯是先留着因为卸载内核包会触发 grub 配置更新万一更新过程出问题可能把旧内核的引导项也搞乱。等确认新内核彻底不用了再干净地卸载。卸载新内核包yum remove kernel-新版本 # RedHat 系 apt-get remove linux-image-新版本 # Debian 系卸载后同样要确认 grub 配置和 initramfs 都回到了正常状态。6.3 如果旧内核也被删了怎么办这是最坏的情况但也不是完全没救。如果/boot里旧内核的vmlinuz和initrd文件还在只是 grub 菜单项没了可以手动在 grub 命令行里引导grub linux /boot/vmlinuz-旧版本 root/dev/sda1 ro grub initrd /boot/initramfs-旧版本.img grub boot如果连文件都没了那就只能通过救援模式rescue mode或者 LiveCD 启动挂载原系统分区重新安装旧内核包。这也是为什么我一直强调升级前备份/boot目录tar czvf /root/boot-backup-$(date %Y%m%d).tar.gz /boot这个备份不大但关键时刻能救命。有了它即使 grub 配置全乱你也能从 LiveCD 里把/boot恢复回去。7. 几个容易被忽略但很致命的细节7.1 内核模块和第三方驱动如果你的系统里装了第三方内核模块比如某些 RAID 卡驱动、虚拟化增强驱动、或者自己编译的模块升级内核后这些模块需要针对新内核重新编译或重新安装。离线环境下这意味着你不仅要下载内核包还要下载对应的驱动包或者准备好编译环境。判断有没有第三方模块可以看ls /lib/modules/$(uname -r)/extra/ ls /lib/modules/$(uname -r)/updates/这两个目录里如果有东西基本就是第三方模块。升级前一定要确认这些模块有没有对应新内核的版本否则新内核起来了但硬件用不了等于白升。7.2 Secure Boot 对内核签名的要求如果机器开启了 Secure Boot未签名的内核是无法引导的。发行版官方仓库的内核通常是签过名的但如果你用的是自己编译的内核或者第三方仓库的内核就可能因为签名问题起不来。检查 Secure Boot 状态mokutil --sb-state如果显示SecureBoot enabled那就要确保你装的内核是签过名的。离线环境下没法临时关闭 Secure Boot 再重开有些机器关了之后需要重新配置所以升级前就要把这个因素考虑进去。7.3 时间同步和证书问题这个坑比较隐蔽。有些内核包在安装时会校验签名或者时间戳如果离线机的系统时间偏差太大校验可能失败。升级前顺手确认一下时间date timedatectl status如果时间偏差大先手动校准。另外如果本地仓库用了 HTTPS还要注意证书问题离线环境下建议直接用file://协议省去证书的麻烦。8. 我个人的操作习惯和几点体会做了这么多次离线内核升级我慢慢形成了一套自己的固定动作。每次动手前我会先在测试机上完整走一遍流程确认没问题再上生产。测试机不需要和生产机配置完全一样但系统版本和架构必须一致。这一步多花一两个小时能避免生产环境出问题时的手忙脚乱。另一个习惯是永远保留至少一个可用的旧内核。哪怕新内核已经稳定运行了一两个月我也不会急着删旧内核。磁盘空间不够就扩/boot反正现在硬盘便宜为这点空间冒引导失败的风险不值得。还有一点是关于文档。每次离线升级我都会把这次用的包版本、下载来源、安装命令、遇到的问题和解决办法记下来。下次再遇到类似需求直接翻记录就行不用重新踩一遍坑。内网环境下的操作往往缺乏在线文档支持自己积累的这份记录就是最宝贵的资料。最后说个心态上的事。离线升级内核这件事技术难度其实不算特别高真正考验人的是细心和耐心。在线环境下你可以快速试错离线环境下每一次操作都要想清楚后果。把准备工作做足把回滚路径留好剩下的就是按部就班执行。急不得也慌不得。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑