openEuler离线升级实战:从依赖解析到本地仓库构建全流程指南
2026/8/7 5:32:29 网站建设 项目流程

1. 项目概述:为什么需要离线升级?

最近在负责一个部署在内网环境的生产系统维护,底层操作系统用的是 openEuler 22.03-LTS-SP1。大家都知道,LTS(长期支持)版本主打的就是稳定,但为了修复一些已知的安全漏洞和获取关键的功能更新,我们决定将系统升级到最新的 SP3 版本。麻烦就麻烦在,这套环境是纯离线的,外网连不上,官方源、第三方源统统指望不上。这就意味着,整个升级过程不能像在公网环境那样,一条dnf update命令就自动搞定,所有依赖包都需要我们手动准备、搬运和安装。

这种离线升级的场景其实挺常见的,尤其是在金融、政务、军工等对网络安全有严格要求的领域,或者一些物理隔离的研发、测试环境中。如果你也面临类似情况,那么这篇从实战中踩坑总结出来的全流程指南,或许能帮你省下大量排查问题的时间。整个过程的核心思路,就是在一台能联网的“跳板机”上,模拟目标环境,下载所有必需的 RPM 包及其依赖,然后打包转移到内网,最后在内网目标机上完成升级。听起来简单,但依赖地狱和版本冲突是两大拦路虎,下面我就把每个环节的细节和避坑要点掰开揉碎了讲清楚。

2. 升级整体设计与前期规划

2.1 环境分析与方案选型

接到离线升级任务,第一步不是急着动手,而是先把情况摸清楚。我们需要明确几个关键信息:

  1. 源版本与目标版本:明确是从 openEuler 22.03-LTS-SP1 升级到 SP3。这属于同大版本下的子版本升级,通常不会涉及核心组件(如内核)的巨变,但包含了大量的安全补丁和累积更新。
  2. 系统架构:通过uname -m确认是 x86_64 还是 aarch64。这决定了你需要下载什么架构的软件包,弄错了全盘皆输。
  3. 已安装软件包:使用rpm -qa命令导出当前系统所有已安装的 RPM 包列表。这一步至关重要,因为离线升级不是要安装一个全新的系统,而是基于现有软件集合进行更新。你需要确保下载的更新包能覆盖当前系统的大部分软件,特别是关键的系统组件和业务依赖。

方案上,我们选择使用dnfdownload命令来下载依赖包。虽然也有yumdownloaderrepoquery等工具,但dnf download能更好地处理复杂的依赖关系,并且是 openEuler 推荐的工具链的一部分。整个流程可以拆解为三个主要阶段:

  • 阶段一(联网环境):搭建一个与目标机尽可能一致的虚拟机或容器环境,使用工具下载全量升级包。
  • 阶段二(介质转移):将下载好的包通过安全方式(如内网文件服务器、移动硬盘)传输到离线环境。
  • 阶段三(离线环境):在目标服务器上,使用本地创建的仓库进行升级操作。

2.2 工具准备与跳板机环境搭建

工欲善其事,必先利其器。我们需要准备一台能访问互联网的机器作为跳板机,这台机器最好是一台干净的虚拟机,避免已有环境干扰。

首先,在跳板机上安装一个与目标机版本一致的 openEuler 22.03-LTS-SP1 系统。你可以从 openEuler 官网下载 ISO 镜像进行安装。安装时,建议选择“最小化安装”,这样系统最干净,下载的包也更精确。

系统安装好后,配置 openEuler 22.03-LTS-SP3 的官方 yum 源。编辑/etc/yum.repos.d/openEuler.repo文件,确保源指向正确的 SP3 仓库地址。一个基础的配置示例如下:

[OS] name=openEuler-$releasever - OS baseurl=https://repo.openeuler.org/openEuler-22.03-LTS-SP3/OS/$basearch/ enabled=1 gpgcheck=1 gpgkey=https://repo.openeuler.org/openEuler-22.03-LTS-SP3/OS/$basearch/RPM-GPG-KEY-openEuler [everything] name=openEuler-$releasever - Everything baseurl=https://repo.openeuler.org/openEuler-22.03-LTS-SP3/everything/$basearch/ enabled=1 gpgcheck=1 gpgkey=https://repo.openeuler.org/openEuler-22.03-LTS-SP3/everything/$basearch/RPM-GPG-KEY-openEuler

