在 RHEL/CentOS 7 上安装 DNF:完整技术指南
DNF (Dandified YUM) 是基于 RPM 的 Linux 发行版的下一代包管理器,旨在完全替代 YUM。它通过 `libsolv` 库提供更快的依赖解析、更低的内存消耗以及稳定的 Python API。虽然 RHEL/CentOS 7 默认搭载 YUM,但 DNF 可通过 EPEL 仓库完整安装,并可在同一系统上与 YUM 并行运行,或作为 YUM 的透明替代品。
本指南将介绍完整的安装流程,解释 YUM 与 DNF 之间的架构差异,涵盖实际边缘案例,并提供生产就绪的命令参考。
为何 DNF 在 RHEL/CentOS 7 上优于 YUM
在操作终端之前,了解*为何*需要升级有助于您做出明智的决策——尤其是在长期运行的 VPS 托管环境中,包管理的可靠性至关重要。
核心架构差异
YUM 依赖基于 Python 的依赖解析器,该解析器在处理大型依赖树时存在有据可查的性能问题。DNF 用 `libsolv` 取代了该解析器,这是一个基于 SAT 求解器的依赖解析引擎,最初由 SUSE 开发。其实际影响十分显著:
- 依赖解析速度:DNF 解析复杂依赖链所需时间仅为 YUM 的一小部分,在解决大型软件包集中的冲突时尤为明显。
- 内存占用:YUM 将整个仓库元数据加载到内存中。DNF 使用延迟加载并更积极地缓存,从而降低峰值 RAM 使用量。
- API 稳定性:YUM 的 Python API 在次要版本之间变化不可预测。DNF 提供有文档记录的、版本化的 Python API,插件作者可以依赖。
- 插件架构:DNF 使用简洁的基于钩子的插件系统。YUM 插件由于松散耦合,常常相互干扰。
- 事务历史:DNF 维护更丰富的事务历史数据库,使回滚和审计更加精确。
YUM 与 DNF:功能对比
| 功能 | YUM | DNF |
|---|
| — | — | — |
|---|
| 依赖解析器 | 基于 Python(内部) | `libsolv` SAT 求解器 |
|---|
| 内存使用 | 较高(完整元数据加载) | 较低(延迟加载 + 积极缓存) |
|---|
| Python API | 跨版本不稳定 | 稳定的版本化 API |
|---|
| 插件系统 | 松散耦合,易产生冲突 | 基于钩子,相互隔离 |
|---|
| 事务回滚 | 有限 | 完整历史记录,支持回滚 |
|---|
| 并行下载 | 否 | 是(通过 `librepo`) |
|---|
| 弱依赖 | 不支持 | 支持(`Recommends`、`Suggests`) |
|---|
| 模块流 | 不支持 | 支持(DNF 4+) |
|---|
| 维护状态 | 已停止维护 | 积极维护中 |
|---|
| RHEL/CentOS 默认 | 7 及更早版本 | 8 及更高版本 |
|---|
前提条件
在继续之前,请确认以下事项:
- 运行中的 RHEL 7 或 CentOS 7 实例(裸机、虚拟机或云 VPS)。
- Root 或 sudo 访问权限——所有安装命令均需提升权限。
- 有效的互联网连接——必须能够访问 EPEL 仓库。
- 至少 500 MB 的可用磁盘空间,用于 DNF、其依赖项及仓库元数据缓存。
如果您在独立服务器上运行最小化 CentOS 7 安装,请验证 `curl` 和 `wget` 是否可用,因为它们有时在精简镜像中缺失。
第一步:更新现有系统软件包
在安装新软件之前同步软件包数据库,可防止版本冲突,并确保 EPEL 发布包能够根据当前 RPM 数据库状态干净地安装。
“`bash
sudo yum update -y
“`
此操作的作用:下载并应用当前已安装软件包的所有可用更新,刷新仓库元数据,并重建 RPM 事务锁。在生产系统上,请在维护窗口期间安排此操作——内核更新需要重启才能生效。
边缘案例:如果 `yum update` 因 `Multilib version problems` 错误而失败,可将 `sudo yum update –setopt=protected_multilib=false -y` 作为一次性解决方案,然后在继续之前排查冲突的软件包。
第二步:启用 EPEL 仓库
DNF 在默认的 CentOS/RHEL 7 基础仓库中不可用。由 Fedora 项目维护的 企业 Linux 额外软件包(EPEL)仓库提供了该软件包。
“`bash
sudo yum install epel-release -y
“`
验证仓库是否处于活动状态:
“`bash
yum repolist | grep epel
“`
预期输出应显示 `epel/x86_64` 且软件包数量不为零(通常为 13,000+)。如果仓库显示为禁用状态,请强制启用:
“`bash
sudo yum-config-manager –enable epel
“`
安全说明:EPEL 软件包由 Fedora 基础设施团队构建并签名。`epel-release` 软件包会自动安装 GPG 密钥。在信任该仓库的软件包之前,您可以对照官方 Fedora 密钥服务器验证密钥指纹——这一步骤在加固的生产系统上值得执行。
位于代理或防火墙后面?如果您的服务器无法直接访问 Fedora 镜像,请使用您的代理设置配置 `/etc/yum.conf`:
“`ini
proxy=http://your-proxy-server:port
proxy_username=user
proxy_password=pass
“`
第三步:安装 DNF
启用 EPEL 后,通过单个命令安装 DNF 及其核心依赖项:
“`bash
sudo yum install dnf -y
“`
这将自动引入 `dnf`、`dnf-data`、`python-dnf`、`libcomps`、`librepo` 和 `libsolv` 作为自动依赖项。根据已安装内容的不同,总下载大小通常在 3–8 MB 之间。
安装内容:
- `dnf` — 主二进制文件和命令行界面
- `libsolv` — 基于 SAT 的依赖解析器
- `librepo` — 并行下载库
- `libcomps` — 用于软件包组的 comps XML 解析器
- `python-dnf` — Python 绑定和 DNF 核心库
第四步:验证安装
确认 DNF 正常运行并检查其版本:
“`bash
dnf –version
“`
安装成功后将产生类似以下的输出:
“`
4.0.9.2
Installed: dnf-0:4.0.9.2-1.el7.noarch at …
Built : CentOS BuildSystem <http://bugs.centos.org> at …
“`
通过列出 DNF 所见的可用仓库进行更深入的健全性检查:
“`bash
dnf repolist
“`
输出应与 `yum repolist` 显示的内容一致,确认 DNF 已从 `/etc/yum.repos.d/` 正确继承了您现有的仓库配置。
重要提示:CentOS 7 上的 DNF 读取与 YUM 相同的仓库 `.repo` 文件。无需进行仓库迁移。两个工具共享 `/etc/yum.repos.d/` 和 `/var/cache/`(位于各自的子目录中)。
第五步:DNF 核心命令参考
DNF 在命令上与 YUM 有意保持兼容。下表涵盖了您最常用的操作:
| 任务 | DNF 命令 |
|---|
| — | — |
|---|
| 更新所有软件包 | `sudo dnf update -y` |
|---|
| 安装软件包 | `sudo dnf install <package> -y` |
|---|
| 删除软件包 | `sudo dnf remove <package> -y` |
|---|
| 搜索软件包 | `dnf search <keyword>` |
|---|
| 获取软件包信息 | `dnf info <package>` |
|---|
| 列出已安装软件包 | `dnf list installed` |
|---|
| 列出可用更新 | `dnf check-update` |
|---|
| 清理缓存元数据 | `sudo dnf clean all` |
|---|
| 查看事务历史 | `dnf history` |
|---|
| 回滚事务 | `sudo dnf history undo <id>` |
|---|
| 安装软件包组 | `sudo dnf groupinstall "<group>"` |
|---|
| 启用仓库 | `sudo dnf config-manager –enable <repo>` |
|---|
DNF 事务历史与回滚
这是 DNF 在操作上最具价值的功能之一,也是 YUM 处理得较差的功能。每次安装、更新或删除操作都记录在 `/var/lib/dnf/history/` 中。要查看最近的事务:
“`bash
dnf history list
“`
要查看特定事务中的具体变更:
“`bash
dnf history info <transaction-id>
“`
要撤销某个事务(例如,回滚一次错误的更新):
“`bash
sudo dnf history undo <transaction-id>
“`
此功能在带有 cPanel 的 VPS 上尤为有用,因为软件包更新可能与控制面板依赖项产生冲突。
DNF 配置文件
DNF 的全局配置位于 `/etc/dnf/dnf.conf`。生产环境使用的关键调优参数:
“`ini
[main]
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=True
best=True
skip_if_unavailable=False
“`
- `installonly_limit=3` — 仅保留最近 3 个内核版本,防止 `/boot` 被占满。
- `clean_requirements_on_remove=True` — 在删除软件包时自动移除孤立依赖项。
- `best=True` — 始终安装最新可用版本,出现错误时报错而非静默降级。
第六步:将 DNF 配置为默认包管理器
在 RHEL/CentOS 7 上,YUM 仍是系统默认值。您有两种方式将 DNF 设为主要界面。
方案 A:Shell 别名(用户级,非破坏性)
将以下内容添加到 `~/.bashrc`(当前用户)或 `/etc/bashrc`(系统范围):
“`bash
alias yum='dnf'
“`
立即应用:
“`bash
source ~/.bashrc
“`
限制:此别名仅适用于交互式 Shell 会话。通过绝对路径(`/usr/bin/yum`)直接调用 `yum` 的脚本,或在不同用户下运行的脚本(例如 cron 任务、systemd 单元)不受影响。
方案 B:符号链接(系统级)
若要进行更彻底的替换,可创建一个符号链接,将 `yum` 二进制文件重定向到 `dnf`:
“`bash
sudo mv /usr/bin/yum /usr/bin/yum.bak
sudo ln -s /usr/bin/dnf /usr/bin/yum
“`
重要警告:此方案影响所有用户和所有系统范围内的脚本。请先在非生产环境中进行充分测试。某些系统脚本和第三方工具(包括某些 cPanel/WHM 组件)会明确调用 `/usr/bin/yum`,如果二进制文件被替换,可能会出现意外行为。请务必按上述方式备份原始二进制文件。
方案 C:DNF 作为 YUM 插件(推荐用于服务器)
对于生产服务器,最简洁的方案是保持 YUM 完整,仅在您自己的工作流和自动化脚本中显式使用 `dnf`。这样既能避免破坏系统工具的风险,又能让您充分使用 DNF 的功能。
实际陷阱与边缘案例
以下是在实际部署中出现的问题,在基础教程中很少涉及。
GPG 密钥冲突:如果您从多个第三方仓库安装软件包,DNF 更严格的 GPG 强制执行(当 `gpgcheck=1` 时)可能会拒绝 YUM 之前静默接受的软件包。请始终使用 `sudo rpm –import <key-url>` 显式导入仓库 GPG 密钥。
插件不兼容:某些 YUM 插件(例如 `yum-plugin-fastestmirror`)没有直接的 DNF 等效项或行为有所不同。DNF 有自己的 `fastestmirror` 插件(`dnf-plugin-fastestmirror`),但默认未启用。使用 `sudo dnf install python3-dnf-plugin-fastestmirror` 安装它。
缓存位置差异:YUM 将元数据缓存在 `/var/cache/yum/` 中。DNF 使用 `/var/cache/dnf/`。如果磁盘空间紧张,两个缓存可能共存并占用大量空间。请分别运行 `sudo dnf clean all` 和 `sudo yum clean all` 来回收空间。
RHEL 订阅管理:在已注册的 RHEL 7 系统上(与 CentOS 相对),`subscription-manager` 插件与 YUM 集成。RHEL 7 上的 DNF 在没有额外配置的情况下,可能无法完全支持受订阅限制的仓库。切换后请使用 `subscription-manager repos –list-enabled` 进行验证。
Python 版本敏感性:CentOS 7 上的 DNF 使用 Python 2 绑定(`python-dnf`)。如果您已在系统上升级到 Python 3,请确保不会无意中破坏 `python-dnf` 依赖链。RHEL 8+ 上的 DNF 4+ 原生使用 Python 3。
规划 CentOS 7 之后的迁移路径
CentOS 7 已于 2024 年 6 月 30 日停止维护。安装 DNF 是一项有用的操作改进,但不会改变 EOL 发行版的底层安全状况。如果您仍在运行 CentOS 7 工作负载,应将迁移到 AlmaLinux 8/9、Rocky Linux 8/9 或 RHEL 8/9 的计划纳入路线图。所有这些发行版均原生使用 DNF,使您现在积累的熟悉度可以直接迁移。
对于在老旧基础设施上运行多项服务的团队,VPS 控制面板可以在迁移窗口期间显著简化并行环境的管理。
如果您的工作负载包含 Web 托管栈,迁移到现代发行版还能让您充分利用通过 Certbot 和 ACME 实现的SSL 证书自动化,该功能在 RHEL 8+ 及其衍生版本上的支持显著更好。
快速参考决策矩阵
在安装前后使用此清单,以确认设置干净且适合生产环境:
- [ ] `yum update -y` 在安装 EPEL 之前无错误完成
- [ ] 通过 `yum repolist | grep epel` 验证 EPEL 仓库处于活动状态
- [ ] `dnf –version` 返回有效的版本字符串
- [ ] `dnf repolist` 输出与 `yum repolist` 输出一致
- [ ] `/etc/dnf/dnf.conf` 已审查并针对您的环境进行调优
- [ ] `installonly_limit` 已设置以防止 `/boot` 分区溢出
- [ ] 已就别名、符号链接或共存策略做出决策
- [ ] 如使用符号链接方案,已备份 YUM 二进制文件
- [ ] 已审计 Cron 任务和自动化脚本中硬编码的 `yum` 路径
- [ ] 已记录 CentOS 7 EOL 迁移时间表
常见问题
DNF 和 YUM 能在同一 CentOS 7 系统上共存而不产生冲突吗?
可以。两个工具均从 `/etc/yum.repos.d/` 读取配置,并维护各自独立的缓存目录。它们共享 RPM 数据库(`/var/lib/rpm`),因此一个工具完成的事务对另一个工具立即可见。同时运行两者(例如两个并发安装)会导致 RPM 锁冲突,但顺序使用是完全安全的。
在 CentOS 7 上安装 DNF 会破坏现有的 YUM 插件吗?
不会。DNF 作为独立二进制文件安装,不会修改 YUM 安装。您现有的 YUM 插件保持完整。但是,DNF 不会加载 YUM 插件——如果您依赖特定的 YUM 插件,需要单独查找并安装其 DNF 等效项。
CentOS 7 上的 DNF 是否支持 DNF 模块(模块流)?
不支持。DNF 模块流是 DNF 4 和 RHEL/CentOS 8 中引入的功能。通过 EPEL 为 CentOS 7 提供的 DNF 版本为 DNF 4.x,但模块流支持需要 AppStream 仓库基础设施,而该基础设施在 CentOS 7 上不存在。
为何 `dnf update` 有时与同一系统上的 `yum update` 产生不同的结果?
DNF 的 `libsolv` 解析器应用更严格的依赖逻辑,可能与 YUM 的内部解析器在版本选择上有所不同。在大多数情况下结果是相同的,但在具有复杂或冲突依赖关系的环境中,DNF 可能会选择不同的软件包版本,或拒绝 YUM 会静默允许的事务。这是一个特性,而非缺陷——DNF 的行为更具可预测性和可审计性。
在托管生产 Web 应用程序的 CentOS 7 服务器上使用 DNF 安全吗?
安全,但需注意使用共存方案(保持 YUM 完整,显式使用 DNF),而非替换 YUM 二进制文件。在将主要工作流切换到 DNF 之前,请验证服务器上的任何控制面板软件或部署自动化工具是否对 YUM 行为存在硬编码假设。
