
如果你刚装完一台 CentOS 7准备用 yum 安装点东西结果发现速度很慢甚至yum makecache直接超时那你大概率会遇到这篇文章要聊的问题——yum 源替换。我自己的环境里维护着几十台机器早几年就开始做源替换这几年系统版本停止维护之后替换源基本成了新机器初始化的必备步骤。这篇文章不是简单贴几个命令而是把替换的原理、操作、常见坑和批量方案都梳理一遍适合刚接触 Linux 的小白也适合要管理成批服务器的运维同学。1. 官方源还能用但体验真的让人想把机器重启1.1 我遇到的典型症状和最快定位思路最早触发我换源的场景很朴素新装了一台 CentOS 7 虚拟机yum install -y vim回车之后进度条卡在 “Downloading packages” 这一行等了十分钟还没有反应最后直接Connection timed out。重试了几次偶尔能走几 KB 就断了。当时第一反应是 DNS 有问题于是手动改了/etc/resolv.conf结果还是一样。再测试到更新服务器的连通性发现 ICMP 能通但 HTTP 请求经常被重置下载速度波动非常夸张。这种状态下如果继续等基本无解。就算把超时时间调大最后也可能因为某个包下载失败导致事务中断还得重新来。所以把 yum 源切换到一个链路相对更稳定、访问速度更快的公共镜像服务成了最实际的做法。判断逻辑很简单如果你的机器能正常访问公网但访问官方更新服务器时延迟很高、连接不稳定那问题大概率不在本机网络而在源服务器这条链路上。1.2 版本停止维护后yum 源地址已经悄悄变了很多人可能还记得早几年 CentOS 7 刚发布的时候官方源里的base、updates、extras都指向官方更新服务器直接使用也没有太大问题。但到了生命周期终点之后原来更新目录里的安装包并不会一直留在原地而是被整体迁移到了归档目录中。对新装出来的 CentOS 7 而言默认的CentOS-Base.repo文件里指向的路径已经无法拿到有效更新数据。简单说如果你现在用的还是系统自带的这份配置执行yum update很可能会遇到两类情况一类是仓库元数据下载 404 或找不到路径另一类是还能拉到更新数据但速度极不稳定。两者都会让人想重启机器。这也是我为什么坚持建议所有 CentOS 7 用户做完初始化之后第一件事就是检查、替换 yum 源。2. 动手前先搞明白 yum 源的三个关键机制替换源不是“把某个文件下载下来覆盖一下”这么简单。如果你不搞清楚背后的机制出了问题会非常被动因为你连排查的方向都没有。2.1 repo 文件、baseurl 与 mirrorlist 的取舍yum 的源配置都放在/etc/yum.repos.d/目录下文件名以.repo结尾。每个文件里可以定义多个仓库段每个段有[唯一标识]、name、baseurl、enabled、gpgcheck等字段。其中最常见的两个地址指令是mirrorlist和baseurl。mirrorlist指向的是一个动态列表地址yum 会去请求这个列表拿到一批镜像地址然后逐个测速、选择可用的那个。好处是官方会动态更新镜像列表坏处是多了一次远程请求而且这个请求本身就可能很慢一旦列表服务不稳定整体体验就会变得非常差。baseurl则是直接指定一个确切的仓库地址yum 会直接去这个地址拉取元数据。换源的核心说白了就是把原来指向官方更新服务器的mirrorlist或baseurl改成指向你选好的公共镜像服务地址并优先使用baseurl避免mirrorlist引入额外的网络请求。2.2 $releasever 和 $basearch 变量一份配置适配多台机器CentOS 7 的 repo 文件里常见这样的写法baseurlhttps://mirrors.example.com/centos/$releasever/os/$basearch/这里的$releasever和$basearch是 yum 的本地变量。$releasever在 CentOS 7 上通常解析为7$basearch通常解析为x86_64或aarch64。因为有了这个变量同一份 repo 文件可以复制到不同架构的机器上不需要手动改路径。但有一个例外需要特别注意版本停止维护后镜像站一般会把归档数据放到类似centos-vault/7.9.2009/这样的具体版本号目录里而不是直接放在centos/7/下。这种情况下如果继续写$releaseveryum 解析出来的7很可能匹配不上归档目录里的7.9.2009结果就是 404。所以遇到归档源时我通常会把版本号写死比如直接用7.9.2009至少在路径匹配上更靠谱。2.3 gpgcheck、本地缓存与“源优先级”的真相gpgcheck1表示开启 GPG 签名校验yum 在安装包时会验证 RPM 包的签名是否与仓库声明的公钥匹配防止源被篡改。系统自带的公钥文件通常放在/etc/pki/rpm-gpg/下。很多人换源之后遇到public key not installed报错就是只改了源地址没有导入对应公钥。另一个容易被忽略的是缓存机制。yum 每次拉取的仓库元数据会缓存在/var/cache/yum/$basearch/$releasever/下。源地址改完之后如果不执行yum clean all下次操作可能还在用旧的缓存元数据导致你看到的现象是“明明改了源怎么还在连接旧服务器”。这个坑特别容易踩后面我会再展开。还有“优先级”的问题。默认情况下 CentOS 7 的 yum 不启用到优先级插件多个仓库如果同时提供同一个包解析顺序并不明确。所以我不建议换源之后让新旧两套仓库同时启用否则会出现依赖解析异常或者拉取到不符合预期的包。后面第 4 章会专门讲这种“源混杂”的情况。3. 一次标准的 yum 源替换操作流程从备份到验证下面这套流程我在新机器上几乎每次都这么走已经形成肌肉记忆了。你可以直接复制但建议先看一遍再动手尤其是备份和验证这两步不要跳过。3.1 备份原 repo 文件一个容易被忽视的细节很多人习惯直接删除/etc/yum.repos.d/下所有.repo文件再下载一份新配置。这种做法我是不太推荐的。虽然新配置一般都能正常用但万一你下载的新配置有问题想回退原来的网络源就麻烦了。所以我每次都会先把原始配置整体备份到一个子目录里。mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/这里有个细节yum 只扫描/etc/yum.repos.d/目录下以.repo结尾的文件不会递归扫描子目录。所以把旧文件放进backup/子目录之后yum 是不会去读它们的等于间接完成了“禁用”同时又保留了完整的回滚路径。这个操作比直接删文件稳妥得多。3.2 写一套适合当前状态的 repo 配置接下来我会在/etc/yum.repos.d/下新建一个干净的配置文件比如叫CentOS-Vault.repo。因为 CentOS 7 已经进入归档状态所以这里使用归档路径。镜像站地址我用示例域名mirrors.example.com表示实际使用时替换成你选择的公共镜像服务地址即可。[base] nameCentOS-$releasever - Base baseurlhttps://mirrors.example.com/centos-vault/7.9.2009/os/$basearch/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 enabled1 [updates] nameCentOS-$releasever - Updates baseurlhttps://mirrors.example.com/centos-vault/7.9.2009/updates/$basearch/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 enabled1 [extras] nameCentOS-$releasever - Extras baseurlhttps://mirrors.example.com/centos-vault/7.9.2009/extras/$basearch/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 enabled1这段配置里的/centos-vault/7.9.2009/是归档目录的常见结构但不是所有镜像站都一模一样。有的站点直接用符号链接把centos/7/指到归档目录有的则要求你访问centos-vault/7.9.2009/。所以我每次换新镜像站时都会先用浏览器或curl确认一下某个具体目录是否存在而不是盲目套模板。curl -I https://mirrors.example.com/centos-vault/7.9.2009/os/x86_64/如果返回 HTTP 200说明路径没问题。如果是 404就去镜像站首页看目录结构找到实际可用的路径再写进配置里。3.3 清理缓存并验证结果配置写好之后执行清理和重建缓存yum clean all yum makecacheyum clean all会清理本地缓存的仓库元数据确保下一次请求不多余。yum makecache则是让 yum 根据新配置重新拉取仓库元数据。这一步跑完你会看到每个仓库都显示metadata cache created或者类似输出这说明新源已基本生效。接着用两个命令验证yum repolist yum install -y treeyum repolist能看到当前启用的仓库列表确认 base、updates、extras 都在 enabled 状态。yum install -y tree则是用一个小包测试实际下载是否顺畅。如果这两个都通过说明替换已经成功。4. 替换后最容易踩的四个坑与完整排查思路即使按照标准流程操作也不代表百分百顺利。下面这几个问题是我见过最多的也是自己踩过之后才彻底搞明白的每个都给出完整的排查路径。4.1 makecache 报错 404 或 Path not found这是最高频的问题。你执行yum makecache时yum 报出类似这样的错误https://mirrors.example.com/centos-vault/7.9.2009/os/x86_64/repodata/repomd.xml [Errno 14] HTTP Error 404 - Not Found遇到 404先不要急着怀疑镜像站挂了。排查链路应该是这样先用curl -I直接请求报错里的完整 URL看看是不是真的 404。如果 404大概率是路径不对比如你把7.9.2009写成了7或者os和x86_64的顺序反了。如果curl能返回 200但 yum 还是 404那就要看 repo 文件里是不是有看不见的字符比如多余空格、行尾回车异常。也有一种情况是镜像站确实把某些旧仓库下线了只保留了一个骨架目录。这个时候你可以看看报错 URL 的上一级目录用curl列目录或者访问镜像站网页版目录确认该仓库是否还存在。归档源并不是所有仓库都保留得很完整有些旧版本的 debug 源或 source 源可能被清理掉这种情况就只启用实际可用的仓库即可。4.2 提示 public key not installedGPG 签名文件没导入还有一种常见报错The GPG keys listed for the CentOS-7 - Base repository are already installed but they are not correct for this package.或者Public key for xxx.rpm is not installed出现这个问题的根本原因是仓库地址换了但公钥没有找对。CentOS 7 的官方公钥文件通常有两个RPM-GPG-KEY-CentOS-7和RPM-GPG-KEY-CentOS-Debug-7都放在/etc/pki/rpm-gpg/下。如果你写的gpgkey路径指向了一个不存在的公钥yum 会因为无法校验签名而拒绝安装。排查方法很简单ls -l /etc/pki/rpm-gpg/ rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7导入后再执行安装应该就能通过。需要说明的是不建议为了省事把gpgcheck改成0。虽然能立刻绕过报错但本地仓库被篡改时不会有任何告警这在稍微正式一点的环境里是要出事的。4.3 改了配置还是超时看看是不是 mirrorlist 在捣乱有些同学改完 repo 文件后发现yum makecache依然卡很久甚至还在不断尝试连接旧地址。这时候第一反应是看/etc/yum.repos.d/下还有没有旧文件带了mirrorlist字段。系统自带的CentOS-Base.repo里往往同时写了mirrorlist和baseurl。如果你只是把baseurl改成了镜像站地址但忘了注释或删除mirrorlistyum 在某些情况下还是会优先使用mirrorlist返回的动态列表你的新配置等于没生效。所以换源后如果要排查超时第一件事就是检查所有 repo 文件里mirrorlist是否还处于未注释状态。grep -n mirrorlist /etc/yum.repos.d/*.repo如果还有未注释的mirrorlist要么删掉这一行要么整行注释掉。之后再yum clean all yum makecache。4.4 yum repolist 出现多个重复源新旧配置混杂还有一种情况是故障表现不明显安装包也能装但yum repolist里能看到两个base仓库一个叫base另一个叫CentOS-7 - Base。出现这种问题多半是/etc/yum.repos.d/下同时存在系统自带的CentOS-Base.repo和你新建的CentOS-Vault.repo两个仓库段都启用了。这种混杂状态很麻烦。两个源都提供同名包时yum 解析依赖可能会在你意想不到的地方翻车而且排查起来比单纯的 404 更费劲。我的建议是尽量保持只启用一套核心仓库不要让同一个逻辑仓库出现多个来源。最简单的处理方式ls /etc/yum.repos.d/把不需要的.repo文件移进backup/子目录只保留你要用的那一个。然后清理缓存再yum repolist确认没有重复源。下面的表格是我每次排错时常用的一张速查表先定位现象再对症处理现象常见原因排查动作makecache 404baseurl 路径写错或目录不存在curl -I请求报错 URLpublic key not installed未导入对应 GPG 公钥检查/etc/pki/rpm-gpg/重新导入依然连接旧服务器超时mirrorlist 未注释grep -n mirrorlist *.reporepolist 重复源新旧 repo 文件同时启用移走多余.repo文件5. 更进一步多机批量切换与自建内网源思路如果你只有一两台机器手改 repo 文件完全够用。但机器一旦多起来比如几十台甚至上百台逐台手改显然不现实。下面分享两个我实际用过的方案一个适合手工脚本批量分发一个适合内网环境彻底自给自足。5.1 多台机器批量分发 repo 配置的脚本思路批量切换的核心思路是先在一台机器上把 repo 文件配好、验证通过然后把文件分发到其他机器再各自执行缓存清理和重建。最简单的实现可以这样写先在本地准备一份CentOS-Vault.repo然后循环读取服务器列表用scp分发并执行远程命令。for ip in $(cat server.list); do echo $ip scp /etc/yum.repos.d/CentOS-Vault.repo root$ip:/etc/yum.repos.d/ ssh root$ip yum clean all yum makecache done这段脚本没有做太多容错比如没检查 ssh 是否成功、没判断缓存重建是否报错。真正用在生产环境时我会加一层判断远程执行yum repolist | grep -c base如果返回数量不对就标记出来不继续往下分发新机器。另外如果机器数量很大更推荐用批量运维工具来管理效率和安全性都会好很多。还有一点容易被忽略分发新配置文件之前最好把目标机器上原来/etc/yum.repos.d/下的.repo文件先重命名或移走不然又会变成第 4 章说的“新旧混杂”。可以复用前文的备份思路在目标机器上先把原文件统一搬到一个backup/目录。5.2 自建内网源的适用条件与最小流程如果你的环境对公网访问有限制或者服务器数量大到每次都要从公网拉包、带宽完全扛不住那自建内网源就是一个很值得做的方向。这里分享一套最小可用的流程不需要额外购买复杂设备一台能访问公网的机器加一块足够大的磁盘就可以开始。第一步安装同步工具yum install -y yum-utils createrepo第二步用reposync同步某个仓库到本地目录。以 base 仓库为例reposync -r base -p /data/yum-repo/centos/7/os/x86_64/-r base表示同步 base 仓库-p指定同步到哪个目录。同步完成后用createrepo生成仓库元数据createrepo /data/yum-repo/centos/7/os/x86_64/第三步把本机或内网其他机器的 yum 源指向这台同步服务器。假设这台内网服务器的地址是yum-server.local配置可以写成[base] nameCentOS-$releasever - Base baseurlhttp://yum-server.local/centos/$releasever/os/$basearch/ gpgcheck0 enabled1这里我把gpgcheck设成了0因为内网自建源通常没有对外分发公钥签名校验只会增加配置复杂度。当然如果你内网要求足够严格也可以用自己的私钥签名 RPM 包再把公钥发到所有客户端机器上但这套链路做起来成本不低一般场景没必要。5.3 同步策略从“能用”到“够用”自建源同步不是一次性的。软件包会持续更新如果不做定时同步过几个月源就“过期”了。我个人的做法是用 crontab 跑一个定时任务每天凌晨流量低峰期同步一次比如0 3 * * * reposync -r base -r updates -r extras -p /data/yum-repo/centos/7/ /var/log/reposync.log 21 createrepo /data/yum-repo/centos/7/os/x86_64/注意一点reposync同步的数据量不小如果网络带宽有限第一次全量同步可能会持续几小时甚至更久建议放在业务低峰期执行。后续增量同步因为只有新包和元数据变化通常会快很多。磁盘占用也要提前估算一个完整的 base 仓库加 updates、extras根据不同版本和架构大致需要几十 GB 到一两百 GB 不等的空间。我在最初规划时低估过一次导致同步到一半磁盘写满后来改成了先估算、再迁移数据盘、最后重跑同步的顺序。如果你预计机器数量还会继续增加建议开始就一次性至少准备 200 GB 的独立挂载点。我在实际使用中发现很多人一听到“自建源”就觉得麻烦其实一旦跑起来收益非常大。尤其是批量重装系统、批量更新安全补丁的时候内网源的稳定性和速度都是公网源没法比的。不过如果你只是维护三五台机器我认为完全没有必要自建直接用公共镜像服务就足够了把精力省下来做更重要的运维工作。最后再分享一个小技巧无论你是手改单机配置还是批量切换换完源之后我都会顺手把yum makecache的输出保存一份日志再安装一个小包做真实下载测试。这一步看着多余却能帮你把 404、密钥、mirrorlist 未注释这类问题一次性暴露出来而不是等到第二天批量装机时才突然发现源是坏的。CentOS 7 已经进入维护末期源配置这件事多花几分钟确认后面能省下很多不必要的折腾。