尧图精选

RedHat 9 yum/dnf源配置全攻略:国内镜像与本地源搭建实践

🕒 发布时间:2026/10/1 4:31:25 📁 来源:尧图网络
装好 RedHat 9 之后执行第一条dnf install屏幕上直接刷出一片报错是我对这个版本印象最深的一件事。什么Failed to download metadata for repo appstream、Errors during downloading metadata连着几条看下来一度以为系统被我装坏了。后来才搞清楚问题不在系统而在源——RHEL 9 的官方仓库绕不开订阅国内直连官方源又慢又容易断不折腾一下几乎没法正常装软件。这篇就围绕 RedHat 9 的 yum/dnf 源配置把两条最常用的路线完整写一遍一是换成国内镜像源阿里云、清华 TUNA二是搭本地 yum 源ISO 挂载或自建 RPM 包目录。适合刚装完 RHEL 9 的新手也适合内网离线环境需要批量部署的老手。后面还附上我实际踩过的坑和排查思路照着操作基本能一次跑通。1. 为什么RedHat 9配源这么折腾订阅、dnf与repo文件基础1.1 订阅限制是第一个拦路虎RHEL 9 和 CentOS 7/8 时代不太一样。CentOS 7 可以直接用官方源因为它的仓库就是公开的RHEL 9 是商业发行版默认的 yum 源全部挂在 Red Hat 订阅体系下没有有效订阅时dnf repolist要么是空的要么报错说没有可用的仓库。也就是说你刚装完系统还没有用subscription-manager注册订阅那么官方仓库对你来说就是关闭的。就算你有 Red Hat 开发者订阅个人可以免费申请国内网络访问官方 CDN 的速度也谈不上多好经常出现下载到一半断流的情况。所以对绝大多数国内用户来说把源换掉是最务实的选择。这里有件事要说明白换源并不是破解订阅只是让 dnf 去读一个公开的、不要求订阅的仓库地址。CentOS Stream、Rocky Linux 的仓库都是公开的RHEL 9 与其版本号对应、包结构类似所以完全可以借用。这一点在后面的操作中会反复用到。1.2 dnf、yum与repo文件结构RHEL 9 里执行yum命令实际调用的就是 dnf。这个版本中yum是一个指向 dnf 的符号链接所以你在网上看到的各种yum install、dnf install写法在 RHEL 9 上基本通用没有本质区别。只是在看日志、查报错时可能会混着出现 yum 和 dnf 两个名字知道是同一个东西就行。dnf 的仓库配置放在/etc/yum.repos.d/目录下文件名必须以.repo结尾否则系统不认。一个典型的 repo 文件长这样[baseos] nameCentOS Stream $releasever - BaseOS baseurlhttps://mirrors.aliyun.com/centos-stream/9-stream/BaseOS/$basearch/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Stream-9各字段的含义先列个表方便查阅字段作用[baseos]仓库标识必须唯一dnf 报错时会引用这个名称name仓库描述信息给人看的baseurl仓库地址支持http://、https://、file://enabled是否启用该仓库1 启用0 禁用gpgcheck是否校验软件包 GPG 签名1 校验0 不校验gpgkeyGPG 公钥文件路径用于签名校验priority仓库优先级数字越小越优先需要插件支持baseurl和metalink、mirrorlist是三种不同的仓库地址机制。官方源通常用metalink或mirrorlist它们会动态返回一批镜像地址好处是自动调度坏处是在国内网络环境下经常解析出不可达的节点。我们自己配国内源时一般直接写死baseurl指到一个具体镜像路径简单粗暴且稳定。2. 网络源改造国内镜像源完整操作与repo模板2.1 操作前的备份与基础准备不管你要用哪个镜像站第一步都不是写配置文件而是先备份原仓库。这一步看起来多余实际非常重要——我见过太多人配完源之后想对比官方源写法结果发现/etc/yum.repos.d/已经被清空连恢复的余地都没有。备份操作很简单mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/执行完之后/etc/yum.repos.d/下除了 backup 目录应该没有任何.repo文件。这一步的目的是把可能存在的官方源和第三方源全部清掉避免它们干扰后面的配置。如果你的系统已经注册过订阅还可以顺手禁用一下官方仓库subscription-manager repos --disable*不过没注册的话这条命令会报错不用管它直接进入下一步。另外确认一下网络和 curl 可用curl -I https://mirrors.aliyun.com能返回 HTTP 头信息说明网络通。如果这一步都不通后面配置镜像源也没意义先检查 DNS 和网关。2.2 阿里云CentOS Stream源配置国内用户配置镜像源阿里云是绕不开的选项服务器在阿里云机房或者就近接入的话速度非常快。RHEL 9 用户最常用的方案是把源指向 CentOS Stream 9 的仓库。先解释一下为什么是 CentOS StreamRHEL 9 和 CentOS Stream 9 在版本号上对应仓库目录结构也比较接近各镜像站同步速度快最关键的是它不要求订阅可以直接访问。虽然 CentOS Stream 更偏向下一个 RHEL 版本的预览但在实际使用中把它作为 RHEL 9 的软件源并没有太大问题这是目前社区最普遍的做法。创建/etc/yum.repos.d/centos-stream.repo写入以下内容[baseos] nameCentOS Stream $releasever - BaseOS baseurlhttps://mirrors.aliyun.com/centos-stream/9-stream/BaseOS/$basearch/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Stream-9 [appstream] nameCentOS Stream $releasever - AppStream baseurlhttps://mirrors.aliyun.com/centos-stream/9-stream/AppStream/$basearch/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Stream-9这里有两个细节需要特别说明。第一是路径中的9-streamCentOS Stream 9 的镜像目录就叫这个名字如果你写baseurl.../centos-stream/9/BaseOS/...大概率会碰到 404因为目录不存在。第二是 gpgkey 指向的/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Stream-9这个文件不一定存在。我用清华的源时遇到过类似问题处理方式是手动下载公钥到本机或者临时把 gpgcheck 改成 0 先跑通后面专门讲。2.3 更贴近RHEL的替代Rocky Linux源用 CentOS Stream 虽然能跑通但如果你在意和 RHEL 9 的二进制兼容性Rocky Linux 9 的源其实是更稳的选择。Rocky Linux 是 RHEL 的下游重建版本从内核到软件包都是直接基于 RHEL 9 的源码重新构建的所以用它做 RHEL 9 的源依赖兼容性通常比 CentOS Stream 更贴合。我自己的生产服务器目前就是这个方案跑了大半年没有遇到过依赖冲突的问题。创建/etc/yum.repos.d/rocky.repo[rocky-baseos] nameRocky Linux $releasever - BaseOS baseurlhttps://mirrors.aliyun.com/rockylinux/9/BaseOS/$basearch/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 [rocky-appstream] nameRocky Linux $releasever - AppStream baseurlhttps://mirrors.aliyun.com/rockylinux/9/AppStream/$basearch/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 [rocky-extras] nameRocky Linux $releasever - Extras baseurlhttps://mirrors.aliyun.com/rockylinux/9/extras/$basearch/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9Rocky Linux 仓库的路径规则比 CentOS Stream 好理解直接就是9/BaseOS、9/AppStream这样不需要写9-stream。用清华源的话把mirrors.aliyun.com替换成mirrors.tuna.tsinghua.edu.cn即可路径结构保持一样。清华源在国内高校和教育网环境里速度不错。2.4 EPEL扩展源很多软件唯一的出路RHEL 9 自带的 BaseOS 和 AppStream 仓库收录的软件有限很多常用的、更新较快的软件包比如 nginx、htop、ffmpeg 等都在 EPEL 仓库里。EPEL 全称 Extra Packages for Enterprise Linux是 Fedora 社区针对 RHEL/CentOS 维护的扩展软件包仓库RHEL 9 可以直接使用。正常情况下安装 EPEL 的姿势是dnf install -y epel-release但 RHEL 9 默认仓库里没有这个包所以需要手动创建 EPEL 的 repo 文件。创建/etc/yum.repos.d/epel.repo[epel] nameEPEL $releasever baseurlhttps://mirrors.aliyun.com/epel/9/Everything/$basearch/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9 [epel-next] nameEPEL Next $releasever baseurlhttps://mirrors.aliyun.com/epel/next/9/Everything/$basearch/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-Next-9EPEL 的公钥文件同样需要手动处理。最简单的办法是从阿里云下载并导入rpm --import https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-9之后再执行dnf makecacheEPEL 仓库就能正常识别了。EPEL 和 BaseOS、AppStream 的区别在于它是个附加仓库基础软件包仍然优先从 BaseOS/AppStream 装EPEL 负责补缺。混合使用时如果出现软件包冲突优先检查是否同时启用了多个来源不同的仓库。3. 本地yum源搭建ISO挂载与createrepo离线方案3.1 挂载RHEL 9 ISO并设置开机自动挂载内网环境、无外网机器、或者外网带宽非常捉急的场景下本地 yum 源是唯一靠谱的出路。本地源的思想很简单让 dnf 把一个本地目录当作仓库目录里有软件包和对应的元数据repodatadnf 就能正常安装软件。最常见的本地源材料是 RHEL 9 的 DVD ISO。去官网或者镜像站下载rhel-baseos-9.x-x86_64-dvd.iso上传到服务器比如放在/data/iso/然后挂载到指定目录mkdir -p /mnt/rhel9 mount -o loop /data/iso/rhel-baseos-9.2-x86_64-dvd.iso /mnt/rhel9-o loop是 loop 设备挂载适合 ISO 这种单文件镜像不传会直接报错。挂载成功后/mnt/rhel9下应该能看到BaseOS、AppStream等目录。重启之后挂载会失效需要在/etc/fstab里加一条记录/data/iso/rhel-baseos-9.2-x86_64-dvd.iso /mnt/rhel9 iso9660 loop,ro 0 0加完之后mount -a测试一下不报错说明配置正确。ro表示只读ISO 挂载本来就只读写明这个选项可以避免某些场景下的异常行为。3.2 配置指向ISO挂载点的repo文件ISO 挂载点里BaseOS和AppStream目录本身自带repodata目录也就是说不需要任何额外的元数据生成操作直接写 repo 文件指向它们就行。创建/etc/yum.repos.d/local.repo[local-baseos] nameRHEL 9 Local BaseOS baseurlfile:///mnt/rhel9/BaseOS enabled1 gpgcheck0 [local-appstream] nameRHEL 9 Local AppStream baseurlfile:///mnt/rhel9/AppStream enabled1 gpgcheck0这里我把gpgcheck设成了 0。原因有两个一是 ISO 自带的 RPM-GPG-KEY 文件在RPM-GPG-KEY-redhat-release里直接配置 gpgkey 指向有时会因为路径问题导致校验失败二是本地源是你自己的介质可信度相对高关了签名校验问题不大。如果你有强迫症可以把 gpgcheck 改成 1并同时配置 gpgkey 指向/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release但这个文件在未注册订阅的 RHEL 9 上不一定存在。写完之后执行dnf clean all dnf makecache如果makecache没有报错本地源基本就通了。3.3 自建RPM包目录源createrepo_c实战不是每个人都有 DVD ISO。还有一种常见场景内网服务器需要部署某个软件及其依赖你希望把所有 RPM 包下载下来放到一个目录里做成一个本地的 yum 源然后分发给内网的其他机器。这个时候就需要createrepo_c出场了。这个工具的作用就是扫描一个目录下的所有 RPM 包生成repodata元数据让这个普通目录变成合法的 yum 仓库。首先安装 createrepo_c这步需要你的源至少能装基础包dnf install -y createrepo_c然后创建仓库目录把 RPM 包放进去mkdir -p /data/rpm-repo/Packages cp /tmp/xxx.rpm /data/rpm-repo/Packages/最后生成元数据createrepo_c /data/rpm-repo执行完成后/data/rpm-repo/repodata/目录出现就是一个可用的本地源了。repo 文件这样写[custom-repo] nameCustom Local RPM Repo baseurlfile:///data/rpm-repo enabled1 gpgcheck0如果你的服务器能上网还有一个更省事的下载方法用dnf repotrack把某个包及其所有依赖一次性拉下来dnf install -y dnf-plugins-core dnf repotrack -p /data/rpm-repo/Packages httpd这条命令会把httpd以及它依赖的所有 RPM 包下载到指定目录然后再createrepo_c /data/rpm-repo生成元数据一个包含完整依赖链的本地源就建好了。3.4 本地源与网络源混用的优先级控制实际运维中纯离线不现实因为软件包总在更新本地源的内容是静态的。比较合理的做法是本地源作为默认优先保证常用基础包安装快、不依赖外网网络源作为补充装新软件时能拿到最新版本。这时需要给仓库设置优先级。dnf 的 priority 功能由dnf-plugins-core提供检查一下是否安装dnf install -y dnf-plugins-core然后在 repo 文件里加上priority字段数字越小优先级越高[local-baseos] nameRHEL 9 Local BaseOS baseurlfile:///mnt/rhel9/BaseOS enabled1 gpgcheck0 priority1 [epel] nameEPEL $releasever baseurlhttps://mirrors.aliyun.com/epel/9/Everything/$basearch/ enabled1 gpgcheck1 priority99这样 dnf 会优先从本地源拉包只有本地源没有的包才去网络源找。需要注意priority 插件只在仓库间包名重复时有意义不同仓库提供不同包时优先级不会影响安装结果。4. 高频报错排雷metadata、变量展开与GPG密钥问题4.1 下载元数据失败先判断是路径问题还是网络问题配源时遇到最多的一条报错就是Errors during downloading metadata for repository baseos - Status: 404 Not Found或者Failed to download metadata for repo appstream这种报错有两种常见原因仓库路径不存在或者网络访问不了。排查思路很简单直接用 curl 看目标地址的 repomd.xml 能不能返回 200curl -I https://mirrors.aliyun.com/centos-stream/9-stream/BaseOS/x86_64/os/repodata/repomd.xml如果返回HTTP/1.1 200 OK说明路径和网络都正常问题出在 repo 文件的变量展开上如果返回 404说明路径写错了去镜像站目录页面核实一下实际的目录结构如果 curl 本身超时或者连不上那先解决网络问题再说。这个排查步骤看起来很简单但能直接过滤掉大半的问题。我见过有人在群里求助半天最后发现是$releasever展开后路径不对连 curl 都没试过。4.2 $releasever和$basearch到底展开成了什么$releasever这个变量在 RHEL 9 里一般会展开为大版本号9但 CentOS Stream 9 的仓库路径里用的是9-stream两者对不上。比如你写baseurlhttps://mirrors.aliyun.com/centos-stream/$releasever/BaseOS/$basearch/os/实际会变成.../centos-stream/9/BaseOS/...但这个路径在镜像站里不存在正确的应该是.../centos-stream/9-stream/BaseOS/...。所以在配置 CentOS Stream 源时我的建议是在路径里写死9-stream不要依赖变量展开。$basearch则比较稳定标准写法即可它会自动展开为x86_64或aarch64。还有一个容易踩的坑是你在 shell 里执行echo $releasever会提示变量为空因为这个变量是 dnf 内部解析的与 shell 无关。要确认变量展开后的路径怎么拼接直接用刚才的 curl 命令逐级去测。4.3 GPG公钥不存在与签名校验报错长这样The downloaded RPM was not signed or the public key is not available Public key for xxx.rpm is not installed这表示 gpgcheck1但 dnf 找不到对应的公钥。解决办法有两个一是核对 repo 文件里的 gpgkey 指向是否正确。比如 CentOS Stream 的公钥文件名是RPM-GPG-KEY-CentOS-Stream-9Rocky Linux 是RPM-GPG-KEY-Rocky-9写错文件名自然找不到。二是直接导入公钥文件。从镜像站拉公钥到本地再导入rpm --import https://mirrors.aliyun.com/rockylinux/RPM-GPG-KEY-Rocky-9导入成功后repo 文件里的 gpgkey 其实可以留空签名校验会使用 rpm 数据库里已有的公钥。需要提醒的是虽然把 gpgcheck 改成 0 可以绕过签名问题但我不建议在公网源上这么干。签名校验的意义在于防止仓库被劫持时安装到被篡改的恶意包。本地 ISO 源、内网自建源这种可信环境可以关镜像源还是尽量保持校验。4.4 SSL证书与代理导致的连接异常有时候 curl 测试返回的是curl: (60) SSL certificate problem: unable to get local issuer certificate这通常不是镜像站本身的问题而是你所在的网络环境存在中间设备比如公司出口代理、上网行为管理设备拦截了 HTTPS 连接或者系统时间不对导致证书链校验失败。先检查系统时间date如果时间偏差超过几分钟先同步时间dnf install -y chrony systemctl enable --now chronyd时间没问题的情况下如果只是少数内网场景的兼容性问题可以临时在 repo 里加一行sslverify0绕过证书校验但这么做有安全风险只建议临时排查用不建议长期保留。更稳妥的做法是配置代理[main] proxyhttp://your-proxy:port写在/etc/yum.conf的[main]段下dnf 的所有请求都会走代理。5. 配置完成后的验证与日常维护5.1 三步验证法配置写完、报错排完最后一定要做完整验证不要只看 makecache 不报错就结束了。我习惯按三步走。第一步查看仓库列表。dnf repolist输出里应该能看到你配置的所有仓库左边是仓库 ID右边是包数量。如果没有输出或者包数量是 0说明仓库没生效回看第 4 章的排查。第二步重新生成缓存。dnf clean all dnf makecachemakecache 会实际去访问每个仓库的 repomd.xml 并下载元数据这一步能过滤掉大部分路径和密钥问题。注意看输出的最后一行类似Metadata cache created才说明全部仓库都成功。第三步实测安装一个包。dnf install -y vim选 vim 是因为它是基础包体积小任何仓库里都有如果连它都能装上说明源的基本功能没有问题。想进一步测 AppStream 仓库可以装dnf install -y nginx试试。5.2 模块化stream的坑与处理RHEL 9 的 AppStream 仓库引入了模块化module streams机制同一个软件可能提供多个版本比如 nodejs 有 18、20、22 等多个模块流默认启用的是其中一个。换源之后如果模块数据异常dnf install nodejs可能会提示找不到包或者版本不符。排查方法dnf module list nodejs如果模块列表为空说明 AppStream 仓库的元数据有问题重新执行dnf clean all dnf makecache。如果能看到模块列表切换版本的操作是dnf module reset nodejs -y dnf module enable nodejs:20 -y dnf install -y nodejs模块化机制是 RHEL 9 的一个重要变化习惯了 CentOS 7 那种一个包一个版本的老用户在这个环节容易困惑。实际上你只需要记住先module list看有哪些版本再module enable选一个其他交给 dnf 就行。5.3 几个日常维护技巧源配好之后不是一劳永逸的几个维护细节值得注意。第一不要每次装软件都手动 makecache可以让 dnf 在需要时自动同步元数据。/etc/dnf/dnf.conf里默认的metadata_expire是 48 小时如果你希望元数据更新更频繁把它改成metadata_expire3600单位是秒即可。第二内核更新要留个心眼。生产服务器上执行dnf update -y会把内核也一起升级默认新的内核版本会导致重启后无法进入旧系统如果新内核有兼容性问题会比较被动。更稳妥的做法是跳过内核更新dnf update -y --excludekernel*需要升级内核时手动去掉--exclude参数再单独执行一次。第三安装软件前先看来源。用dnf info 包名查看输出里的Repository字段确认这个包是来自 BaseOS、AppStream 还是 EPEL。如果同一个包在多个仓库都有可以指定仓库安装dnf install -y --enablerepoepel 包名避免从错误的仓库装到不合适的版本。另外说一个实际经验本地源和网络源混用时建议定期刷新本地源内容。比如 ISO 挂载的源里面软件版本是固定的并不会随着系统更新而变化。内网有条件的团队通常会用一台机器每天定时从外网同步 rpm 包到本地目录再createrepo_c刷新元数据这样既快又能保持相对新的版本。配源这件事本质上就是让 dnf 知道该去哪里找包。路径写对密钥配好剩下的就交给它了。按照这篇文章的步骤来无论是国内镜像源还是完全离线的本地源都能在 RHEL 9 上稳定跑起来。如果你配置过程中碰到本文没覆盖的报错优先回去检查那三条仓库路径是否存在、变量是否展开正确、GPG 公钥是否导入大部分问题都出在这三个环节里。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →