Rocky和AlmaLinux如何启用EPEL与CRB仓库
dnf 找不到软件包?了解 Rocky Linux 和 AlmaLinux 的 BaseOS、AppStream、CRB 内容,安全启用 EPEL,并避免第三方仓库覆盖基础系统。
为什么 dnf 找不到所需的软件包
EPEL 和 CRB 是全新 Rocky Linux 或 AlmaLinux 服务器默认不会提供的两个软件仓库。因此,在新服务器上运行 dnf install htop 时,会得到 No match for argument: htop,随后得到 Error: Unable to find a match: htop。系统没有故障,镜像站也没有宕机。基础发行版有意只提供少量软件包;CRB 已存在,但处于禁用状态;EPEL 则是需要手动添加的独立社区软件仓库。
在 Ubuntu 上,同一个软件包位于 universe 中,而 universe 几乎在所有云镜像中都已启用,因此通常不会遇到这个问题。Red Hat 系列以不同方式拆分软件包,默认提供的软件包更少。解决方法只需运行 3 条命令。本指南接下来会说明一些通常不会在第一周告诉你的内容:这些软件仓库能提供什么、不能保证什么,以及如何防止第三方软件仓库在不知不觉中接管基础系统。
这些命令的验证方式。我们的命令测试容器只运行 Ubuntu,因此下面的 dnf 命令没有在我们自己的测试机上执行。这些命令遵循 Rocky Linux 和 AlmaLinux 的文档。每一步都说明了应看到的输出,因此请在自己的服务器上逐步检查,不要一次性粘贴整个代码块。
什么是 BaseOS、AppStream 和 CRB?
BaseOS 就是操作系统本身:内核、glibc、systemd 和核心用户空间组件。这里的软件版本会在整个主版本生命周期内保持不变,安全修复会回移植到这些固定版本中。BaseOS 中看起来已有多年历史的版本号,并不表示软件包没有打补丁,而是表示它是一个已打补丁的旧版本。这正是企业级发行版的设计目标。
AppStream 包含运行在操作系统之上的组件:Web 服务器、数据库、语言运行时、编辑器和监控代理。在版本 8 中,AppStream 的很大一部分内容以带有备用流的模块形式提供,因此 dnf module list 很重要;例如,您需要选择一个 PHP 流。版本 9 几乎取消了所有模块化机制,因此在 Rocky 9 和 Alma 9 上,您通常会直接获得某个组件的一个版本,不需要先启用模块。
Extras 默认启用,内容很少。它主要提供其他仓库的发布软件包,epel-release 本身就是从这里获得的。因此,在 Rocky 或 Alma 上安装 EPEL 时,您不需要信任随机 URL。
CRB 是 CodeReady Builder 仓库,在版本 8 中称为 PowerTools。它包含发行版的构建组件:开发头文件、静态库,以及软件包在构建时所需的测试和文档工具。该仓库已存在于镜像中,但默认处于禁用状态。在 Red Hat 自有产品中,相同内容称为 CodeReady Linux Builder,随订阅提供;Red Hat 声明该仓库不在支持范围内。Rocky 和 Alma 同时继承了这些内容以及默认禁用的设置。
对于从 Debian 或 Ubuntu 转来的读者:main 会在同一个归档中同时提供运行时软件包和 -dev 头文件,因此那里不需要启用 CRB。与 EPEL 最接近的是 universe,它由社区维护,不提供厂商支持承诺。
EPEL 是什么,由谁维护
EPEL 代表 Extra Packages for Enterprise Linux。它是 Fedora 项目的一部分:将 Fedora 中已有的软件包针对当前企业版发行版重新构建,由 EPEL Special Interest Group 维护;该组织成员主要来自 Fedora 社区,多数是志愿者。Red Hat 提供构建和镜像基础设施,也有一些 Red Hat 工程师负责维护其中的软件包。双方的关系仅此而已。EPEL 不是 Red Hat 产品。 无论是在 RHEL 还是其重构发行版上,EPEL 软件包都不附带支持合同或 SLA(服务级别协议)。
一项策略使 EPEL 可以安全启用:EPEL 软件包绝不能替代基础发行版中的软件包。如果 AppStream 提供 nginx,EPEL 就不会提供。EPEL 软件包审核人员负责执行这项规则,因此它只代表 EPEL 的承诺。它无法保护您免受之后添加的其他软件源或软件包的影响。
EPEL 的生命周期承诺也不同于基础发行版,这一点通常会在第三年造成问题。BaseOS 软件包版本会在整个十年主版本生命周期内保持冻结。EPEL 维护者承诺的时间窗口要短得多:至少覆盖一个 RHEL 次要版本周期或 13 个月,以较短者为准。实际上,大多数软件包的维护时间远超这一期限。有些软件包会在维护者停止维护后退役;有些则会在您的发行版生命周期中途跳转到新的主版本,因为 EPEL 会跟随 Fedora。因此,一次常规的 dnf upgrade 可能会在您以为稳定的服务器上安装 EPEL 工具的新主版本,而您依赖的软件包也可能在没有通知送达您的情况下停止接收更新。新版本也不会自动应用到已经运行的服务中,因此事务完成后,needs-restarting 可用于告知您哪些进程仍在使用旧二进制文件。
启用 EPEL 前还应了解另一个后果:EPEL 针对最新的 RHEL 次要版本构建。如果您使用冻结镜像或供应商的特定版本软件源,将服务器固定在较旧的次要版本上,EPEL 软件包可能会要求使用比当前系统更新的基础库。dnf 会将其报告为缺少依赖项,看起来像是镜像问题,实际却是版本偏差问题。
启用 CRB 并在 Rocky 或 Alma 上安装 EPEL
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --set-enabled crb
sudo dnf install -y epel-release
sudo dnf makecache
dnf repolist --enableddnf repolist --enabled 现在应列出 baseos、appstream、extras、crb 和 epel。您还可能看到一个小型 epel-cisco-openh264 条目,这是由 epel-release 添加的。如果列表中缺少 crb,说明启用步骤未生效,下一节将解释原因。
在 Rocky 8 和 Alma 8 上,该仓库仍称为 PowerTools,因此中间的命令应改为 sudo dnf config-manager --set-enabled powertools。仓库 ID 区分大小写。较早的 CentOS 8 文档将其写作 PowerTools,包含大写字母,因此无法匹配。在 AlmaLinux 10 上,从 10.0 开始默认启用 CRB 仓库(于 September 2025 更改),因此您只需执行 epel-release 步骤。
epel-release 来自 extras,后者已启用,因此无需信任某个 URL,也无需手动导入密钥。该软件包会写入 /etc/yum.repos.d/epel.repo,并将 EPEL 签名密钥安装到 /etc/pki/rpm-gpg/ 下。在该文件中确认 gpgcheck=1,并忽略任何建议使用 --nogpgcheck 绕过签名错误的指南。签名检查失败表示软件包并非其声称的内容,或者系统时钟错误。
在 Rocky 上,epel-release 还会在 /usr/bin/crb 安装一个小型辅助工具,因此 sudo crb enable 和 crb status 无需插件即可完成相同工作。在依赖该工具前,使用 command -v crb 检查系统是否已安装,因为并非每个重构版本分支都提供它。
要确认 EPEL 可以访问,而不只是已列出,请让它查询一个只有该仓库提供的软件包:
dnf repoquery --repo=epel htop该命令会输出软件包名称、版本和架构。没有输出表示仓库已启用,但未返回任何内容。这通常是镜像或元数据问题,而不是配置问题,因此接下来尝试 sudo dnf clean all && sudo dnf makecache。
dnf 提示“没有此命令:config-manager”的原因
这是最先让人困惑的问题,而且恰好会出现在大多数 VPS 提供商提供的镜像中。
No such command: config-manager. Please use /usr/bin/dnf --help
It could be a DNF plugin command, try: "dnf install 'dnf-command(config-manager)'"config-manager 是插件,不是内置的 dnf 子命令。它包含在 dnf-plugins-core 中。完整的服务器安装会安装该软件包,但精简镜像、云镜像和容器镜像通常不会安装。dnf 自己给出的建议可以正常工作,因为该软件包声明了这一虚拟功能:
sudo dnf install -y 'dnf-command(config-manager)'请直接使用该命令。括号属于 shell 语法,因此不加引号的版本会因语法错误失败,而不是报告 dnf 错误。
如果所需的仓库正是被禁用的仓库,导致无法安装该插件,请直接编辑配置文件。找到包含该配置段的文件,打开它,然后在 [crb] 下设置 enabled=1:
grep -rl crb /etc/yum.repos.d/这正是 config-manager 写入的内容,因此手动设置不会遗漏任何配置。dnf repolist --enabled 可确认结果。
部分 EPEL 软件包必须先启用 CRB 才能安装
第二个常见问题不会在错误信息中直接提到 CRB。某个 EPEL 软件包依赖的库只在 CRB 中提供时,依赖解析会失败。错误信息会列出缺少的库,以及需要该库的软件包:
Error:
Problem: conflicting requests
- nothing provides libexample.so.0()(64bit) needed by examplepkg-1.4-2.el9.x86_64 from epel原因是 CRB 未启用,因此 dnf 找不到唯一提供该库的软件仓库。按顺序检查以下两项:
dnf repolist --enabled
dnf --enablerepo=crb repoquery --whatprovides 'libexample.so.0()(64bit)'如果第二条命令列出了某个软件包,而直接安装仍然失败,则说明 CRB 未启用。此类错误很常见,因此 AlmaLinux 在 version 10 中默认启用 CRB,专门避免此问题。--enablerepo=crb 也可以作为单次安装的临时选项使用。但只要使用 EPEL,就应永久启用 CRB,因为下一次 EPEL 更新可能引入新的 CRB 依赖,而且不会提前提示。
这个软件包来自哪个仓库?
启用 4 个仓库几周后,真正有用的问题就不再是安装了什么,而是这些软件包来自哪里。
dnf repolist --all
dnf info htop
dnf repoquery --installed --qf '%{from_repo} %{name}' | sort | uniq -c | sort -rn
dnf repository-packages epel list installed对已安装的软件包执行 dnf info 会输出一行 From repo。dnf list installed 会在第三列显示相同信息,并在前面加上 @。因此,@epel 表示该软件包来自 EPEL,@System 表示 dnf 不知道其来源。后者通常意味着有人对下载的文件执行了 rpm -i。repoquery 会按仓库统计软件包数量。这是发现继承的服务器中有 40 个软件包来自某个陌生仓库的最快方法。最后一条命令会准确列出某个仓库提供的软件包。在决定移除该仓库前,您需要先查看这份清单。
在 apt 中,与此对应的习惯是 apt-cache policy <package>。第一个月内,建议将dnf 和 apt 命令对照保持在第二个标签页中。两者的概念对应关系很清晰,但选项并不完全相同。
如何阻止第三方仓库替换基础软件包?
EPEL 承诺不会这样做。其他仓库都没有此承诺。数据库、代理或语言运行时的供应商仓库,可能会提供自己的库版本,而 BaseOS 也提供该库。dnf 仍会安装供应商版本,因为 dnf 的默认规则很简单:无论软件包来自哪个仓库,版本最高者优先。
两个控制项可以处理大多数情况,它们都位于 /etc/yum.repos.d/ 下的仓库文件中。
priority= 决定多个仓库提供同名软件包时由哪个仓库优先。数值越小,优先级越高;默认值为 99。因此,应为基础仓库设置较小的数值,为第三方仓库设置较大的数值。这样,即使第三方版本更新,dnf 仍会选择基础软件包。现代 dnf 会自行处理此问题,因此 CentOS 7 时代单独使用的 yum-plugin-priorities 软件包已不再属于解决方案。
includepkgs= 是更强的过滤选项。excludepkgs= 会阻止仓库提供指定名称的软件包,但这要求您预先判断该仓库可能提供哪些软件包。includepkgs= 则相反:该仓库只能提供指定名称的软件包,不能提供其他软件包。对于只应提供自有代理的供应商仓库,只需配置一行。
[vendor-tools]
name=Vendor tools for EL9
baseurl=https://packages.example.com/el9/x86_64/
enabled=1
gpgcheck=1
gpgkey=https://packages.example.com/RPM-GPG-KEY-vendor
priority=90
includepkgs=vendor-agent,vendor-agent-plugins在版本 8 中,还需要了解一个设置。如果 AppStream 模块提供同名软件包,第三方仓库中的软件包可能会被隐藏;在该仓库的配置段中,module_hotfixes=1 会告诉 dnf 停止过滤该软件包。如果软件包对 dnf repoquery 可见,但无法在版本 8 的系统上安装,通常就是这个原因。版本 9 几乎移除了所有模块,因此此问题在那里很少出现。
如需将一个软件包固定到指定版本,请安装 python3-dnf-plugin-versionlock 并使用 sudo dnf versionlock add <package>。这相当于 apt-mark hold。请注意一个容易误解的差异:从 Debian 转过来的用户通常会遇到这个问题。在 apt 中,较高的 Pin-Priority 优先;在 dnf 中,较低的 priority 优先。
混用 RHEL 相邻发行版的软件仓库会使服务器无法升级
Rocky、Alma、CentOS Stream、Oracle Linux 和 RHEL 足够接近,因此它们的软件包可以互相安装;但它们又存在足够差异,最终会形成一个没有任何人能够支持的系统。它们为何如此接近,以及为什么 Stream 如今位于 RHEL 之前而不是与其并列,详见Red Hat Linux 如何分裂为 Fedora 和 RHEL,以及 CentOS 后来的发展。
其机制在于版本号。CentOS Stream 9 的版本进度领先于 RHEL 9。因此,即使只将 Rocky 9 服务器指向 Stream 仓库一次,甚至只安装一个软件包,也会留下版本领先于 Rocky 后续所有版本的软件包。下一个 Rocky 次要版本发布后,其中该软件包的版本反而低于当前已安装版本,因此 dnf upgrade 不会处理它。此时系统运行的是一种未经任何人测试的软件包组合,而且会在你以为系统已完成修补的情况下,悄悄保持数年。
其表现是 dnf upgrade 报告没有可执行的操作,而 sudo dnf distro-sync 建议降级一长串软件包。distro-sync 是修复工具:它会强制所有已安装软件包与启用的软件仓库实际提供的版本保持一致,其中也包括降级。先禁用外部仓库,再运行该工具,并在确认前查看它列出的变更。若镜像中已不再提供旧版 RPM,修复就会失败。此时,使用干净镜像重建服务器,比继续处理依赖解析器更快、更安全。
ELevate 遗留项是这一问题的另一种常见形式。ELevate 是基于 Leapp 构建的 AlmaLinux 迁移工具,用于将 CentOS 7 服务器升级,或在不同重建发行版之间转换。迁移过程过于仓促时,/etc/yum.repos.d/ 中会残留 EL7 仓库文件,系统中也会继续安装 EL7 软件包。使用 rpm -qa | grep el7 查找这些软件包。每个软件包都无法由任何启用的软件仓库更新;之后再次运行 Leapp 时,它们会被报告为无法映射的软件包,进而成为需要手动清理的升级阻塞项。应在服务器运行平稳时清理这些遗留项,而不是等到需要进行下一次大版本升级的当天。
供应商仓库中的软件包覆盖了 AppStream 软件包,是同类问题中影响较轻的一种,前文的 includepkgs 命令就是解决方法。容器工具最常出现这种情况,因为 Docker 自有仓库中的 containerd.io 会与 AppStream 中的 runc 冲突,因此必须移除其中一个。确定方案后记录排除规则,并按已验证的顺序执行:在 Rocky Linux 上安装 Docker教程说明了应先移除哪些发行版软件包。
软件包仓库中的 apt 到 dnf 对照
/etc/apt/sources.list.d/*.sources对应/etc/yum.repos.d/*.repo,一个文件可以包含多个[sections],每个都有自己的 id。add-apt-repository universe对应dnf install epel-release,但universe仍属于 Ubuntu 自己的软件仓库,而 EPEL 是独立项目。apt update没有需要记住的对应项。dnf 会按自己的计划刷新元数据,dnf makecache可立即强制刷新。apt-cache policy <pkg>对应dnf info <pkg>,加上dnf list --showduplicates <pkg>可查看所有可用版本。apt-mark hold对应dnf versionlock add,来源为python3-dnf-plugin-versionlock。- 在
/etc/apt/preferences.d/中使用固定版本,对应仓库部分中的priority=,但编号方向相反。 dpkg -S /path/to/file对应rpm -qf /path/to/file。
自动更新需要理解其实现思路,而不是照搬语法,因为这里没有 unattended-upgrades。计时器、配置文件以及是否重启的问题,见Rocky 和 Alma 上的 dnf-automatic。
保持软件仓库列表简短
启用 CRB,安装 epel-release,然后记录所做的更改及其原因。可以写入配置管理系统,也可以记录在服务器上的普通文件中。服务器运行三年后,如果由其他人接手维护,这份记录的价值会比预想的更高。
添加软件仓库前先搜索。运行 dnf search,然后运行 dnf info,之后再考虑添加新仓库。人们启用 EPEL 的许多原因,其实 AppStream 已经可以满足。系统监控就是最明显的例子,因为 Performance Co-Pilot 已包含在基础软件仓库中,不需要任何第三方软件仓库。每增加一个软件仓库,就多了一个可能在某个周二向服务器提供软件包的外部方;软件仓库越多,下一次大版本升级就越困难。
如果您还在两种发行版之间进行选择,那么这套仓库布局在两者上完全相同,epel-release 的行为也一致。真正的差异在其他方面:Rocky Linux 与 AlmaLinux 的比较介绍了两者的重建理念,因为 AlmaLinux 现在以 ABI(应用程序二进制接口)兼容性为目标,而不是逐行重建。
FAQ
如何在 Rocky Linux 9 或 AlmaLinux 9 上启用 EPEL?
依次运行 sudo dnf install -y dnf-plugins-core、sudo dnf config-manager --set-enabled crb 和 sudo dnf install -y epel-release。使用 dnf repolist --enabled 确认,输出中应列出 baseos、appstream、extras、crb 和 epel。安装 EPEL 软件包前先启用 CRB,因为其中许多软件包依赖只有 CRB 提供的库。在版本 8 中,仓库 ID 是 powertools,而不是 crb。
在生产服务器上启用 EPEL 是否安全?
EPEL 使用广泛,并且遵循一项策略:EPEL 软件包不会替换基础发行版中的软件包。因此,启用 EPEL 不会改变 BaseOS 或 AppStream 提供的内容。需要注意的是支持问题:EPEL 是 Fedora 社区维护的项目,不提供服务级别协议;维护者对某个软件包的承诺期限可能只有一个 RHEL 次要版本周期或 13 个月。使用 dnf repository-packages epel list installed 保留软件包清单,并对客户可访问服务依赖的任何 EPEL 软件包使用 dnf versionlock。
为什么 dnf 提示 no such command: config-manager?
因为 config-manager 是 dnf 插件,而不是内置命令;精简镜像或容器镜像通常不包含 dnf-plugins-core。提示本身已经给出解决方法:sudo dnf install -y 'dnf-command(config-manager)'。其中的引号可防止 shell 将括号解释为特殊字符。如果暂时无法安装任何软件,请运行 grep -rl crb /etc/yum.repos.d/,打开它指定的文件,然后在 [crb] 部分手动设置 enabled=1。
CRB 和 PowerTools 有什么区别?
它们是同一个仓库的两个名称。版本 8 将其称为 PowerTools,ID 为 powertools;版本 9 及更高版本将其称为 CRB,ID 为 crb;Red Hat 自己的产品则将这些内容称为 CodeReady Linux Builder。该仓库提供开发头文件、静态库和构建时工具。在 Rocky 和 AlmaLinux 9 上默认禁用。AlmaLinux 10 从 10.0 起默认启用,因此在该版本上运行启用命令前,请先检查 dnf repolist --enabled。
如何再次移除 EPEL,同时避免破坏系统?
先使用 dnf repository-packages epel list installed 创建清单,因为单独移除 epel-release 软件包不会移除从 EPEL 安装的任何软件包。这些软件包仍会保留在磁盘上,但失去更新来源,并且不再获得安全修复;系统不会显示错误来提醒您。逐个评估软件包,移除或替换不再需要的软件包,然后再运行 sudo dnf remove epel-release。如果某个 EPEL 软件包没有替换任何其他软件包,并且确实必须移除,sudo dnf repository-packages epel remove 可在一个事务中清除这组软件包。因此,确认前请仔细阅读待执行操作列表。