努力
加油

从 CentOS 7.6 升级到 8.2 后,软件包管理有哪些变化?

从 CentOS 7.6 升级到 8.2,最核心的变化在于包管理工具从 yum 全面切换到了 dnf。

虽然你在命令行里敲 yum 命令依然能跑通(因为系统做了兼容层映射),但底层的逻辑、依赖解析机制以及行为表现已经发生了本质改变。对于运维和开发来说,这不仅仅是换个名字那么简单,很多旧习惯在 CentOS 8 上会直接报错或产生意想不到的副作用。

以下是几个关键的变化点,建议重点留意:

1. 底层引擎变更:从 YUM 到 DNF

CentOS 8 基于 RHEL 8,采用了 DNF (Dandified YUM) 作为默认的包管理器。

  • 性能提升:DNF 使用 Python 3 编写,依赖解析速度更快,内存占用更合理,尤其是在处理大型仓库元数据时。
  • API 变化:如果你之前写过自动化脚本调用了 yum 的 Python API,现在需要迁移到 dnf 的 API。不过日常手动操作影响不大。

2. 模块(Modules)系统的引入 —— 最容易踩坑的地方

这是 CentOS 7 到 8 最大的体验差异之一。

  • CentOS 7:一个软件包就是一个版本。比如 httpd 就是那个版本的 Apache。
  • CentOS 8:引入了 AppStream 仓库,支持“模块化”安装。同一个软件可能有多个流(Stream)或多个版本共存。
    • 现象:当你执行 yum install httpd 时,它可能不再直接安装最新的稳定版,而是提示你选择模块。
    • 解决:如果不想用模块化的复杂逻辑,可以显式指定不启用模块,或者使用 --setopt=module_platform_id=platform:f8 等参数。但在大多数情况下,直接使用 dnf install <package> 会自动处理默认流。
    • 注意:某些旧软件可能没有对应的模块定义,导致安装失败,这时需要检查是否缺少了 EPEL 源或其他第三方源。

3. 仓库结构重组:AppStream vs BaseOS

CentOS 7 只有一个主要的 base 和 updates 仓库。CentOS 8 将仓库分为了两个主要部分:

  • BaseOS:包含基础操作系统组件,如内核、glibc、系统工具等。这部分相对稳定,更新频率低。
  • AppStream:包含用户空间的应用程序、运行时环境(如 Node.js, Python, Ruby)、数据库服务器等。这部分更新频繁,提供多种版本。

影响:

  • 以前 yum update 会把所有东西都更新一遍。
  • 现在你需要理解这两个仓库的区别。通常 dnf update 会同时更新两者,但如果你只关心应用层,关注 AppStream 即可;如果要升级内核,必须确保 BaseOS 的源配置正确。

4. GPG 签名验证更严格

CentOS 8 对软件包的 GPG 签名验证更加严格。

  • 问题:如果你从第三方源(如 EPEL、Remi、Nginx 官方源等)安装软件,必须确保这些源的 GPG 密钥已正确导入并信任。
  • 常见错误:Public key for xxx.rpm is not installed。
  • 解决:在安装任何第三方 RPM 前,先导入其 GPG 密钥。例如:
    rpm --import https://nginx.org/keys/nginx_signing.key

5. 服务管理:systemctl 成为绝对主流

虽然这不是包管理器本身的功能,但与包安装后的服务启动紧密相关。

  • CentOS 7 还保留着大量的 chkconfig 和 service 命令兼容性。
  • CentOS 8 彻底移除了大部分传统 SysVinit 脚本的支持,强制使用 systemd。
  • 影响:安装完软件后,不能用 service nginx start 了,必须用 systemctl start nginx。如果某个旧软件的 RPM 包里还残留着 init.d 脚本,可能在安装时报错或无法自动启用服务。

6. 移除了一些过时包和特性

  • Python 2 被移除:CentOS 8 默认只提供 Python 3。如果你依赖 Python 2 的包(如 python-devel),需要通过 dnf module install python2 来启用模块,或者使用容器化方案。
  • Perl 5.26+:版本大幅升级,可能导致一些基于 Perl 的旧脚本失效。
  • GCC 版本:默认 GCC 版本更高(8.2+),编译旧代码时可能需要调整 CFLAGS 或使用 scl(Software Collections)来安装旧版本编译器。

7. 实际建议与最佳实践

  1. 不要试图原地升级:CentOS 官方并不推荐从 7 直接升级到 8。最稳妥的方式是备份数据后全新安装 CentOS 8。如果必须升级,请使用 leapp 工具进行预检和迁移,但成功率并非 100%,尤其是有大量自定义配置的系统。
  2. 善用 dnf 而非 yum:虽然 yum 可用,但建议使用 dnf 命令,因为它更接近未来趋势,且文档和社区支持更多针对 DNF。
  3. 检查依赖冲突:由于模块化系统的存在,有时会出现“已安装 X 但需要 Y”的奇怪依赖链。使用 dnf distro-sync 可以同步所有已安装包到最新版本,避免混合不同来源的包。
  4. EPEL 源适配:确保你的 EPEL 源版本匹配 CentOS 8。旧的 EPEL 7 源在 CentOS 8 上完全不可用,需重新配置。
  5. 查看帮助:多用 man dnf 和 dnf --help,了解新的选项如 --allowerasing, --refresh, --best 等。

总结来说,从 CentOS 7 到 8,包管理的核心思维要从“单一仓库、简单安装”转变为“多仓库分离、模块化版本管理”。适应这个新模型后,你会发现依赖解析更智能,系统也更稳定。