1. 为什么 CentOS Stream 9 一定要换 yum 源聊这个标题之前我先说个场景。前阵子帮朋友在一台新装好的 CentOS Stream 9 上部署环境dnf install nginx敲下去光标就卡在那里转圈转了半天最后报了个连接超时。那个节点部署在内网机房出口带宽本身就不宽裕官方源服务器又远在海外每次拉元数据都要等十几秒下载包更是随缘。说实话这种体验在 CentOS 7 时代就有到了 Stream 9 也一点没改善。所以换阿里云 yum 源这件事不是可选项是必选项。CentOS Stream 9 是红帽公司 RHEL 9 的上游滚动版本它的软件仓库管理工具是 DNF同时保留了对 yum 命令的兼容。你平时敲yum install也好dnf install也好底层解析仓库配置、处理依赖的逻辑是一套东西。这套逻辑读取的配置文件放在/etc/yum.repos.d/目录下每个.repo文件里定义了仓库地址、GPG 校验信息、是否启用等参数。所谓配置阿里 yum 源本质就是把这几个仓库地址从官方指向阿里云镜像让软件包下载走国内线路。这篇文章我按我自己实际操作的顺序来写先说清楚 Stream 9 的仓库机制和换源之前要考虑的问题再给一份可以照着敲的完整流程然后补充 EPEL、CRB 这些扩展仓库的配置方法最后把这几年来我踩过的坑和排查思路一并整理出来。无论你是刚接触 Linux 的新手还是已经管过一批服务器的运维这份内容应该都能直接拿来用。2. 动手前需要搞清楚的三件事2.1 Stream 9 的仓库结构和 CentOS 7/8 有什么不同很多从 CentOS 7 转过来的老运维第一反应是找到CentOS-Base.repo改一下 baseurl 就行这句话在 Stream 9 上只对了一半。CentOS Stream 9 的仓库划分比 7 要细得多默认启用的核心仓库就有四个仓库名作用原官方地址示例BaseOS操作系统基础组件内核、核心工具链http://mirror.centos.org/centos-stream/9-stream/BaseOS/$basearch/os/AppStream应用软件包nginx、php、python 等http://mirror.centos.org/centos-stream/9-stream/AppStream/$basearch/os/CRB构建依赖库原名 PowerTools很多编译场景需要启用http://mirror.centos.org/centos-stream/9-stream/CRB/$basearch/os/Extras附加软件包用于安装其他产品所需依赖http://mirror.centos.org/centos-stream/9-stream/extras/$basearch/os/每个仓库单独一个.repo文件比如CentOS-Stream-BaseOS.repo、CentOS-Stream-AppStream.repo。你打开这些文件会看到里面有两组关键字段mirrorlist和baseurl。mirrorlist是一个动态地址系统根据你的地理位置返回一组可用镜像列表baseurl是直接指定的仓库路径。换阿里源的核心动作就是把mirrorlist注释掉、把baseurl改成阿里云的镜像地址。这里有个 Stream 9 特有的细节官方仓库文件里baseurl写的是http://mirror.centos.org/centos-stream/而阿里云的镜像路径是https://mirrors.aliyun.com/centos-stream/两者目录结构基本一致所以只需要替换域名前缀后面的路径可以原样保留。这也是为什么用 sed 替换比手动重写整个文件更安全不容易把路径写错。2.2 备份与回滚方案换源之前最重要的一件事是备份。很多人贪图快直接curl一个阿里云的 repo 文件覆盖到/etc/yum.repos.d/里把原始文件全冲掉了。后面一旦阿里源这边出现问题或者你需要用回官方源做对比排查手里没有原始配置就得去网上重新找很被动。我的习惯是在/etc/yum.repos.d/下先建一个backup目录把目录里所有原生的.repo文件整体挪进去。注意是挪不是删这样后续想恢复一条mv命令就能回来。顺带提一句如果你只是想测试某个仓库的地址是否正确也可以临时给.repo文件改名加.bak后缀DNF 会自动忽略非.repo结尾的文件。2.3 网络与基础工具自检换源之前先用一条命令确认机器能访问外网别一上来就改了配置然后发现连阿里云也连不上那就分不清是源的问题还是网络的问题了。我一般这样测curl -I https://mirrors.aliyun.com/centos-stream/能返回HTTP/1.1 200 OK之类的响应头说明网络通、域名解析正常。如果卡在那里不动先检查 DNS 配置/etc/resolv.conf里有没有可用的 nameserver再检查路由和防火墙很多内网机器在安全组里没放行 443 端口HTTPS 请求会被静默丢弃。另外确认一下系统里有没有sed、curl、vim这些基础命令正常安装的系统都自带但如果是一台被精简过的最小化系统可能会缺缺什么先补什么别等到改了一半发现没有编辑器可用。3. 完整配置流程直接照着做3.1 备份原始 repo 文件登录到 CentOS Stream 9 服务器先切换成 root 或者用 sudo 提权。下面的命令会把/etc/yum.repos.d/下所有.repo文件移动到backup子目录cd /etc/yum.repos.d/ mkdir -p backup mv *.repo backup/ ls backup/执行完ls应该能看到CentOS-Stream-AppStream.repo、CentOS-Stream-BaseOS.repo、CentOS-Stream-CRB.repo、CentOS-Stream-Extras.repo、CentOS-Stream-HighAvailability.repo等文件。如果你的系统还开启了 debuginfo、source 之类的仓库也会一并列出来全部挪走没有影响。3.2 下载阿里云官方 repo 配置阿里云镜像站为 CentOS Stream 9 提供了现成的 repo 文件下载到本地覆盖即可。目前推荐的获取方式有两种。方式一直接用阿里云镜像站生成的发行版仓库文件。在浏览器打开https://mirrors.aliyun.com/centos-stream/后可以看到9-stream目录里面有一套repos子目录包含各个仓库对应的.repo文件。用命令行下载是这样curl -o /etc/yum.repos.d/CentOS-Stream-BaseOS.repo https://mirrors.aliyun.com/centos-stream/9-stream/BaseOS/$basearch/repodata/repomd.xml.key等等上面这条命令还不对它只下载了一个 GPG 公钥。阿里云对 CentOS Stream 9 的仓库配置文件目前没有像 CentOS 7 时代那种一键wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo的文件。所以更稳妥的方式是方式二恢复官方 repo 文件后做 sed 替换。方式二我实际用的方法把第 3.1 节备份的文件恢复回来然后批量把mirrorlist注释掉、把baseurl前缀替换成阿里云地址。注意先恢复再改cd /etc/yum.repos.d/ mv backup/*.repo ./ sed -i s|^mirrorlist|#mirrorlist|g CentOS-Stream-*.repo sed -i s|^#baseurlhttp://mirror.centos.org/centos-stream|baseurlhttps://mirrors.aliyun.com/centos-stream|g CentOS-Stream-*.repo这两条 sed 命令是核心解释一下。第一条把所有以mirrorlist开头的行注释掉因为阿里源不需要动态镜像解析直接锁死地址更稳定。第二条把被注释的#baseurlhttp://mirror.centos.org/centos-stream去掉注释同时把域名换成阿里云的。注意官方文件里 baseurl 默认是被注释的前面有个#所以替换时要带上^#前缀否则匹配不到任何行。改完以后随便挑一个文件验证一下cat /etc/yum.repos.d/CentOS-Stream-BaseOS.repo关键行应该是这样#baseurlhttp://mirror.centos.org/centos-stream/9-stream/BaseOS/$basearch/os/ baseurlhttps://mirrors.aliyun.com/centos-stream/9-stream/BaseOS/$basearch/os/$basearch是变量系统会自动替换成x86_64或aarch64不需要你手工改。3.3 清理缓存并验证配置改完后需要让 DNF 重新拉取仓库元数据。这一步我建议按顺序执行dnf clean all dnf makecachednf clean all会把之前缓存的元数据、包文件全部清空避免旧缓存干扰。dnf makecache会重新读取/etc/yum.repos.d/下所有启用的仓库从阿里云下载repomd.xml和对应的元数据文件。执行过程中你会看到每个仓库前面显示baseos、appstream、crb、extras这样的标识速度应该比官方源快得多。验证是否真正生效我用两个方法。第一个是看元数据下载耗时阿里源通常几秒内完成第二个是实际装一个软件试试dnf install -y htop安装成功后再查看软件来源dnf list installed htop或者用dnf repolist查看所有启用的仓库及包数量统计dnf repolist如果仓库地址和包数量都正确显示说明换源已经成功。这里说句题外话我见过有人换完源不执行dnf clean all然后发现元数据一直报错其实是因为 DNF 还拿着旧的缓存在做解析跟新的仓库内容对不上。所以换源三连改配置、清缓存、重新生成缓存这个顺序最好一次都不要省。4. 进阶配置EPEL 与扩展仓库4.1 为 Stream 9 配置阿里云 EPEL 镜像EPELExtra Packages for Enterprise Linux是 Fedora 社区维护的扩展软件仓库提供大量不在 CentOS 官方源里的软件比如htop、tmux、fail2ban。CentOS Stream 9 可以安装对应版本的 EPEL 仓库。国内服务器上 EPEL 官方源同样很慢所以也要换成阿里云镜像。配置步骤我一般这样做。先安装 EPEL 的发布包这个包本身可以从阿里云下载dnf install -y https://mirrors.aliyun.com/epel/epel-release-latest-9.noarch.rpm安装完成后系统会在/etc/yum.repos.d/下多出epel.repo和epel-testing.repo两个文件。接着按同样的思路改源sed -i s|^metalink|#metalink|g /etc/yum.repos.d/epel.repo sed -i s|^#baseurlhttps://download.example/pub/epel|baseurlhttps://mirrors.aliyun.com/epel|g /etc/yum.repos.d/epel.repo注意 EPEL 的配置结构和官方源不太一样它用的是metalink而不是mirrorlistbaseurl 的原始地址是https://download.example/pub/epel这些细节在写 sed 的时候要对应上。改完同样执行dnf clean all dnf makecache然后试试装一个之前没有的软件dnf install -y fail2ban能装上就说明 EPEL 源正常。这里有个小坑新版 EPEL 的 repo 文件里baseurl 那一段在注释示例里写的是#baseurlhttps://download.example/pub/epel/9/Everything/$basearch如果你把整行注释打开后直接用系统解析时$basearch也会自动替换不需要手动改但前提是这行没有被额外转义。我建议装完以后cat看一下文件内容确认 baseurl 行没有被加多余的反斜杠或者空格。4.2 CRB 仓库到底开不开CRB 全称 CodeReady Builder对应 CentOS 7 时代的 PowerTools主要放构建依赖库和一些开发相关的包。很多人在编译软件时报错找不到库文件原因就是 CRB 没有启用。默认情况下它是禁用的打开方式有两种dnf config-manager --set-enabled crb或者直接编辑 repo 文件把enabled0改成enabled1。如果你用的是 SELinux、虚拟化、容器相关组件建议把 CRB 打开否则dnf builddep之类的工作会很痛苦。但要注意CRB 的包和 BaseOS、AppStream 的版本绑定很紧混用不匹配的源会直接破坏依赖关系所以 CRB 一定要和你的 CentOS Stream 9 主版本保持一致来源要么都用阿里云要么都用官方不要交叉。4.3 镜像源优先级配置当你有官方源、EPEL、第三方源共存时包的版本冲突是一个很常见的问题。比如某个软件在 AppStream 里有 1.0 版在 EPEL 里有 1.2 版DNF 默认会选版本号更高的但这不一定是你要的。这时候可以给仓库设置优先级dnf install -y dnf-plugins-core dnf config-manager --setoptepel.priority90 --save数值越小优先级越高。我一般把官方源设成 10EPEL 设成 90这样除非官方源没有否则不会优先用 EPEL 的包。优先级配置属于保平安型操作不配置也能用但多一步能省掉后面很多莫名其妙的依赖冲突。5. 常见问题与排查实录5.1 GPG 公钥导入失败换源后执行dnf makecache时有时会报Public key for xxx.rpm is not installed或者The GPG keys listed for the repository are not yet installed。这是因为新启用的仓库使用的 GPG 公钥还没有导入系统。解决思路分两步。先看 repo 文件里gpgkey这一行指向哪个公钥文件然后手动导入rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial如果提示找不到这个文件先确认路径ls /etc/pki/rpm-gpg/CentOS Stream 9 的公钥文件名通常是RPM-GPG-KEY-centosofficial和RPM-GPG-KEY-epel-9。导入时可以一次性全部导入不影响使用。5.2 $releasever 变量解析异常有些教程里会让你把 repo 文件里的$releasever手动替换成9。从 Stream 9 开始$releasever的返回值和 CentOS 7/8 不一样。CentOS Stream 9 里它返回9-stream而不是单纯的9。如果你在文件里写死了9-stream在阿里云路径下通常没问题但如果某些第三方脚本生成 repo 文件时写的是/centos-stream/9/路径就错了会 404。我排查这个问题的经验是先看实际请求的 URL 是什么可以用dnf -v repolist查看详细输出里面会显示每个仓库 final baseurl 的解析结果。如果发现路径不对直接看对应的.repo文件把变量部分改成9-stream就好。5.3 网络正常却连不上 mirrors.aliyun.com这种情况我遇到过一次现象是浏览器能打开阿里云镜像站但服务器上curl一直超时。查了半天发现是服务器上的reposync进程把连接数占满了导致新的连接一直被拒绝。排查命令ss -ant | grep :443 | wc -l如果不放心可以把 repo 文件里的baseurl从https临时改成http阿里云镜像站兼容两种协议。镜像站本身的带宽和稳定性在国内属于第一梯队如果你的服务器在海外那还不如继续用官方源阿里云对海外线路的优化不多强扭的瓜不甜。5.4 makecache 报错说仓库元数据不匹配有一次我配置完执行dnf makecache报Failed to download metadata for repo appstream同时提示repomd.xml校验失败。检查下来发现是之前残留的缓存目录里有一个损坏的repomd.xml。解决办法是彻底清理rm -rf /var/cache/dnf/* dnf makecache注意dnf clean all有时候并不会把/var/cache/dnf/下所有子目录删干净尤其是你手动拷过缓存文件的情况。直接删掉整个缓存目录是最彻底的办法删完系统会自动重建不用担心破坏什么。5.5 软件版本比预期旧换源后dnf install nginx装出来一个老版本很多人会以为是源的问题。实际上阿里云镜像站会定期同步 CentOS Stream 官方仓库同步频率通常是几小时到一天一次理论上滞后很小。如果确实发现版本不对先看仓库启用状态dnf repolist --enabled然后用dnf list --showduplicates nginx看该软件在源里有哪些版本。如果源里确实只有旧版本可以手动指定版本号安装或者检查有没有多仓库干扰了选择顺序。正常情况下阿里云源的同步速度足够日常使用不必过度纠结。6. 实测效果与调优心得配置完成之后我拿一台 2 核 4G 的 CentOS Stream 9 测试机做了一轮对比。换源前dnf makecache的元数据下载耗时平均在 30 秒到 60 秒之间高峰期甚至超过两分钟换源后稳定在 5 秒以内。实际安装一个nginx加一个php-fpm换源前的整体耗时大概在 4 分钟左右换源后跑完不到 40 秒。这个差距对单台机器来说可能只是省了一点等待时间但如果你要批量初始化一批服务器或者在 CI 流水线里做镜像构建节省的时间就是实实在在的成本。我说一个很多人没注意的点换完源以后别忘记检查一下系统时间。GPG 校验和 HTTPS 握手都对系统时间敏感如果服务器时钟偏差过大即便源配置完全正确也会出现证书校验失败的诡异错误。我在一台跑了好几年的机器上就遇到过时区一直定在 UTC和本地时间差了 8 个小时倒是没影响下载但排查问题时差点误导我往源配置上想。顺手执行一句timedatectl set-ntp true把这个隐患提前灭掉。另外如果你的服务器数量不止一台我强烈建议不要一台台手动敲命令而是把整个/etc/yum.repos.d/目录打包成一个 tar分发到其他机器上解压覆盖。这样能保证所有机器使用完全一致的仓库配置排查问题时也不用反复确认是不是你这边改漏了一行。我自己维护了一批测试环境就是用 Ansible 推送 repo 文件配合dnf clean all dnf makecache这个 handler一次性把几十台机器的源全部换完中间没出过任何问题。7. 踩坑后的几条实用建议按照惯例最后整理几条我用实际教训换来的建议算不上系统性的方法论但每一条都值得留意。第一修改任何系统级配置文件之前先做备份这真的是老生常谈但越基础的道理越容易在实际操作中被忽略。/etc/yum.repos.d/下的文件改动成本很低但影响范围是全局的一个错误的地址会让整台机器的软件安装全部瘫痪。第二不要在业务高峰期动仓库配置。dnf makecache会重新拉取大量元数据在带宽有限的机器上会拖慢其他网络请求。我习惯在凌晨或者维护窗口期做这类变更顺手再跑一遍dnf update -y把系统补丁打完。第三如果用的是云厂商自带的防火墙或者安全组记得确认出站方向的 80/443 端口是放行的。很多内网机器默认只开了入站规则出站全通但也有一些策略严格的环境把出站也限制了这种情况下换哪个源都是白搭。第四配置完源以后最好留存一份换源后的标准 repo 文件清单。下次再遇到同类环境直接对照清单检查省得逐行 diff。我自己是把这一整套文件放在内部 Git 仓库里维护的改一次同步一次相当于给服务器配置做了版本管理。CentOS Stream 9 配置阿里 yum 源这件事本质上就是一个把默认远程地址换成国内高速地址的操作技术上不难但里面的细节不少。希望这篇文章能帮你少走几步弯路把时间花在真正需要折腾的事情上。