ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

CentOS 7 yum源失效怎么办?切换vault归档源最全修复指南

CentOS 7 yum源失效怎么办?切换vault归档源最全修复指南

凌晨一点,值班手机响了。业务那边反馈所有新环境初始化失败,我登录一台故障机执行yum update,日志干净利落地甩出一行红字:Could not resolve host: mirrorlist.centos.org。看到这行报错,我心里基本有数了,这多半不是网络抽风,而是 CentOS 7 的 yum 源进了生命周期终止后的“失联区”。

CentOS 7 在 2024 年 6 月 30 日停止维护,官方维护计划早就公布过。但 CentOS 7 至今仍是存量最大的 Linux 发行版之一,大量线上业务、离线机房、老构建机都还在用它。官方源退役后,默认请求的mirrorlist.centos.org和mirror.centos.org/centos/7/路径会逐步不可用,表现就是 yum install 报错、yum update 失败、依赖解析直接崩溃。更麻烦的是,这类报错不只有一种长相,有时是 DNS 解析失败,有时是 404,有时干脆卡在 mirrorlist 测速上。排查不仔细,很容易绕弯子。

这篇文章把我实际处理这个问题的完整过程写出来,包含报错类型辨别、排查顺序、Base 源和 EPEL 源的配置修改、缓存清理,以及几个特别容易踩的坑。如果你正被 CentOS 7 的 yum 源问题折磨,或者想提前储备这个运维操作场景的处理方案,直接照做即可。

1. 报错现场:CentOS 7 源失效的几种典型长相

1.1 最容易遇到的几类报错

先说结论:CentOS 7 源失效不会只有一种表现形式。我实际处理过的服务器里,最常见的是下面这三种。

第一种,DNS 解析类型:

Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=container error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org"

第二种,仓库校验失败类型:

One of the configured repositories failed (CentOS-7 - Base), and yum will now exit

第三种,元数据 404 类型:

http://mirror.centos.org/centos/7/os/x86_64/repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found

这三种表面症状差异很大。第一种看起来像 DNS 没配好,第二种像是仓库配置损坏,第三种像文件路径写错。但它们的根因是同一件事:CentOS 7 进入生命周期终止(EOL)状态后,官方仓库维护重点已经转移到归档目录,老仓库不再生成新的repomd.xml,部分 URL 直接返回 404,部分mirrorlist接口干脆不再对版本 7 返回可用镜像列表。也就是说,不是你的网络坏了,而是远端真的“没有这个东西了”。

1.2 为什么 CentOS 7 的源会集体消失

CentOS 7 的完整版本是 7.9.2009,这也是该系列最后一个正式版本。任何软件发行版只要停止维护,官方通常会把历史仓库从“主下载目录”挪到“归档目录”,避免占用主目录的空间,也避免用户继续收到已不维护的包。CentOS 项目的归档位置就是vault.centos.org。

对 yum 源来说,默认情况下 CentOS 7 的 Base、Updates、Extras 三个仓库会去请求:

  • mirrorlist.centos.org/?release=7&arch=x86_64&repo=os
  • mirror.centos.org/centos/7/os/x86_64/repodata/repomd.xml

一旦官方把主目录里的centos/7/内容移走,这两个地址就变成无效状态。镜像列表返回不了可用镜像,主目录返回 404,yum 自然拉不到任何仓库元数据。

需要注意,EPEL 源(Extra Packages for Enterprise Linux)也存在类似问题。EPEL 7 同样停止维护,默认的download.fedoraproject.org/pub/epel/7/路径也会失效,需要切到归档路径archives.fedoraproject.org/pub/archive/epel/7/。

2. 动手前的排查:先分清楚是真的源失效,还是本地网络故障

2.1 三步定位问题

改配置之前,我建议先花几分钟做一遍快速定位,避免把网络问题错怪到源头上。

第一步,用yum repolist看具体是哪个仓库报错。报错信息里通常写了仓库名,比如 CentOS-7 - Base、CentOS-7 - Updates,或者 EPEL。记住这个名字,后面要定向处理。

第二步,手动用 curl 测试关键 URL。如果报错里带着 mirrorlist 地址,就测 mirrorlist;如果带着具体 repodata 路径,就测 repodata。

curl -I --connect-timeout 5 "http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os" curl -I --connect-timeout 5 "http://mirror.centos.org/centos/7/os/x86_64/repodata/repomd.xml"
  • 如果 curl 返回 200 或 302,说明网络和域名解析都没问题,问题在别的仓库或配置细节。
  • 如果 curl 返回 404,可以基本确认是远端归档问题。
  • 如果 curl 报Could not resolve host,先查 DNS:cat /etc/resolv.conf,再用ping或者dig试几个常见域名。
  • 如果 curl 超时,检查出网防火墙和代理配置。公司内网环境经常有代理限制,yum 默认不走代理,需要在/etc/yum.conf里显式配置proxy=。

