☰
CentOS 7 yum源404修复与Docker安装指南
2026/10/16 3:32:50 网站建设 项目流程

如果你手头还有一台 CentOS 7,大概率在某次yum操作时撞到过这种画面:命令行先卡在 Loading mirror speeds,接着冒出一串Could not resolve host、HTTP Error 404 - Not Found,最后以[Errno 14]收尾。别急着怀疑网络,也别急着重装系统,这多半是 yum 源文件里的官方地址已经失效了。这篇内容以我实际维护的一台 CentOS 7 老机器为线索,从源故障的定位与换源讲起,一直到 Docker 环境顺利装好并调好关键运行参数,所有命令都能直接复制执行,重点把最容易踩坑的源文件处理、GPG 校验和依赖冲突单独拿出来说明。

1. 故障定位:先搞清是网络问题,还是 yum 源本身废了

1.1 yum 报错现场的几种典型表现

我这次遇到的第一反应是执行yum makecache,结果输出比平时长很多,一直停在Determining fastest mirrors,然后刷出类似内容:

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

又或者直接这样:

Could not resolve host: mirrorlist.centos.org; 未知的错误

还有一种隐蔽情况是安装了第三方扩展源,比如某个 EPEL 扩展源文件里写着旧地址,yum install安装任何包时都会因为Cannot retrieve metalink for repository直接中断。单看报错,特别像 DNS 故障,因为curl解析不了域名,但实际上换个yum源就能解决一大半问题。

判断故障范围有一个笨办法:先把yum换源动作放一边,手动访问一下报错里出现的域名。比如:

curl -I http://mirrorlist.centos.org

如果返回 404 或者超时,基本可以确定是本机之外的仓库端问题;如果连域名解析都对不上,再查/etc/resolv.conf和网络连通性。网络修完发现 yum 还是报同样错误,那基本就坐实了是本地源配置太老。

1.2 为什么 CentOS 7 的默认源会集体失效

CentOS 7 进入维护停止阶段后,官方把历史版本的软件包全部转移到了归档目录,之前常规使用的mirrorlist.centos.org和mirror.centos.org路径不再继续同步。也就是说,服务器上原有/etc/yum.repos.d/CentOS-Base.repo里指向的这些地址,虽然配置文件还在,但远端目录已经不存在了,结果必然是一大串 404。

另一个更容易被忽略的点是公共镜像站的上游同步策略。很多镜像站点会逐步清退已经停止维护的发行版目录,就算你的仓库文件指向的是某个公共镜像路径,镜像站上游一旦不再同步 CentOS 7,本地执行yum clean all && yum makecache依然会失败。所以不要把希望寄托在“旧地址还能用”上,正确做法是主动切换到归档源或仍然提供 7 版本的镜像站。

以前我们不常碰这种问题,是因为源文件会随着发行版更新一起换掉。但 CentOS 7 已经不再有常规更新,源文件自然就停留在老状态。换句话说,这台机器自己不会好,必须手动干预。

1.3 动手换源前,先做三个确认

换源之前,我建议按下面顺序操作,能省下不少后面排查的时间。

第一,确认本机网络。不要用ping,很多环境禁 ICMP,最好用 curl 访问一个稳定页面,比如curl -I https://www.centos.org,能拿到 HTTP 响应头说明网络没问题。第二,查看/etc/yum.repos.d/目录里到底有哪些源文件,用ls -l /etc/yum.repos.d/,把官方源和第三方源分清楚,别一股脑全禁用。第三,检查系统时间,date -R看一眼,如果系统时间偏差太大,HTTPS 请求会因为证书校验失败出现各种奇异报错,很多人忽略这一项。

2. 恢复 yum 源:备份、换源、清理缓存一条龙

2.1 动手前先备份,而不是直接删配置

