拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CentOS下安装yum全攻略:在线装、离线装、本地源搭建与报错恢复

CentOS下安装yum全攻略:在线装、离线装、本地源搭建与报错恢复

先说个可能反常识的事:CentOS 这系统,正常情况下 yum 是自带的,根本不用你费劲去装。但你要是搜过“Centos 下安装 yum”这个词,那大概率是遇到了下面某一种情况:最小化安装后 yum 神秘失踪、手贱把 python 升级结果 yum 罢工、或者系统里 rpm 依赖关系一团乱麻,yum 命令直接报-bash: yum: command not found。还有一些场景是离线内网环境,不能连外网,需要手工下载 rpm 包来搭 yum。

这篇文章我就把“装 yum”这件事彻底讲透,覆盖从“为什么 yum 会丢”到“在线装、离线装、本地源搭建、换国内源、常见报错修复”的完整链路。适合 CentOS 6/7/8/9 各版本的用户,也适合遇到 yum 被搞残想抢救一下的运维新人。我会把命令和背后的逻辑一起讲,保证你跟着做完不只是能跑通,还能理解每一步到底在干什么。

1. 先搞清楚 yum 的真面目:它其实只是个 python 脚本

很多人把 yum 当成系统自带的黑盒工具,坏了就不知道从哪下手。实际上 yum 的本质并不神秘:它是一组用 Python 写的包管理脚本,通过调用 rpm 去解析和安装软件包,然后从配置好的“软件源”(也就是 repo)里拉取元数据和 rpm 包,自动帮你解决依赖关系。

也正是因为 yum 是 Python 写的,它和你系统里的 Python 环境关系极其密切。CentOS 6 的 yum 依赖 Python 2.6,CentOS 7 的 yum 依赖 Python 2.7,CentOS 8 开始才转向 DNF(新一代 yum,底层也是 Python 3)。所以很多“yum 突然坏了”的案例,根子根本不在 yum 本身,而是有人把系统自带的 Python 给换掉或者升级了,导致 yum 找不到对应的解释器。这一点我建议你刻在脑子里,后面排错会省很多事。

1.1 什么情况下你才需要“手动安装 yum”

这不是制造焦虑,我按实际遇到的可能性从高到低排个序:

  • 最小化安装 CentOS 后,发现yum命令不存在。这种情况多见于精简版镜像、容器镜像或者自己裁剪过的系统。
  • 升级或误删了系统自带的 python,导致 yum 无法启动,此时会报There was a problem importing one of the Python modules之类错误。
  • 用rpm -e强行删除了 yum 相关包,清理依赖时连 repo 配置一起删了。
  • 在内网离线环境工作,新装的机器上什么都没有,需要手动把 yum 的 rpm 包拷进去装。
  • RPM 数据库损坏,yum 运行异常,需要重装 yum 来恢复。

如果你只是 yum 的源列表坏了,比如yum repolist空,或者安装时报 404,那根本不用重装 yum,只要重新配源就行。这部分我在第 4 章会重点讲。

1.2 yum、rpm、源三者的关系

yum 是“包管理门面”,但它底层不是直接操作文件的,它把所有脏活累活都交给 rpm 来完成。rpm 负责装包、卸包、查询包;yum 负责从远程仓库拉取元数据(repodata 目录下的文件),分析依赖树,决定“我应该先装 A,再装 B,最后装 C”,然后逐个调用 rpm 安装。源就是软件包和元数据存放的位置,可以是互联网上的镜像站,也可以是你本机挂载的光盘或 ISO 文件。

理解了这个三角关系,你就明白为什么“装 yum”这件事不是简单地丢一个绿色软件进去运行。你需要确保:

  1. yum 的 rpm 包本身装好了;
  2. 它依赖的 python 库(比如 urlgrabber、libxml2 等)是齐的;
  3. 有可用的源配置(.repo 文件)和源地址里的元数据。

2. 动手前必做的事:确认系统身份和剩余武器

别上来就复制网上的命令,先花两分钟查看系统情况。不同 CentOS 版本对应的 yum 版本和依赖不一样,用错了版本轻则装不上,重则把系统搞得更乱。

2.1 看清系统版本和架构

登录服务器后,依次执行下面几条命令:

cat /etc/redhat-release uname -m rpm -qa | grep -E '^yum|^rpm'

