一、CentOS 系包管理器体系架构全景
CentOS/RHEL/Fedora 采用 RPM(Red Hat Package Manager) 作为底层包格式,上层通过 yum(传统)或 dnf(现代)进行依赖解析和仓库管理。这是企业级 Linux 中最成熟的包管理生态之一。

核心层级
| 层级 | 工具 | 职责 |
|---|---|---|
| 用户层 | dnf |
现代包管理器(CentOS 8+/RHEL 8+/Fedora 22+) |
| 兼容层 | yum |
传统包管理器(CentOS 7 及之前),在 CentOS 8+ 中作为 dnf 的兼容别名 |
| 辅助层 | yum-utils / dnf-utils |
仓库查询、包下载等辅助工具 |
| 构建层 | createrepo / rpmbuild |
生成仓库索引、构建 RPM 包 |
| 依赖解析 | libsolv / hawkey |
DNF 的依赖求解引擎(基于 SAT 问题求解) |
| 底层 | rpm |
直接操作 .rpm 文件,无自动依赖解析 |
| 包格式 | .rpm |
cpio 归档 + 元数据,支持 GPG 签名 |
关键洞察 :与 APT 的
dpkg类似,rpm是底层工具,不自动解决依赖;dnf/yum是上层工具,负责从仓库下载依赖并调用rpm执行实际安装。DNF 使用libsolv库进行依赖求解,这是它比 YUM 更快、更可靠的核心原因。
二、DNF 命令详解(现代首选)
CentOS 8、RHEL 8、Fedora 22+ 的默认包管理器。DNF(Dandified YUM)使用 C/C++ 核心 + Python 接口,比纯 Python 的 YUM 性能更好、内存占用更低。

2.1 同步与升级
dnf update --- 更新包数据库
bash
sudo dnf update
sudo dnf check-update # 仅检查,不执行升级
sudo dnf update --refresh # 强制刷新缓存后检查
原理 :从 /etc/yum.repos.d/ 中配置的仓库下载 repodata(仓库元数据),更新本地缓存。
dnf upgrade --- 升级已安装包
bash
sudo dnf upgrade # 升级所有可升级包
sudo dnf upgrade nginx # 升级指定包
sudo dnf upgrade --refresh # 刷新缓存后升级
sudo dnf upgrade --exclude=kernel* # 排除特定包
与
dnf update的区别 :在 DNF 中,update和upgrade是等效命令 (YUM 中略有差异)。update是upgrade的别名。
dnf distro-sync --- 发行版同步
bash
sudo dnf distro-sync # 将系统同步到仓库当前状态
危险但强大 :此命令会降级包(如果仓库版本低于本地),确保系统与仓库完全一致。用于修复版本漂移或回滚测试。
2.2 安装操作
dnf install --- 安装软件
bash
sudo dnf install nginx
sudo dnf install -y nginx # 自动确认
sudo dnf install nginx-1.20.0 # 安装指定版本
sudo dnf install @nginx # 安装模块流(Modular Stream)
sudo dnf install ./package.rpm # 安装本地 RPM 文件
依赖解析流程:
- 读取仓库
repodata中的primary.xml/filelists.xml libsolv计算依赖闭包(SAT 求解)- 下载所有 RPM 到
/var/cache/dnf/ - 调用
rpm事务安装(支持事务回滚)
dnf reinstall --- 重新安装
bash
sudo dnf reinstall nginx # 修复损坏的安装
dnf downgrade --- 降级包
bash
sudo dnf downgrade nginx # 降级到仓库中的前一个版本
2.3 卸载操作
dnf remove / dnf erase --- 卸载
bash
sudo dnf remove nginx # 卸载包
sudo dnf erase nginx # erase 是 remove 的别名
sudo dnf remove --noautoremove nginx # 不删除依赖
dnf autoremove --- 清理孤儿包
bash
sudo dnf autoremove # 删除不再需要的依赖
sudo dnf autoremove -y # 自动确认
"孤儿包"判定:DNF 追踪每个包的安装原因。如果某包不再被任何显式安装的包依赖,则标记为可删除。
2.4 查询操作
dnf search --- 搜索包
bash
dnf search nginx # 搜索包名和描述
dnf search --all nginx # 搜索所有字段
dnf info --- 显示详情
bash
dnf info nginx # 显示仓库包详情
dnf info --installed nginx # 仅显示已安装版本
dnf repoquery --- 仓库查询(超级强大)
bash
dnf repoquery -l nginx # 列出仓库包的所有文件(无需安装!)
dnf repoquery --requires nginx # 显示依赖
dnf repoquery --whatprovides '*/nginx.conf' # 哪个包提供此文件
dnf repoquery --tree nginx # 显示依赖树
dnf provides --- 查询提供者
bash
dnf provides /usr/sbin/nginx # 哪个包提供此文件
dnf provides '*/nginx.conf' # 通配符搜索
2.5 事务历史(DNF 杀手功能)
DNF 的 history 是其他包管理器难以企及的优势。
bash
sudo dnf history # 显示所有事务历史
sudo dnf history info 5 # 查看第 5 号事务详情
sudo dnf history undo 5 # 撤销第 5 号事务(回滚!)
sudo dnf history redo 5 # 重做第 5 号事务
sudo dnf history rollback 5 # 回滚到第 5 号事务之前的状态
事务数据库位置 :/var/lib/dnf/history/(SQLite 格式)
2.6 缓存管理
bash
sudo dnf clean all # 清理所有缓存
sudo dnf makecache # 预生成缓存
sudo dnf clean packages # 仅清理下载的 RPM
sudo dnf clean metadata # 仅清理仓库元数据
三、YUM 命令详解(传统兼容)
CentOS 7 及之前的默认工具。在 CentOS 8+ 中,yum 命令被映射到 dnf,但保留独立配置。
3.1 YUM 与 DNF 的核心差异
| 特性 | YUM | DNF |
|---|---|---|
| 开发语言 | Python(56k+ 行代码) | C/C++ + Python(29k 行代码) |
| 依赖解析 | 自研解析器 | libsolv(SAT 求解) |
| 性能 | 较慢,内存占用高 | 更快,内存占用低 |
| API | 文档不完善 | 完善的 Python API |
| 事务历史 | 基础 | 完整(支持 undo/rollback) |
| 插件 | Python 插件 | 更紧密的插件架构 |
| 并行下载 | 不支持 | 支持 |
| 自动 Bug 报告 | 无 | 有 |
3.2 YUM 常用命令(与 DNF 基本一致)
bash
sudo yum update
sudo yum install nginx
sudo yum remove nginx
sudo yum search nginx
sudo yum info nginx
sudo yum clean all
sudo yum repolist
3.3 YUM 特有工具(yum-utils)
bash
sudo yum install yum-utils
# 下载 RPM 不安装
yumdownloader nginx
yumdownloader --resolve nginx # 下载含依赖
# 查询仓库文件
repoquery -l nginx
repoquery --requires nginx
# 查看变更日志
yum changelog nginx
# 验证包
yum verify nginx
四、RPM 底层命令详解
当 DNF/YUM 无法解决问题时(如强制安装、查询文件归属、验证完整性),需要直接使用 rpm。
4.1 安装与卸载
bash
# 安装本地 RPM(不解决依赖!)
sudo rpm -ivh package.rpm
sudo rpm -ivh --nodeps package.rpm # 忽略依赖(危险)
sudo rpm -ivh --force package.rpm # 强制安装(覆盖)
sudo rpm -ivh --test package.rpm # 测试模式(不实际安装)
# 升级
sudo rpm -Uvh package.rpm # 升级或安装
sudo rpm -Fvh package.rpm # 仅升级已安装的(freshen)
# 卸载
sudo rpm -e nginx # 卸载
sudo rpm -e --nodeps nginx # 忽略依赖卸载(危险)
sudo rpm -e --allmatches nginx # 卸载所有匹配版本
标志解释 :-i = install, -v = verbose, -h = hash 进度条, -U = upgrade, -F = freshen, -e = erase
4.2 查询命令(RPM 最强大的功能)
bash
# 列出所有已安装包
rpm -qa
rpm -qa | grep nginx
# 查询包是否安装
rpm -q nginx
# 显示包详情
rpm -qi nginx # 已安装包
rpm -qpi package.rpm # 未安装包(加 -p)
# 列出包文件
rpm -ql nginx # 已安装
rpm -qpl package.rpm # 未安装
# 查询文件归属(超级实用!)
rpm -qf /usr/sbin/nginx
rpm -qf $(which nginx)
# 显示依赖
rpm -qR nginx # 已安装
rpm -qpR package.rpm # 未安装
# 显示配置文件
rpm -qc nginx
# 显示文档
rpm -qd nginx
# 显示脚本
rpm -q --scripts nginx # 安装/卸载脚本
4.3 验证与校验
bash
# 验证已安装包的文件完整性
rpm -V nginx
rpm -Va # 验证所有包
# 导入 GPG 公钥
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-*
# 检查签名
rpm -K package.rpm # 验证包签名
rpm -K --nosignature package.rpm # 忽略签名
-V 输出解释:
S.5....T. c /etc/nginx/nginx.conf
S= Size 改变M= Mode(权限)改变5= MD5 校验失败D= Device 改变L= Link 改变U= User 改变G= Group 改变T= mTime 改变c= 配置文件(预期可能改变)
4.4 数据库维护
bash
# 重建 RPM 数据库(损坏时修复)
sudo rpm --rebuilddb
# 初始化数据库
sudo rpm --initdb
# 数据库位置
/var/lib/rpm/
五、仓库配置详解
5.1 /etc/yum.repos.d/ 仓库文件格式
ini
# /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
关键字段:
| 字段 | 说明 |
|---|---|
name |
仓库描述 |
baseurl |
仓库 URL(支持 http://, https://, ftp://, file://) |
mirrorlist |
镜像列表 URL(与 baseurl 二选一) |
enabled |
1 = 启用, 0 = 禁用 |
gpgcheck |
1 = 验证 GPG 签名 |
gpgkey |
GPG 公钥 URL |
exclude |
排除特定包 |
includepkgs |
仅包含特定包 |
5.2 常用仓库变量
| 变量 | 替换值 |
|---|---|
$releasever |
发行版版本(如 8, 9) |
$basearch |
基础架构(如 x86_64, aarch64) |
$arch |
完整架构(如 x86_64) |
5.3 EPEL 仓库(企业级必备)
EPEL(Extra Packages for Enterprise Linux)是 RHEL/CentOS 的官方扩展仓库。
bash
# CentOS 8/9
sudo dnf install epel-release
# CentOS 7
sudo yum install epel-release
# 启用 EPEL 后搜索
sudo dnf --enablerepo=epel search htop
5.4 模块流(Modular Stream)
RHEL 8+/CentOS Stream 引入的模块化系统,允许同一软件多版本共存。
bash
dnf module list # 列出所有模块
dnf module list nodejs # 列出 nodejs 的可用流
dnf module enable nodejs:18 # 启用 nodejs 18 流
dnf module install nodejs:18 # 安装模块流
dnf module switch-to nodejs:20 # 切换版本
dnf module reset nodejs # 重置为默认
六、实用技巧与故障排查
6.1 一键系统维护脚本
bash
#!/bin/bash
# centos-maintenance.sh
set -e
echo "=== 更新包数据库 ==="
sudo dnf update
echo "=== 升级系统 ==="
sudo dnf upgrade -y
echo "=== 清理孤儿包 ==="
sudo dnf autoremove -y
echo "=== 清理缓存 ==="
sudo dnf clean all
echo "=== 验证包完整性 ==="
sudo rpm -Va || true
echo "=== 系统维护完成 ==="
6.2 常见故障排查
错误 1:Failed to download metadata for repo
bash
# 清理缓存并重建
sudo dnf clean all
sudo dnf makecache
# 检查网络/DNS
curl -I http://mirror.centos.org
# 禁用问题仓库临时安装
sudo dnf --disablerepo=problem-repo install package
错误 2:GPG key retrieval failed
bash
# 手动导入公钥
sudo rpm --import https://example.com/RPM-GPG-KEY-example
# 或临时禁用 GPG 检查(不推荐长期使用)
sudo dnf install --nogpgcheck package.rpm
错误 3:rpmdb: damaged header instance
bash
# RPM 数据库损坏
sudo rm -f /var/lib/rpm/__db* # 删除锁文件
sudo rpm --rebuilddb # 重建数据库
sudo dnf clean all
sudo dnf update
错误 4:依赖冲突 / 损坏包
bash
# 查看具体冲突
sudo dnf repoquery --conflicts package
# 强制重新安装修复
sudo dnf reinstall package
# 使用 rpm 强制操作(最后手段)
sudo rpm -e --nodeps --allmatches broken-package
sudo dnf install broken-package
错误 5:事务历史回滚
bash
# 查看最近事务
sudo dnf history
# 回滚到特定事务之前
sudo dnf history rollback N
# 撤销特定事务
sudo dnf history undo N
6.3 下载与离线安装
bash
# 下载 RPM 及依赖(不安装)
sudo dnf install --downloadonly --downloaddir=/tmp/nginx nginx
sudo dnf download --resolve nginx
# 离线安装
sudo rpm -ivh /tmp/nginx/*.rpm
# 或
sudo dnf install /tmp/nginx/*.rpm
七、RPM 包构建(rpmbuild)
7.1 构建环境准备
bash
sudo dnf install rpm-build rpmdevtools rpmlint
rpmdev-setuptree # 创建 ~/rpmbuild 目录结构
7.2 SPEC 文件示例
spec
# ~/rpmbuild/SPECS/example.spec
Name: example
Version: 1.0.0
Release: 1%{?dist}
Summary: An example package
License: MIT
URL: https://example.com
Source0: %{name}-%{version}.tar.gz
BuildRequires: gcc
Requires: glibc
%description
An example package for demonstration.
%prep
%autosetup
%build
%configure
make %{?_smp_mflags}
%install
make install DESTDIR=%{buildroot}
%files
%license LICENSE
%doc README.md
/usr/bin/example
%changelog
* Mon Jan 01 2024 Builder <builder@example.com> - 1.0.0-1
- Initial package
7.3 构建命令
bash
rpmbuild -ba SPECS/example.spec # 构建二进制 + 源码包
rpmbuild -bb SPECS/example.spec # 仅构建二进制包
rpmbuild -bs SPECS/example.spec # 仅构建源码包
rpmbuild -bi SPECS/example.spec # 安装到 buildroot(测试)
# 使用 mock 在干净环境中构建
sudo dnf install mock
mock -r epel-9-x86_64 rebuild SRPMS/example-1.0.0-1.src.rpm
八、DNF vs YUM vs APT vs apk:企业级对比
| 维度 | DNF/YUM(CentOS/RHEL) | APT(Debian/Ubuntu) | apk(Alpine) |
|---|---|---|---|
| 设计目标 | 企业级稳定、长期支持 | 生态丰富、社区活跃 | 容器最小化 |
| 底层格式 | .rpm(cpio + 元数据) |
.deb(ar + tar) |
.apk(tar.gz) |
| 依赖解析 | libsolv(SAT 求解) |
apt 自研求解器 |
简单直接 |
| 事务历史 | 完整(支持回滚) | 基础(dpkg 日志) | 无 |
| 模块多版本 | 支持(Module Stream) | 有限(Pinning) | 不支持 |
| 缓存管理 | /var/cache/dnf/ |
/var/cache/apt/ |
/var/cache/apk/ |
| 配置文件处理 | .rpmnew / .rpmsave |
.dpkg-dist / 交互式 |
直接覆盖 |
| 企业支持 | RHEL 官方商业支持 | Canonical(Ubuntu Pro) | 社区 |
| SELinux 集成 | 原生支持 | 需额外配置 | 不支持 |
九、命令速查表
| 任务 | DNF 命令 | YUM 命令 | RPM 命令 |
|---|---|---|---|
| 更新数据库 | dnf update |
yum update |
--- |
| 升级系统 | dnf upgrade |
yum upgrade |
--- |
| 安装 | dnf install pkg |
yum install pkg |
rpm -ivh pkg.rpm |
| 本地安装 | dnf install ./pkg.rpm |
yum localinstall pkg.rpm |
rpm -ivh pkg.rpm |
| 重新安装 | dnf reinstall pkg |
yum reinstall pkg |
--- |
| 降级 | dnf downgrade pkg |
yum downgrade pkg |
--- |
| 卸载 | dnf remove pkg |
yum remove pkg |
rpm -e pkg |
| 清理孤儿包 | dnf autoremove |
yum autoremove |
--- |
| 搜索 | dnf search str |
yum search str |
--- |
| 详情 | dnf info pkg |
yum info pkg |
rpm -qi pkg |
| 列出文件 | dnf repoquery -l pkg |
repoquery -l pkg |
rpm -ql pkg |
| 文件归属 | dnf provides /path |
yum provides /path |
rpm -qf /path |
| 依赖树 | dnf repoquery --tree pkg |
--- | rpm -qR pkg |
| 事务历史 | dnf history |
yum history |
--- |
| 事务回滚 | dnf history undo N |
yum history undo N |
--- |
| 清理缓存 | dnf clean all |
yum clean all |
--- |
| 验证完整性 | --- | --- | rpm -V pkg |
| 重建数据库 | --- | --- | rpm --rebuilddb |
十、总结
CentOS/RHEL 系的包管理器设计遵循**"稳定优先、企业就绪"的哲学:DNF 的 history undo 提供了其他发行版难以企及的 事务回滚能力**,Module Stream 解决了企业环境中多版本共存 的难题,而 RPM 的 verify 机制确保了文件完整性审计。
掌握 dnf 的日常操作、rpm 的底层查询和 history 的事务回滚,是管理企业级 RHEL/CentOS 系统的核心能力。