配置完成后,运行dnf clean all && dnf makecache更新元数据缓存。

注意:务必确保跳板机的架构(x86_64/aarch64)与目标机完全一致。另外,如果目标机上安装了一些非官方源(如 EPEL、NVIDIA、MySQL 等)的软件,你需要在跳板机上也添加对应的源,否则无法下载这些软件的更新包。这往往是依赖缺失的罪魁祸首。

3. 核心环节:离线包下载与依赖解析

3.1 使用 DNF Download 下载全量更新包

这是整个流程中最关键也最容易出错的一步。我们的目标不是下载 SP3 的所有包,而是下载“从当前 SP1 系统升级到 SP3 所需”的包。这里就需要用到之前导出的已安装包列表。

假设你将目标机的包列表保存为installed_packages.list并传到了跳板机。首先,我们需要安装dnf-plugins-core,它提供了download命令插件:

sudo dnf install -y dnf-plugins-core

接下来,创建一个目录用于存放下载的 RPM 包,例如/opt/offline_upgrade_sp3

sudo mkdir -p /opt/offline_upgrade_sp3

然后,使用dnf download命令进行下载。这里有一个非常重要的技巧:直接对整个列表下载可能会因为个别包的仓库问题而中断。更稳健的做法是编写一个脚本,或者使用xargs配合循环。但更推荐使用dnfrepoquerydownload组合来解析依赖。

一个经过实战检验的相对可靠的方法是分两步走:

  1. 解析依赖树:使用repoquery命令生成需要下载的包列表(包含依赖)。

    # 首先,确保安装了 yum-utils 或 dnf-utils sudo dnf install -y dnf-utils # 生成需要更新的包列表。--releasever 指定目标版本。 sudo dnf repoquery --installroot=/tmp/empty-root --releasever=22.03-LTS-SP3 --qf "%{name}" --upgrades | sort -u > /tmp/upgrade_packages.list

    这个命令会列出所有可以从当前版本升级到 SP3 的包。--installroot指定一个空路径,以避免受当前系统已安装包的影响,力求模拟一个干净的环境去解析 SP3 的升级关系。

  2. 批量下载:根据生成的列表进行下载。

    cd /opt/offline_upgrade_sp3 sudo dnf download --resolve --alldeps --destdir /opt/offline_upgrade_sp3 $(cat /tmp/upgrade_packages.list)
    • --resolve:自动解决依赖关系。
    • --alldeps:下载所有依赖包,包括那些可能已经安装但需要更新版本的。
    • --destdir:指定下载目录。

实操心得dnf download过程可能会非常漫长,并且网络不稳定可能导致中断。强烈建议使用screentmux会话在后台运行此命令。另外,第一次运行时很可能会因为缺少某些依赖而失败,提示找不到某个包。这时需要根据错误信息,检查是否缺少对应的仓库(如 EPEL),或者该包在 SP3 中是否已被改名或废弃。这是一个需要耐心反复迭代的过程。

3.2 处理依赖冲突与异常包

在下载过程中,你几乎一定会遇到类似这样的错误:

No match for argument: some-obscure-package Error: Unable to find a match: some-obscure-package

这通常意味着:

  1. 该软件包来自一个你尚未配置的第三方仓库。
  2. 该软件包在 SP3 官方源中已被移除或改名。
  3. 该软件包是一个本地手动编译安装的包,不存在于任何仓库。

应对策略:

  • 对于情况1:在跳板机上添加对应的第三方仓库源,然后重新运行下载命令。
  • 对于情况2:这是最棘手的情况。你需要判断这个包是否关键。
    • 如果不关键(例如某个旧的工具),可以考虑在升级后从目标系统卸载它,或者寻找替代品。可以在下载列表中剔除它。
    • 如果关键,需要去软件项目的官方社区查找是否提供了兼容 SP3 的包,或者评估是否必须保留在 SP1 版本(这可能带来安全风险)。
  • 对于情况3:这类包无法通过包管理器更新。你需要单独备份该软件的安装目录、配置和数据,并在升级完成后,手动重新编译安装或部署。

一个实用的技巧是,将dnf download的错误输出重定向到文件,然后逐一分析处理:

sudo dnf download --resolve --alldeps --destdir . $(cat list.txt) 2>&1 | tee download.log

然后grep -i "no match\|error" download.log来快速定位问题包。