第一行告诉你系统是大版本,第二行告诉你 CPU 架构,第三行看当前还残留哪些 yum/rpm 相关包。输出示例:

CentOS Linux release 7.9.2009 (Core) x86_64 yum-3.4.3-168.el7.centos.noarch yum-plugin-fastestmirror-1.1.31-53.el7.noarch yum-metadata-parser-1.1.4-10.el7.x86_64

这里有两条信息很关键:noarch表示 yum 本身是纯脚本包,不区分架构;但yum-metadata-parser是 C 扩展模块,区分 x86_64 和 i386。下载时要注意和uname -m的结果一致。

2.2 确认还剩哪些“武器”可以用

在 yum 缺失的环境里,你反而要珍惜还能用的工具:

  • rpm 是否可用:rpm --version。只要 rpm 还在,你就能手动装包。
  • 有没有网络连通性:curl -I http://mirrors.aliyun.com或者ping -c 3 mirrors.aliyun.com。注意有些内网禁 ping 但允许 HTTP 访问,所以用 curl 更准确。
  • 有没有 wget / curl:which wget curl。如果都没有,你只能先在本地电脑下载好 rpm 包再传到服务器。
  • Python 版本:python -V。CentOS 7 应该是 Python 2.7.5,如果变成 3.x,那 yum 大概率已经“死”了。

我建议你把这几项结果记录下来,后面每一步都能用得上。有个小技巧:如果 rpm 还在但 yum 没了,你可以用rpm -qa | wc -l看看系统装的包总数。如果总数正常,说明只是 yum 层被删了;如果总数也很少,那这个系统可能是裁剪版或容器底,后续补依赖的工作量会大很多。

3. 完整实操:两条路把 yum 装回去

这一章是核心,分“在线安装”和“离线安装”两条路线。在线安装适合还能连外网的机器,离线安装适合内网、隔离网段或特殊要求的场景。

3.1 在线安装:从镜像站直接拉 rpm 包

先说一个误区,很多人会直接敲yum install -y yum。问题是现在 yum 都没了,系统根本执行不了这命令。正确做法是先用 rpm 方式把 yum 包装回去,然后再用 yum 自己修复其他缺失的依赖。

以 CentOS 7.9 x86_64 为例,完整命令序列如下:

cd /tmp curl -O http://mirrors.aliyun.com/centos-vault/7.9.2009/os/x86_64/Packages/yum-3.4.3-168.el7.centos.noarch.rpm curl -O http://mirrors.aliyun.com/centos-vault/7.9.2009/os/x86_64/Packages/yum-plugin-fastestmirror-1.1.31-53.el7.noarch.rpm curl -O http://mirrors.aliyun.com/centos-vault/7.9.2009/os/x86_64/Packages/yum-metadata-parser-1.1.4-10.el7.x86_64.rpm

先解释一下为什么是centos-vault:CentOS 7 已经进入 EOL(生命周期结束)状态,普通路径下官方源只保留最新版本,旧版本的 rpm 包全部归档到 vault 库里。阿里云镜像站有对应的 vault 目录,这是国内访问速度非常稳的地址。如果你用的是 CentOS 8 或更早的版本,路径结构类似,只要把版本号和目录名替换掉即可。

下载完成后,按依赖顺序安装:

rpm -ivh yum-metadata-parser-*.rpm rpm -ivh yum-plugin-fastestmirror-*.rpm rpm -ivh yum-*.rpm

这套顺序的讲究是:先装底层的 C 扩展(metadata-parser),再装插件,最后装主程序。如果你用rpm -ivh yum-*.rpm一次性装,rpm 也会尝试解析本地文件中的依赖,但遇到缺其他包时照样会报错。所以一步步来更稳妥。

装完验证:

which yum yum --version

如果提示缺其他依赖,比如python-urlgrabber,那就用同样的方式从镜像站下载对应包再装上:

curl -O http://mirrors.aliyun.com/centos-vault/7.9.2009/os/x86_64/Packages/python-urlgrabber-3.10-10.el7.noarch.rpm rpm -ivh python-urlgrabber-*.rpm

很多新手卡在这一步就慌了,其实完全不用。yum 的依赖包分布在同一个 Packages 目录下,缺什么补什么,缺几个补几个,用rpm -ivh逐个装上即可。