第三步,把/etc/yum.repos.d/目录里的.repo文件全部列出来,确认系统里除了默认源之外还有没有第三方源。很多服务器会残留各种第三方软件源,它们如果也指向 CentOS 7 时代的老地址,一样会报错。

2.2 备份配置文件

修改任何系统配置文件前,备份是底线操作。yum 源配置文件虽然改动量不大,但一旦替换出错,连恢复现场都很麻烦。

mkdir -p /root/yum-repo-backup/$(date +%F) cp -r /etc/yum.repos.d/* /root/yum-repo-backup/$(date +%F)/

如果后续改动出问题,直接把这个目录里的文件拷回去就能恢复。另外我习惯顺手记录一下当前系统版本和架构:

cat /etc/redhat-release uname -m

CentOS 7 的最终版本号是 7.9.2009,架构一般是x86_64,这两个信息在下一步配置里会用到。若服务器是aarch64等 ARM 架构,路径中的架构参数要对应替换。

3. 核心修复:把 yum 源切换到归档源

3.1 修改 CentOS-Base.repo

CentOS 7 的默认源配置位于/etc/yum.repos.d/CentOS-Base.repo。修复原则其实很简单:把失效的mirrorlist和mirror.centos.org地址全部替换成vault.centos.org/7.9.2009/下的对应路径。

最稳妥的方式是手工编辑,逐段替换。下面是我实际用过的配置片段:

[base] name=CentOS-$releasever - Base baseurl=http://vault.centos.org/7.9.2009/os/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [updates] name=CentOS-$releasever - Updates baseurl=http://vault.centos.org/7.9.2009/updates/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [extras] name=CentOS-$releasever - Extras baseurl=http://vault.centos.org/7.9.2009/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

注意这里有三个关键点。

第一,mirrorlist=行必须注释掉或者删除。否则即使你写了正确的baseurl,yum 有时仍会去请求 mirrorlist 接口,轻则多绕一段请求,重则直接报错。

第二,路径里的7.9.2009是 CentOS 7 的最终版本号。不要写成7。vault.centos.org/7/不一定稳定,官方归档目录按完整版本号组织,7.9.2009才是准确的归档目录名。

第三,$basearch变量可以保留,yum 会自动替换成x86_64或aarch64。$releasever在 CentOS 7 上通常等于7,但我建议直接写死完整版本号,减少变量解析带来的不确定性。

如果你不想手工编辑,也可以用 sed 快速替换。默认的 CentOS-Base.repo 里baseurl是注释状态,mirrorlist是启用状态,处理方式就是取反再换地址:

sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-Base.repo sed -i 's|^#baseurl=|baseurl=|g' /etc/yum.repos.d/CentOS-Base.repo sed -i 's|http://mirror.centos.org/centos/$releasever|http://vault.centos.org/7.9.2009|g' /etc/yum.repos.d/CentOS-Base.repo

这套命令在绝大多数默认配置的 CentOS 7 系统上可以直接复用。第三行的目的是把文件里的变量形式地址替换成固定的归档地址,注意单引号防止 shell 展开。

3.2 处理 EPEL 源

EPEL 是 CentOS 7 里最常用的第三方软件源,很多额外包都依赖它。如果系统里装了epel-release,/etc/yum.repos.d/epel.repo同样需要改。先确认一下:

rpm -qa | grep epel-release

有输出,就说明 EPEL 源存在。编辑/etc/yum.repos.d/epel.repo,把mirrorlist注释掉,baseurl改成归档地址:

[epel] name=Extra Packages for Enterprise Linux $releasever - $basearch baseurl=https://archives.fedoraproject.org/pub/archive/epel/7/$basearch enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

如果你用了 epel-testing,同样处理:

[epel-testing] name=Extra Packages for Enterprise Linux $releasever - Testing - $basearch baseurl=https://archives.fedoraproject.org/pub/archive/epel/7/testing/$basearch enabled=0 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

这里有个特殊情况。如果系统里根本没有安装epel-release,却需要使用 EPEL 中的软件包,那就先别急着装包。因为老版本的epel-releaserpm 文件自带的仓库配置也会指向失效地址。正确做法是:先到 EPEL 归档目录下载与 CentOS 7 匹配的epel-releaserpm,然后用rpm -ivh安装,装完再按上面的方式修改仓库文件。

3.3 清理缓存并验证修复结果

源配置改完后,第一件事不是直接 yum install,而是清理缓存和重建元数据。原因很简单:本地/var/cache/yum里可能还残留着旧的仓库元数据,它会把 yum 引导到老地址上,导致改了半天仍然报错。

yum clean all yum makecache

yum clean all会清掉所有仓库的元数据缓存和临时文件。yum makecache会按当前配置文件重新拉取所有启用仓库的repomd.xml,这一步如果顺利执行,说明源配置已经生效。

接下来跑一遍yum repolist,确认仓库数量正常:

yum repolist

输出里应该能看到base、updates、extras和epel等仓库,状态正常。最后做个实际测试:

yum -y update

这里注意,CentOS 7 已经 EOL,别指望还能拉到大量更新,但命令执行过程不报 404、不报Could not resolve host,就说明 yum 源本身已经恢复可用。如果只想装某个软件,也可以直接yum -y install <package>验证。

4. 实操中的坑:这些情况我全遇到过

4.1 DNS 正常但依旧报错,元凶可能是 fastestmirror

有一次我处理一台服务器,curl 测试 mirrorlist 地址完全正常,但 yum 就是慢吞吞地报错。排查到最后,发现是fastestmirror插件在捣乱。

fastestmirror插件会在 yum 执行时自动测试多个镜像的速度,优先选择最快的一个。当配置文件里的mirrorlist还指向失效地址时,插件会反复做无效请求,结果就是长时间等待,最终报错或回退失败。

解决办法有两个。一是改配置时坚持把mirrorlist=注释掉,从根上避免插件去请求它。二是直接禁用插件:

sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf

或者修改/etc/yum.conf,把默认启用插件的开关关掉:

plugins=0

我个人的习惯是,在 EOL 系统上直接禁用 fastestmirror。反正所有仓库都指向固定归档地址了,测速已经没有意义,反而多一层故障隐患。

4.2 GPG 签名校验报错,别急着关 gpgcheck

切换到 vault 源后,有时会遇到公钥缺失或签名校验失败的报错:

Public key for xxx.rpm is not installed

这种情况多发生在长期未更新的机器上,系统缺少 CentOS 7 的 GPG 公钥。不要条件反射式地把gpgcheck=1改成gpgcheck=0,这是把安全底线降级了。正确的是导入对应的公钥文件:

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

如果公钥文件本身丢失,可以重新安装对应密钥包(centos-release或epel-release),或者从归档源下载公钥再导入。

4.3 clean all 之后 makecache 卡死

有台机器执行yum makecache时卡在“determining fastest mirrors”这一步,二十分钟没动。这不是网络问题,是插件逐个测试镜像站点超时。按 4.1 的方式关掉 fastestmirror 之后,makecache 十几秒就完成了。所以如果你用的还是默认配置文件,我建议先禁用插件再执行清理缓存。

另外还有一种情况:仓库配置里baseurl写成了https://,但服务器时间不准,SSL 握手报证书错误。CentOS 7 的老机器时间同步服务经常失灵,如果 makecache 报证书或校验错误,先date看下系统时间,再用ntpdate或 chrony 同步一遍。

4.4 内网离线机连 vault 都访问不了

外网可达的机器按第 3 章操作就能修复。但很多内网服务器只开放了特定端口,根本访问不到vault.centos.org。这种情况下,最实用的方案是做一个本地 yum 源。

最简单的做法是用 CentOS 7 的 ISO 镜像做本地源。把 ISO 上传到服务器,然后挂载:

mkdir -p /mnt/cdrom mount -o loop /opt/CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom

新建一个本地源配置文件,例如/etc/yum.repos.d/local.repo:

[localiso] name=CentOS 7 Local ISO baseurl=file:///mnt/cdrom/ enabled=1 gpgcheck=0

然后把所有原来失效的源文件移走:

mkdir -p /etc/yum.repos.d/disabled mv /etc/yum.repos.d/CentOS-*.repo /etc/yum.repos.d/disabled/ mv /etc/yum.repos.d/epel*.repo /etc/yum.repos.d/disabled/

最后执行yum clean all && yum makecache。ISO 源虽然软件包版本是固定的,但作为应急安装基础依赖已经完全够用。需要注意,gpgcheck=0只适合这种离线临时环境,不要用到生产环境常规源上。

如果内网有专门的软件仓库服务器,那就用一台有外网的机器,通过reposync把归档仓库同步下来,再用createrepo生成元数据。注意reposync和createrepo分别属于yum-utils和createrepo包,在源失效前就要提前安装准备。

4.5 容器里跑的 CentOS 7 同样要改

Docker 容器里使用 CentOS 7 镜像,源失效问题一样会爆。我曾经遇到一个构建环境,容器内执行 yum install 时报同样错误。由于容器镜像大多是精简版,可能没有 vim 和 curl,直接用 sed 处理更省事:

sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-Base.repo sed -i 's|^#baseurl=|baseurl=|g' /etc/yum.repos.d/CentOS-Base.repo sed -i 's|http://mirror.centos.org/centos/$releasever|http://vault.centos.org/7.9.2009|g' /etc/yum.repos.d/CentOS-Base.repo yum clean all yum makecache

如果容器里连 sed 都没有,那就换基础镜像吧,这个系统太精简了,后面维护也会很痛苦。

5. 源修复只是应急:CentOS 7 之后的长期打算

5.1 修复完源,系统依然处于“裸奔”状态

yum 源修复可以让系统继续安装软件、继续做依赖解析,但这里必须把话说清楚: CentOS 7 已经停止维护,后续不会再有任何官方安全更新。修复源只是让这台机器“能继续工作”,并不代表它“安全”。线上业务如果还跑在 CentOS 7 上,等于一直暴露在没有安全补丁的状态下。

我的处理原则是:能用修复方案稳住现有环境,但同时在项目计划里给迁移安排一个明确的优先级。迁移的时间窗口越长,后续面临的风险就越高。至少需要梳理清楚下面几件事:

  • 当前所有运行在 CentOS 7 上的服务清单和依赖关系
  • 各业务的数据备份方案和备份验证结果
  • 配置文件的版本管理,尽量把手工改动的配置收进代码仓库
  • 可回滚的迁移方案,比如提前准备系统镜像快照或整机备份

5.2 三条迁移路线的取舍参考

从实际运维角度看,CentOS 7 迁移主要有三种方向。我用表格简单列一下对比:

迁移方向RHEL 兼容性迁移成本维护周期适合场景
CentOS Stream 8/9与 RHEL 同源,属于滚动发布的中间版本中等,yum 源和软件版本差异小按 Stream 版本独立节奏维护想继续留在 CentOS 生态,且能接受滚动更新模式
AlmaLinux / Rocky Linux面向 RHEL 兼容重建,社区维护稳定中等,可直接在 CentOS 7 上做系统迁移工具升级跟随 RHEL 生命周期,通常 8 到 10 年生产环境做平滑迁移,需要可靠长期维护
Debian / Ubuntu LTS不兼容 RHEL 体系,软件包格式不同较高,应用需要重新编译部署按各发行版 LTS 周期维护借机做架构升级,愿意接受更大的改动量

如果你只是想把现有业务尽快稳定住,我建议优先考虑 RHEL 兼容路线,迁移过程中业务系统的改动量最小。如果本身运维团队对 Debian 系更熟,而且应用没有强依赖 RHEL 的某些特性,第三条路线也不差。不要因为“换系统”听起来成本高就一直拖着,拖到官方源彻底不可用的时候,连应急修复的机会都会越来越少。

5.3 建议做一个源健康监控

CentOS 7 源已经处于“半只脚入土”的状态,它什么时候再次出现故障完全不可预测。与其被动等业务反馈,不如主动监控。我在处理完源问题后,给相关服务器加了一个简单的巡检脚本:

#!/bin/bash REPO_URL="http://vault.centos.org/7.9.2009/os/x86_64/repodata/repomd.xml" if ! curl -sI --connect-timeout 5 "$REPO_URL" | grep -qE "200|301|302"; then echo "$(date '+%F %T') CentOS 7 yum repo check failed: $REPO_URL" >> /var/log/yum-repo-check.log fi

放到 crontab 里每天跑一次:

crontab -e 0 6 * * * /opt/scripts/check-centos7-repo.sh

有告警可以直接发给值班群。这个脚本成本很低,但能避免下次源出问题时全业务一起踩雷。

5.4 一点个人经验

CentOS 7 源失效这个问题,我在不同环境里处理过很多次,最深的体会是:不要急着背命令,先把报错拆开看。是 DNS 解析失败还是 404,是单个仓库挂掉还是所有仓库挂掉,这决定了完全不同的处理路径。repomd.xml拉取失败和包安装失败是两回事,混在一起排查会浪费大量时间。

另外一点很实用:修改源配置时尽量做到“最小变更”。只注释该注释的mirrorlist,只替换该替换的 baseurl,不要把仓库文件里的其他参数顺手改掉,否则排查时你又多了一堆变量。每次改完都执行一次yum clean all && yum makecache做验证,别让旧缓存掩盖问题。

最后再分享一个小技巧。处理这类问题时,我会先把/etc/yum.repos.d/里所有.repo文件全部拉出来看一眼。很多 CentOS 7 服务器不止配置了官方源和 EPEL,还残留了各种第三方源和内部私有源。它们虽然平时不显眼,但在主源失效的同一个时间点,往往也会一起出问题。把整个目录里的仓库状态都过一遍,再针对性修复,远比盯着某一条报错要高效得多。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进