4. 创建本地仓库与升级介质准备

4.1 使用 Createrepo 构建本地 YUM 仓库

所有 RPM 包下载完成后,它们只是一堆散乱的文件。为了让离线环境中的dnf能够识别并处理依赖关系,我们必须将它们组织成一个本地 YUM 仓库。

这就需要用到createrepo_c工具(createrepo的 C 语言实现,效率更高)。首先安装它:

sudo dnf install -y createrepo_c

安装完成后,进入存放 RPM 包的目录,执行创建仓库元数据的命令:

cd /opt/offline_upgrade_sp3 sudo createrepo_c .

这个命令会扫描当前目录下的所有 RPM 包,生成repodata文件夹,里面包含了仓库的元数据(如 primary.xml, filelists.xml, others.xml 等),dnf正是通过这些元数据来查询包信息和依赖关系的。

注意事项createrepo_c .命令末尾的点号代表当前目录,千万别漏了。这个过程可能需要几分钟,取决于 RPM 包的数量和大小。完成后,你可以使用dnf repolist命令(指定本地仓库路径)来测试仓库是否创建成功,但更直接的测试是在下一步。

4.2 打包与完整性校验

仓库创建好后,就可以将整个/opt/offline_upgrade_sp3目录打包了。为了保证传输效率,通常使用tar进行压缩:

cd /opt sudo tar -czvf offline_upgrade_sp3.tar.gz offline_upgrade_sp3/

完整性校验是必须的环节!在通过网络或移动介质传输大文件时,数据损坏的风险是存在的。我们需要生成压缩包的校验和:

sha256sum offline_upgrade_sp3.tar.gz > offline_upgrade_sp3.tar.gz.sha256

这个sha256文件需要和tar.gz文件一起传输到离线环境。在离线环境解压前,首先进行校验:

sha256sum -c offline_upgrade_sp3.tar.gz.sha256

如果显示 “OK”,说明文件完好无损。如果校验失败,必须重新传输,绝对不要使用损坏的包进行升级,否则会导致系统处于不可预测的状态。

5. 离线环境升级操作实录

5.1 前置检查与备份

在离线目标机上执行任何升级操作前,必须完成以下准备工作,这是你的“安全绳”:

  1. 完整系统备份:如果条件允许,对整机做快照(如果是虚拟机)或使用ddrsync等工具对关键分区进行完整备份。这是最彻底的回滚方案。
  2. 关键数据备份:备份/etc,/home,/var(特别是/var/lib下的数据库数据,如 MySQL、PostgreSQL),以及任何自定义的服务数据目录。
  3. 记录当前状态
    • rpm -qa > /backup/installed_packages_pre_upgrade.list
    • df -h记录磁盘空间。
    • ip addr,ss -tulnp记录网络和端口状态。
    • systemctl list-units --type=service --state=running记录运行中的服务。
  4. 检查磁盘空间:升级过程需要临时空间。确保/分区和/var分区有至少 5-10GB 的可用空间。解压后的 RPM 包和临时缓存会占用空间。

5.2 配置本地仓库并执行升级

offline_upgrade_sp3.tar.gz和校验文件传输到目标机,例如放到/opt下。校验并解压:

cd /opt sha256sum -c offline_upgrade_sp3.tar.gz.sha256 sudo tar -xzvf offline_upgrade_sp3.tar.gz

解压后,目录结构为/opt/offline_upgrade_sp3/,里面是 RPM 包和repodata文件夹。接下来在目标机上创建一个本地仓库配置文件:

sudo vim /etc/yum.repos.d/local_sp3.repo

写入以下内容:

[local-sp3-upgrade] name=Local OpenEuler 22.03-LTS-SP3 Upgrade Repository baseurl=file:///opt/offline_upgrade_sp3 enabled=1 gpgcheck=0 priority=1
  • baseurl使用file://协议指向本地目录。
  • gpgcheck=0是因为我们自建的本地仓库没有 GPG 签名。在生产环境中,如果你有内部签名机制,可以配置gpgcheck=1并指定gpgkey
  • priority=1设置较高的优先级,确保升级时优先使用本地仓库。

保存后,清除 DNF 缓存并启用新仓库:

sudo dnf clean all sudo dnf makecache

现在,可以开始模拟升级了。强烈建议先进行测试升级(dry-run),这能预览将要发生的变化,而不会实际安装任何包:

sudo dnf upgrade --repo local-sp3-upgrade --downloadonly --assumeno

或者使用更直观的:

sudo dnf check-upgrade --repo local-sp3-upgrade

查看输出,确认将要升级、安装或卸载的包列表是否符合预期,特别注意是否有核心组件(如内核、glibc、systemd)被标记为更新。

如果一切看起来正常,就可以执行真正的升级了。这是一个需要耐心的过程:

sudo dnf upgrade --repo local-sp3-upgrade -y

命令执行后,dnf会从本地仓库解析依赖,下载(实际上文件已在本地)并安装所有更新。整个过程不能中断,请确保服务器供电和连接稳定。

5.3 升级后必要操作与验证

升级完成后,系统不会立即重启。需要执行一系列收尾和验证工作:

  1. 更新引导配置:如果内核升级了,需要重新生成 initramfs 并更新 grub 配置。

    sudo dracut -f sudo grub2-mkconfig -o /boot/grub2/grub.cfg # 对于 UEFI 系统,路径可能是 /boot/efi/EFI/openEuler/grub.cfg
  2. 重启系统:这是最关键的一步,新内核和核心库将在重启后生效。

    sudo reboot
  3. 重启后验证

    • uname -r检查内核版本是否已更新。
    • cat /etc/os-release确认系统版本号变为 22.03-LTS-SP3。
    • rpm -qa | grep -E \"kernel|systemd|glibc\"查看核心组件版本。
    • systemctl list-units --type=service --state=failed检查是否有服务启动失败。
    • 运行主要业务应用,进行功能性测试。

6. 常见问题排查与回滚方案

6.1 升级过程中遇到的典型错误

即使准备再充分,实际升级时也可能遇到问题。下面是一些常见错误及解决方法:

问题现象可能原因排查与解决思路
Error: Transaction check error包依赖冲突,例如新包 A 需要新版本库 B,但旧包 C 又依赖旧版本库 B。这是最经典的依赖地狱。首先仔细看错误信息,定位冲突的包。尝试dnf remove [包C]移除冲突的旧包(确保它不重要),或者寻找是否有一个兼容的旧包 C 的更新版本在仓库里。操作前务必确认移除的包不影响业务
Package X is already installed本地仓库中的包版本与已安装版本相同或更旧。这通常是因为下载的包集合中混入了不需要更新的包。可以暂时在本地仓库配置中排除这个包,或者使用dnf upgrade --exclude=包名跳过它。
Failed dependencies: libY.so.Z is needed by X动态库依赖缺失。虽然下载了 RPM,但可能某个底层库的版本不对。使用dnf provides */libY.so.Z在本地仓库中查找哪个包提供此库。确保提供该库的包已被正确下载并包含在升级事务中。
升级后服务无法启动1. 配置文件格式在新版本中不兼容。
2. 服务的依赖路径或环境变量改变。
1. 检查服务的日志 (journalctl -u [服务名])。
2. 对比备份的旧配置文件与新版本的默认配置文件,进行合并或调整。
3. 查看是否有相关的selinux策略需要调整。

6.2 系统回滚操作指南

如果升级后系统出现严重问题且无法快速修复,回滚是最后的保障。回滚的前提是:你没有在升级后清除 DNF 的历史事务记录和旧版本的 RPM 包

  1. 查看 DNF 历史

    sudo dnf history list

    找到最近那次升级操作的 ID(例如 10)。

  2. 执行回滚

    sudo dnf history undo 10 -y

    这条命令会尝试逆操作,将系统恢复到升级前的状态。

  3. 回滚后重启

    sudo reboot

重要警告:回滚并非 100% 可靠,特别是当升级过程中涉及了复杂的依赖变更或配置文件修改时。它高度依赖于 DNF 事务记录的完整性和旧 RPM 包的保留情况。因此,完整的系统备份才是你最可靠的回滚手段。在升级前制作可启动的备份镜像,在出现不可恢复的错误时,直接从备份还原,这是生产环境最稳妥的做法。

整个离线升级过程,考验的不仅是技术,更是耐心和细致。每一个环节的检查与验证,都是为最终的成功增加砝码。尤其是在处理依赖和冲突时,切忌盲目操作,多查资料,多模拟测试。希望这份详尽的记录能让你在下次面对类似任务时,心中更有底气。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询