3.2 离线安装:U 盘/内网传输 rpm 包的四步法

离线环境是 yum 安装最典型的应用场景。你在一台能上网的电脑上下载好所有包,然后传到目标服务器。核心思路和在线安装一样,只是多了“传递”这一步。

第一步:在一台同版本 CentOS 的联网机器上准备下载目录:

mkdir /tmp/yum-rpms && cd /tmp/yum-rpms

第二步:用 yum 的“仅下载不安装”功能批量拉取 yum 及相关依赖:

yum install --downloadonly --downloaddir=/tmp/yum-rpms yum

这条命令会把 yum 以及它依赖的所有包都下载到指定目录,省去你手动分析依赖关系的痛苦。如果手头这台机器也没有 yum 了,那就只能退回到手动 curl 方式,逐个下载我在 3.1 列出的包。

第三步:把/tmp/yum-rpms目录整个打包,传到目标机器:

tar czf yum-rpms.tar.gz yum-rpms

可以用scp、U 盘拷、甚至python -m SimpleHTTPServer临时起个 HTTP 服务让内网机器下载,看现场情况方便。

第四步:在目标机器上执行本地安装:

tar xzf yum-rpms.tar.gz cd yum-rpms rpm -ivh *.rpm

这里有个注意事项:rpm -ivh *.rpm会尝试按文件名顺序安装,如果运气不好依赖顺序不对,会提示failed dependencies。这时不用重来,改成:

rpm -ivh --nodeps *.rpm

但--nodeps相当于禁用依赖检查,能装上不代表运行正常,装完一定要执行yum --version验证。如果 yum 能正常输出版本号,说明风险可控;如果报 Python 导入错误,那说明缺了 python 的某个模块,还得继续补。

3.3 装完 yum 后立刻要做的事

装好 yum 之后千万别急着用,先做三件事:

  1. 用rpm -qc yum查看 yum 的配置文件是否完整,确认/etc/yum.conf存在且内容不少于十行。
  2. 检查/etc/yum.repos.d/目录,看是否还有.repo文件。如果没有,yum 会提示找不到源,这就是为什么很多人“装完 yum 还是用不了”的原因——光有客户端没有源配置。
  3. 执行yum clean all清一下可能的缓存或脏数据,确保从干净状态开始。

如果你是在线机器,可以直接跳到第 4 章换源;如果连的都是内网源或本地源,也要继续往下看,把源配置好才是最终目标。

4. 装完 yum 第一件事:把 yum 源配置利索

很多教程把“装 yum”和“配 yum 源”混在一起讲,容易让人混淆。装 yum 是把客户端软件装好;配源是告诉 yum 去哪里找软件包。两个环节缺一不可。

4.1 本地 yum 源:离线内网必备技能

本地源通常分两种:一种是挂载 ISO 镜像作为源,一种是把已有的 rpm 包目录制作为源。它们都适合内网离线环境。先讲最常见的 ISO 光盘源。

假设你已经把 CentOS 的 ISO 文件上传到了服务器/opt目录下:

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

如果/mnt/cdrom不存在就mkdir -p创建。挂载后检查一下:

ls /mnt/cdrom/Packages/ | head ls /mnt/cdrom/repodata/

看到repodata目录才说明这个 ISO 包含完整仓库元数据,可以作为 yum 源。接下来创建.repo文件:

vi /etc/yum.repos.d/local.repo

写入以下内容:

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

gpgcheck=0是跳过 GPG 签名验证。本地源图省事可以这么写,但如果安全要求高的环境,建议把gpgcheck=1并设置gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7,避免装到被篡改的包。

然后:

yum clean all yum repolist

正常情况下会看到Local CentOS ISO这个仓库,且包数量在几千个左右。

第二种场景更进阶:你手里有一堆散落的 rpm 包,想做成一个本地源,让局域网内其他机器也能用。这时需要createrepo工具生成元数据:

yum install -y createrepo # 如果 yum 还没法用,就从 ISO 里 rpm 安装 mkdir -p /data/yumrepo cp /path/to/*.rpm /data/yumrepo/ createrepo /data/yumrepo

之后把/data/yumrepo通过 Nginx 或 HTTP 服务暴露出去,客户端在.repo里写baseurl=http://你的IP/yumrepo即可。这就是很多内网环境“离线安装 docker、离线安装 nodejs、离线安装 maven”的底层套路。