我见过有人直接rm -rf /etc/yum.repos.d/*.repo,然后从网上复制新配置。这个方法能用,但最大的问题是不可回滚,而且如果新配置写错,连排查的参照物都没了。更稳的做法是先把旧配置挪走:

mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/

备份后ls /etc/yum.repos.d/应该是空的,后续所有的.repo文件都是我们自己创建的,降低混乱程度。

这里多说一句,如果只是某个第三方源失效,但官方源还能用,不要连官方源一起备份迁移。尽量只禁用出问题的源,把影响面控制在最小范围。老机器上跑的存量服务没人知道依赖什么,多动一次手就多一分风险。

2.2 生成新的源文件,指向归档源或可用镜像

对于 CentOS 7,最稳的基础源是官方归档地址vault.centos.org。我在/etc/yum.repos.d/下新建了CentOS-Base.repo,内容如下:

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

注意我写的是7.9.2009而不是$releasever。原因很简单:$releasever在 CentOS 7 上会解析成7,但归档目录的真实结构里更多能看到7.9.2009这种具体版本号。虽然部分路径做了软链,但为了减少不确定性,直接把版本写死更省心。

如果你所在网络访问vault.centos.org速度不理想,可以把baseurl换成你实测可用的公共镜像站地址。绝大多数镜像站保留的路径格式是https://镜像站基础路径/centos/7/os/x86_64/,注意确认一下该镜像站是否还同步 CentOS 7。至于具体选哪家,我的建议是去镜像站帮助页看同步状态,不要听别人说可以用就直接写上去,否则还是会遇到 404。

2.3 处理 GPG 密钥,这步不能图省事跳过

很多人换了源以后跑yum install,会在末尾看到GPG key retrieval failed或者Public key for xxx.rpm is not installed。这是因为新源启用了gpgcheck=1,但本机没有导入对应的签名公钥。

CentOS 7 的官方公钥通常已经躺在/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7里。如果系统没导入,手动导入一下:

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

个别情况下,镜像站使用的是自己签发的密钥,那需要在源文件的gpgkey字段里写镜像站提供的密钥地址。这里千万注意,不要遇到密钥错误就把gpgcheck=0关闭。老环境最怕依赖包被替换,开启 GPG 校验至少能挡住一层低级风险。

清缓存并验证源状态:

yum clean all yum makecache yum repolist

如果makecache正常结束,能看到 base、updates、extras 三个仓库的元数据下载成功,这一阶段就算过关了。我个人习惯再做一次yum install -y yum-utils,因为后面配置 Docker 源时要用到yum-config-manager,提前装好省得来回折腾。

3. 安装 Docker:源正确了,依赖问题也少一大半

3.1 安装前先看一眼系统底子

Docker 在 CentOS 7 上能跑,但先要确认内核符合条件。执行:

uname -r

CentOS 7 默认内核一般是 3.10.x,Docker 官方也是按这个内核做兼容。基础容器运行没问题,但如果以后要跑比较新的镜像,建议评估是否升级内核。老服务器生产环境我一般不轻易升级内核,除非有明确需求,比如要用到更新内核模块或新特性。

还要看下内核是否加载了相关网络模块,避免后面 iptables 报错。至少确认/proc/net/ip_tables_names存在,或者:

lsmod | grep -E "iptable_nat|ip_tables"

如果输出为空,可能需要先加载模块。更常见的坑是安装完 Docker 启动时报 iptables 相关的 NAT 失败,这时候检查系统是否启用了 firewalld,或者 iptables 服务是否被 disable。测试环境可以临时systemctl stop firewalld,但生产环境要谨慎,因为停下来会影响防火墙规则。

3.2 添加 Docker 仓库,并解决 404 问题

CentOS 7 上安装 Docker,我不建议用发行版自带的旧版本 Docker 包,而是用 Docker 官方仓库或可信镜像仓库。官方仓库地址是:

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

yum-config-manager来自yum-utils,前面如果已经装好了,这里就能直接用。它会生成一个/etc/yum.repos.d/docker-ce.repo文件,里面包含 stable、test、nightly 等仓库源,默认启用的通常是 stable。

如果download.docker.com访问不了,或者你觉得速度太慢,可以把仓库文件里的 baseurl 改成自己可达的镜像路径。具体做法是生成文件后执行:

sed -i 's#download.docker.com#你选定的镜像地址#g' /etc/yum.repos.d/docker-ce.repo

注意这个替换会把多个字段一起改动,改完后仔细看一眼docker-ce.repo,确认路径格式是linux/centos/7/x86_64/stable,别把多级路径拼错。我实际遇到过一次镜像站路径缺了linux一级,导致 yum 报 404,排查时看了半天才发现是 URL 结构不一致。

添加完成后,再做一次yum makecache fast,然后直接安装:

yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

如果只想装最小运行环境,docker-ce、docker-ce-cli、containerd.io 三个包就够了。docker-buildx-plugin和docker-compose-plugin属于扩展工具,能装就装上,后面处理多阶段构建和编排项目会方便很多。

3.3 依赖冲突的经典场景:container-selinux

在较老的 CentOS 7 上,执行上面的安装命令时很容易出现类似提示:

Error: Package: containerd.io-x.x.x requires container-selinux >= 2.107

这是因为 Docker 相关组件依赖较新的container-selinux,而系统自带的版本太老,且软件源里可能找不到匹配版本。网上有人建议用--skip-broken跳过依赖,我强烈不建议这么做,跳过依赖会让运行时行为不可控,后面容器起不来更麻烦。

正确顺序是先在 extras 源里找container-selinux:

yum install -y container-selinux

如果 extras 源本身已经失效或版本不满足,就去归档源里手动找对应 rpm。比如从vault.centos.org/7.9.2009/extras/x86_64/Packages/下找到container-selinux-*.rpm,用rpm -Uvh本地安装,再重新执行 Docker 安装命令。我处理过的一台机器就是这样,前后多了几分钟,但整个依赖树是完整的,后续没再出问题。

安装完成后启动并设置开机自启:

systemctl start docker systemctl enable docker systemctl status docker

如果是刚装好的干净环境,systemctl status docker会显示 active (running)。再跑一个docker version,能看到 Client 和 Server 的版本信息,只要 Server 段不是报 failed to connect,说明 Docker 系统服务已经正常。

4. 运行时配置:别装完就以为万事大吉

4.1 daemon.json 里几个值得提前调的参数

Docker 装好后,默认配置可以直接用,但不建议直接用。生产环境常见的磁盘写满、日志爆炸、内核防火墙冲突,很多都能通过一个配置文件提前规避。我习惯创建/etc/docker/daemon.json:

{ "registry-mirrors": ["https://docker.mirrors.example.com"], "exec-opts": ["native.cgroupdriver=systemd"], "storage-driver": "overlay2", "log-driver": "json-file", "log-opts": { "max-size": "50m", "max-file": "3" } }

逐项解释一下:

registry-mirrors配置镜像加速地址,国内网络拉公共镜像会快很多,但这里要填你实际可用的加速器或内部仓库地址,不要迷信网上随便找的地址。exec-opts里的native.cgroupdriver=systemd特别重要,尤其当你以后计划在这台机器上跑 Kubernetes 相关组件时。Docker 默认 cgroup 驱动是 cgroupfs,而 kubelet 默认用 systemd,两者不一致会直接导致节点状态异常。即使现在不用 k8s,我也建议一开始就统一成 systemd,省得后期改驱动造成存量容器需要重启。

storage-driver用 overlay2,这是现代 Docker 的默认存储驱动,性能和稳定性都优于老的 devicemapper。但要注意,如果根文件系统是 XFS 且格式化时没开启ftype=1,overlay2 会拒绝使用,Docker 启动时会报错。遇到这个情况先执行:

xfs_info / | grep ftype

如果输出ftype=0,说明文件系统不支持 overlay2,要么重新格式化分区并显式添加-n ftype=1,要么临时把 storage-driver 改成vfs。vfs 性能差,适合临时测试,生产环境要重新规划存储。

日志配置也很实用。json-file加max-size和max-file,能让单个容器日志最高 50MB、最多保留 3 个文件,避免长时间运行的容器把磁盘塞满。之前踩过一次坑,一个打印大量日志的服务一天写了十几 GB,磁盘直接告警,从那以后我新建任何 docker 环境都会带上这个配置。

4.2 重启并验证配置生效

配置写到/etc/docker/daemon.json后,要重启 Docker 才会生效:

systemctl restart docker docker info

重点看输出里的几行:Cgroup Driver是不是 systemd,Storage Driver是不是 overlay2,Registry Mirrors里有没有你配置的地址。如果显示Cgroup Driver: cgroupfs,说明 daemon.json 里exec-opts写的位置不对或者 JSON 格式有问题,重启不会报错但配置也没加载。检查 JSON 可以用:

python -m json.tool /etc/docker/daemon.json

这个命令专门用来校验 JSON 语法,命令行只报你能看懂的错误。我见过有人少写一个逗号或引号,系统不会主动告诉你,最后发现配置没生效才回头查这里。

Docker 配置验证好以后,跑一个最小化容器确认链路完整:

docker run --rm hello-world docker ps -a

hello-world是个极小的镜像,能成功下载并退出,说明 pull、run、容器运行时这几条链路都正常。如果pull阶段就超时,优先检查registry-mirrors地址是否可用,再查 DNS 和相关防火墙。

5. 常见问题与排查技巧实录

5.1 高频报错速查表

报错现象常见原因解决办法
Could not resolve host: mirrorlist.centos.org官方源域名不再提供解析或 DNS 异常换 vault 源或可用镜像站
HTTP Error 404 - Not Foundduring makecache源路径已归档 / 镜像站清退大版本用 7.9.2009 明确版本路径
GPG key retrieval failed公钥未导入或 gpgkey 地址不可达rpm --import对应公钥文件
Package docker-ce is not availableDocker 仓库文件未生效检查/etc/yum.repos.d/docker-ce.repo
container-selinux >= 2.107requiredextras 源里没有匹配依赖单独安装 container-selinux 后重试
Failed to create NAT chainon docker startiptables 或 firewalld 异常确认内核模块、临时停 firewalld 测试
docker.sock: connect: permission denied当前用户不在 docker 组把用户加入 docker 组或使用 sudo
overlay2 文件系统不支持XFS 未开启 ftype=1xfs_info查看,重新格式化或换 vfs

这张表基本是我这几年在老机器上维护环境时整理出来的高频问题。看报错不要只看最后一行,要往前面翻,yum的输出里往往已经给出了失败的具体 repo 路径。

5.2 几个实用但容易忽略的小技巧

第一,保留旧源配置文件备份的好处不只是回滚。当系统真正要迁移或重装时,备份里能看出原来装过哪些第三方源,这对排查历史依赖很有参考价值。所以备份目录我通常保留一段时间,不会修完源就马上清理。

第二,遇到yum下载缓慢或无响应,可以考虑给/etc/yum.conf里加超时参数:

timeout=30

这个参数控制每个请求的超时时间,默认值往往是很长,网络不佳时很容易卡死。调短以后失败会快速返回,至少能立刻知道是哪个源出问题。

第三,如果 Docker 服务突然挂掉,不要急着重启,先看日志:

journalctl -u docker --no-pager -n 50

很多启动失败的原因记录在这里。最常见的是 daemon.json 配置错误、磁盘空间不足、iptables 规则加载失败。日志里会把具体错误路径或配置项名写出来,比自己翻配置快很多。

第四,关于镜像加速地址,建议你实际测试再写入 daemon.json。有的加速地址只是临时有效,过了段时间就返回 401 或超时。换个思路,如果你有一台带宽好的内网服务器,可以部署一个轻量级镜像仓库作为私有 registry,把常用镜像缓存进去,稳定性反而更高。这一步扩展性很强,后续不管做 CI 还是部署都能复用。

个人在处理这类老环境时最大的感受是:先备份,再验证,每个阶段用命令确认结果,不要一口气把所有配置全改完再回头看。源故障不要动不动就重装系统,因为你不知道系统上跑了多少个存量依赖;把源和依赖修好,后面装 Docker 就是水到渠成的事。这套思路不仅适用于当前这台 CentOS 7,遇到其他进入维护停止期的发行版一样能派上用场。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询