4.2 更换国内镜像源:阿里云源的完整配置方法

在线机器装完 yum 后,默认源指向mirror.centos.org,在国内访问速度通常不佳。换源是必须的一步。

以 CentOS 7 为例,先把官方源备份(有后悔药),再替换:

mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak

从阿里云镜像站下载对应版本的 Base 源:

curl -O http://mirrors.aliyun.com/repo/Centos-7.repo mv Centos-7.repo /etc/yum.repos.d/CentOS-Base.repo

然后可选安装 epel 扩展源:

curl -O http://mirrors.aliyun.com/repo/epel-7.repo mv epel-7.repo /etc/yum.repos.d/epel.repo

epel(Extra Packages for Enterprise Linux)是 EPEL 社区维护的扩展软件仓库,里面有很多不在官方源里的常用软件。yum install -y epel-release也是热门搜索词,原理一样,只是通过软件包方式安装。

最后清理重建缓存:

yum clean all yum makecache yum repolist

CentOS 8 或 Stream 9 的换源过程大同小异,主要区别是.repo文件名和路径不同。CentOS 8 还要注意模块化源的配置,别把 AppStream 和 BaseOS 两个源漏掉。

4.3 高频源操作技巧:exclude 和 update 控制

配好源之后,有几个我建议你提前知道的细节:

  • 内核版本一旦更新,可能需要重启才生效,而且有停服风险。生产环境执行更新时可以用:
yum update -y --exclude=kernel*

这个方式在处理生产服务器内核敏感期的场景中非常实用,能防止 yum 顺手给你升级内核。

  • yum install -y yum-utils device-mapper-persistent-data lvm2这条命令很常见,是用来装 docker 前置依赖的。如果你执行后发现没反应或提示无效,先看源里有没有这些包,再确认yum makecache是否成功。很多时候问题不在命令本身,而是缓存不完整。

  • 批量下载某个软件及其所有依赖的 rpm 包,可以这样:

yum install --downloadonly --downloaddir=/root/rpms docker-ce

这在做内网离线安装 docker、离线安装 nodejs、离线装 maven 场景下极其好用。把下载好的 rpm 包带到内网,配合本地源,就能在不连外网的情况下完成部署。

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

这章是我戴过“镣铐”后的经验总结。yum 安装和使用中踩过的坑,比文档里写的多得多,我挑高频的、典型的列出来。

5.1 rpm 安装时的 dependency 报错

典型报错:

error: Failed dependencies: python-urlgrabber is needed by yum-3.4.3-168.el7.centos.noarch

很多人卡在这里就不知道怎么办了。不用慌,按我 3.1 的步骤,去源路径下搜索python-urlgrabber,下载同版本 rpm 后装上,再重新装 yum。这里有个技巧:在阿里云镜像站网页上,可以直接进Packages/目录按文件名搜索,找到后右键复制链接。如果你能联网,用curl下载最快;如果不能联网,用个人电脑下载再传进去。

也可以换一种思路,用rpm -Uvh代替rpm -ivh。-U是升级安装,如果系统里已经存在旧版本的依赖,它有时能更平滑地处理。但要注意:如果系统里某些包版本比你要装的还新,-U也可能报错,这时你需要尊重版本依赖,去找匹配的版本。

5.2 yum makecache 报 metadata 错误的排查

典型报错类似:

Errors during downloading metadata for repository 'base': - Status: 404 Not Found

这个基本可以确定是源地址不对或版本目录不对。排查步骤:

  1. 看报错里是哪个 repo:yum repolist -v。
  2. 打开对应的.repo文件,检查baseurl路径是否真实可访问。
  3. 用 curl 试一下:curl -I http://mirrors.aliyun.com/centos-vault/7.9.2009/os/x86_64/repodata/repomd.xml。能返回 200 说明路径可用。
  4. 如果 404,多半是版本号不对,或你用了已不再维护的地址。

CentOS 7 已经 EOL 后,很多人的报错都出在旧链接失效。这个问题在 CentOS 6、7、8 上太典型了。记住一个原则:旧版本用vault路径,新版本用当前路径,不要把两者搞混。你在网上搜到的教程如果是两三年前写的,很多链接已经失效。

5.3 yum 报错 but there is no python module named yum

这是“yum 和 python 关系”问题的典型体现。通常发生在你升级/替换了系统 python 之后,此时 yum 脚本试图用新 python 运行时,发现找不到 yum 模块。

解决办法分两种:

  • 如果系统的/usr/bin/python被软链接指到了别的版本,把它改回来:
ls -l /usr/bin/python ln -sf /usr/bin/python2.7 /usr/bin/python

CentOS 7 上/usr/bin/python应该指向python2.7。这是最简单有效的修复方法。

  • 如果你发现系统里原本的 python2.7 已经被删了,那就麻烦一些,需要重新安装 python2.7 包。这又是一个“离线安装包”的场景,可以从镜像站下载python-2.7.5-*.rpm和依赖包,用 rpm 装回去。建议先检查/usr/libexec/urlgrabber-ext-down是否还在,它是 yum 下载模块的重要依赖组件,经常跟着 python 一起被误删。

5.4 yum 命令存在但所有操作都报 Cannot find a valid baseurl

这个报错和 yum 本身没关系,是源配置或网络的问题。我见过不少运维在这个坑里浪费半天时间。按以下优先级依次排查:

  • 网络能不能通到源服务器:ping -c 2 mirrors.aliyun.com。如果不通,检查网卡 IP、网关、DNS。热词里“centos ping 不通网关”就是这个场景。
  • 代理是否配置:cat /etc/yum.conf看有没有proxy=...配置。有些内网环境需要代理才能访问外网源。
  • 源文件是否写了正确的baseurl,或者变量$releasever、$basearch是否被正确替换。你可以敲yum repolist -v看到最终解析出来的 URL,直接拿这个 URL 去 curl 验证。
  • DNS 解析是否正常:cat /etc/resolv.conf,确认 nameserver 是可用的。

我遇到过最离谱的一次,是客户机房把 80 端口出方向给禁了,yum 所有请求超时,最后放行 80 端口才解决问题。所以如果 curl 通但 yum 不通,一定要查防火墙和安全策略。

5.5 yum 安装一个很想要的包,却提示 No package matching

这种情况常见于:

  • 源里根本没有这个包。解决办法:启用 epel 源,或者在线上搜索该包属于哪个仓库。
  • 仓库优先级问题,某个源被禁用了:检查/etc/yum.repos.d/下各.repo文件里enabled=0的仓库,以及yum --enablerepo=xxx install 包名的用法。
  • 缓存过期:先yum clean all && yum makecache,再装。

顺带说一个实用技巧:如果你不确定包在哪个源里,可以用yum provides 文件名反查。比如你知道有个可执行命令叫redis-cli,但不知道属于哪个包,执行yum provides redis-cli就能查到它属于redis这个包,这样就不会装错。

6. 一些我踩坑后留下的心得

最后分享几条我在实际环境中积累的经验,不一定写在官方文档里,但非常管用。

第一,凡是涉及到对 yum 大动干戈的操作,强烈建议先备份/etc/yum.repos.d/整个目录,再顺手备份一下/etc/yum.conf。改坏了随时回滚,比什么都强。备份的成本只有一行命令,修复的成本可能是一整晚。

第二,不要去“优化”系统自带的 Python 环境。很多 CentOS 系统的 Python 2.7 看起来版本旧,但它和 yum 是深度绑定的。你装新软件需要 Python 3 时可以并行安装python3包,不要动/usr/bin/python这个默认解释器的指向。我在生产环境见过太多次因为升级 Python 导致 yum 崩溃的例子。

第三,离线环境下,养成“下载 yum 包时连依赖一起拉全”的习惯。用yum install --downloadonly --downloaddir而不是手动一个个拷贝。因为你永远猜不到目标机器缺哪个依赖,把整个依赖树拉回来,才能在离线环境里从容应对。

第四,如果要在内网搭建 yum 源,不一定要用复杂架构。最简单可靠的做法就是一台机器挂 ISO 镜像 + 一台机器把下载目录通过 Nginx 共享,再写几个干净的.repo文件。这套方案我已经在不同项目里用过很多次,离线装 docker、nodejs、maven 全都能覆盖,稳定得很。

yum 这东西用好了不觉得稀奇,一旦坏了才知道它有多重要。希望这篇整理能让你少走一些弯路,遇到问题时有章可循,不用再全网搜零散答案。

返回列表