1. CentOS7 换源这件事,为什么现在还得认真做一遍
CentOS7 这个系统现在的处境有点微妙——2024 年 6 月 30 日官方正式给它画了句号,原来mirror.centos.org上挂着的centos/7目录被整体搬进了归档路径centos-vault/7.9.2009,很多机器上敲一条yum install就直接甩出一屏Cannot find a valid baseurl for repo: base/7/x86_64。偏偏大量存量业务、教学环境、内网实验机、老硬件上的定制系统还在跑 CentOS7,学校里做实验还在问"Linux 配置本地 yum 源实验目的是什么",所以把 yum 源换掉、把 yum 安装软件和卸载软件这套基本功重新捋顺,依然是绕不开的日常活。
这篇东西我会把几种换源方案摊开讲:网络源怎么改成国内镜像、完全断网的机器怎么用 ISO 搭本地源、两套源怎么排优先级不打架;再往下把 yum 安装、卸载、离线批量下载、history 回滚和一堆红字报错逐个拆开。适合刚接触 Linux 的新手照着抄,也适合老手检查一下自己那套脚本是不是还停留在mirror.centos.org的年代。
1.1 官方源停更之后,你的机器上到底发生了什么
很多人以为"停更"就是不再推送安全补丁了,其实更直接的影响是仓库地址失效。CentOS7 默认的/etc/yum.repos.d/CentOS-Base.repo里,base、updates、extras三个仓库的baseurl指向的是http://mirror.centos.org/centos/$releasever/os/$basearch/,而mirrorlist指向的mirrorlist.centos.org这个动态解析服务也已经停止对外提供 CentOS7 的列表。
$releasever在 CentOS7 上取值就是7,$basearch一般是x86_64。这两条路径拼起来最终解析到http://mirror.centos.org/centos/7/os/x86_64/,而实际的包现在躺在了https://vault.centos.org/7.9.2009/os/x86_64/。路径里的7变成了7.9.2009这个精确版本号,这就是报错的根源。
顺带说一个容易忽略的点:CentOS7 的小版本号很重要。你的系统是 7.6、7.7 还是 7.9,装的包版本不一样,但换源时统一指向7.9.2009是安全的——yum 会自己挑出比当前系统新的包做升级,不会把系统版本号强行改掉。除非你有极其严格的版本一致性要求,否则没必要去找对应小版本的 vault 目录(vault.centos.org上确实有 7.0 到 7.9 的每一版,但没必要自找麻烦)。
1.2 换成国内镜像,快的到底是哪一段
有人会问:换源不就是把域名换一下吗,能有多大差别?差别在两点,一个是带宽,一个是可达性。
vault.centos.org的服务器在国外,跨洋链路的丢包和抖动很常见,装个gcc、kernel-devel这种大包,慢的时候几 KB/s,一条yum install -y epel-release能等到你想关终端。国内几家镜像站——阿里云、清华 TUNA、中科大 USTC、华为云——都保留了 CentOS7 的 vault 副本,走国内线路,实测下载速度从几百 KB/s 跳到几 MB/s 是常态。
可达性这块更关键。有些内网出口做了白名单,mirror.centos.org直接不通,vault.centos.org也未必通,但mirrors.aliyun.com一般早就在放行列表里了。换源这个动作,一半是为了快,一半是为了能通。
注意:镜像站的 vault 目录是只读归档,不会再有新包进来。这意味着换完源之后,
yum update是能正常跑的,但不会带来新的安全更新。真正在意安全补丁的线上环境,该考虑的是迁移到还在维护周期的发行版,换源只是让老机器能继续装包、能继续维护。
1.3 动手之前先确认三件事
换源之前花两分钟做三个确认,能省掉后面半小时的排查。
第一是系统版本和架构。cat /etc/redhat-release看版本,uname -m看架构。大多数是x86_64,但如果是 ARM 机器(比如某些国产平台的服务器),仓库地址里的$basearch会解析成aarch64,路径不一样,直接照抄 x86 的配置会 404。
第二是网络通不通。ping -c 3 mirrors.aliyun.com,或者更准一点用curl -I https://mirrors.aliyun.com/centos-vault/。如果 DNS 有问题,ping会提示Name or service not known,这时候得先修/etc/resolv.conf,比如加一行nameserver 223.5.5.5,换源才有意义。
第三是有没有 ISO 文件。如果这台机器完全断网,走本地源方案,需要提前把CentOS-7-x86_64-DVD-2009.iso(大约 4.4 GB)传到这台机器或者它的宿主机上。虚拟机的话直接在虚拟光驱里挂载就行。
顺手再备份一下现有配置:
mkdir -p /root/repo-bak cp -a /etc/yum.repos.d/ /root/repo-bak/这个备份看着多余,但当你手抖写错一个字符,把三个仓库全搞挂的时候,它就是救命稻草。
2. 三套换源方案,按环境对号入座
换源这件事不存在"唯一正确答案",得看机器处在什么网络环境里。有外网的走网络源,纯内网的走本地源,内网但有代理或部分白名单的可以两套并存。下面三套方案按场景分开写,别混着抄。
2.1 方案A:网络源替换,最省事的一条路
网络源的核心动作就一句话:把CentOS-Base.repo里的mirrorlist注释掉,baseurl改成镜像站地址。最不容易出错的做法是直接把文件重写,别用sed一行行抠,sed的转义和路径拼接很容易翻车。
下面是我常用的阿里云版本,以7.9.2009为准,四个仓库base、updates、extras、centosplus全配齐:
cd /etc/yum.repos.d/ mv CentOS-Base.repo CentOS-Base.repo.bak cat > CentOS-Base.repo <<'EOF' [base] name=CentOS-7 - Base - mirrors.aliyun.com baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/os/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 enabled=1 [updates] name=CentOS-7 - Updates - mirrors.aliyun.com baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/updates/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 enabled=1 [extras] name=CentOS-7 - Extras - mirrors.aliyun.com baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 enabled=1 [centosplus] name=CentOS-7 - Plus - mirrors.aliyun.com baseurl=https://mirrors.aliyun.com/centos-vault/7.9.2009/centosplus/$basearch/ gpgcheck=1 enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 EOF几个设计说明。gpgkey我写成file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7而不是镜像站的 URL,原因是系统自带的这个密钥文件本来就是可信的,走本地引用不会因为 HTTPS 握手或证书时间问题失败——CentOS7 老机器系统时间跑偏导致 HTTPS 证书校验失败,是很常见的一个坑。centosplus我设成enabled=0,因为这个仓库里有替换系统核心组件的新版本包(比如新内核、新 glibc 相关),平时不开,需要的时候用--enablerepo=centosplus临时打开,避免它悄悄参与常规升级把系统搞乱。
如果你所在环境更信任清华或中科大,把域名换掉即可:
- 清华 TUNA:
https://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.9.2009/ - 中科大 USTC:
https://mirrors.ustc.edu.cn/centos-vault/7.9.2009/ - 华为云:
https://mirrors.huaweicloud.com/centos-vault/7.9.2009/
路径结构完全一致,os、updates、extras三个子目录都在。想省事的话直接下载镜像站维护好的 repo 文件也行,比如curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo,但要注意这类文件里指向的可能不是 vault 路径,下完得cat一下确认。
2.2 方案B:本地源,完全断网的机器靠它活着
内网机器、涉密环境、产线上的老设备,压根碰不到外网,这时候唯一的出路是拿安装 ISO 搭本地源。整个过程四步:挂载 ISO、写 repo 文件、刷新缓存、验证。
挂载这步,物理机把光盘塞进去,或者用mount /dev/sr0 /mnt/cdrom;虚拟机在设置里把 ISO 挂到虚拟光驱,然后同样mount /dev/sr0 /mnt/cdrom。如果 ISO 是当普通文件传进来的,用 loop 挂载:
mkdir -p /mnt/cdrom mount -o loop /root/CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom确认挂上去了,ls /mnt/cdrom应该能看到Packages、repodata、isolinux这些目录。看到repodata就说明这是一张可以直接当仓库用的 DVD,不是精简版。
然后写一个独立的 repo 文件,别去动CentOS-Base.repo,让两者互不干扰:
cat > /etc/yum.repos.d/local-dvd.repo <<'EOF' [local-dvd] name=CentOS-7 Local DVD baseurl=file:///mnt/cdrom gpgcheck=0 enabled=1 priority=1 EOFgpgcheck=0这一条经常被人吐槽"不安全",但在内网离线场景下,包来源是你自己拷进去的 ISO,介质本身可控,关掉校验省去导入密钥的麻烦是划算的。如果你在意校验,把gpgcheck=1、gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7写上,同样能跑通。
priority=1是给方案C准备的伏笔,单独用本地源时它没作用。想让这个源永久生效,还需要把挂载写进/etc/fstab:
echo "/root/CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom iso9660 loop,defaults 0 0" >> /etc/fstab本地源的硬伤必须说清楚:DVD ISO 里只有
os这一个仓库,包数量大约四千多个,覆盖基础系统、常用开发工具、大部分服务端软件。但updates 和 extras 不在里面,所以epel-release装不了、nginx装不了、docker-ce装不了。这一点在盘库存的时候一定要心里有数,缺什么就得靠方案C或者离线拷包解决。
2.3 方案C:本地源和网络源共存,优先级说了算
最常见的情况是:机器能连外网,但网络质量很差,同时手头有张 ISO。这时候两套源都配上,让本地源优先,缺包的时候自动去外网补,是最舒服的状态。
优先级由yum-plugin-priorities插件控制,CentOS7 基础源里就有这个包:
yum install -y yum-plugin-priorities装完确认/etc/yum/pluginconf.d/priorities.conf里有enabled=1,一般装完默认就是开的。然后在每个 repo 段里加priority=N,数字越小优先级越高。给本地 DVD 源写priority=1,给网络源的base、updates、extras写priority=10。
这个机制的判断逻辑是这样的:yum 在收集候选包时,会发现同一个包既在本地源里也在网络源里,这时候它不会两份都下,而是取优先级数字最小的那个源里的版本。所以只要本地源里有,就绝不会去外网拉,速度快、不用等;本地源里没有的,才落到网络源兜底。
有个细节要注意:优先级只解决"同一个包选哪个源"的问题,不解决"哪个版本更新"的问题。本地 ISO 里的包版本是 7.9.2009 定格的,网络源的updates里可能有更新的版本,但因为本地源优先级高,yum 依然会用本地那份。装关键组件时如果想强制走网络源拿新版,用--disablerepo=local-dvd临时禁用本地源。
2.4 换完源必须做的验证三连
改完配置文件不算完事,还有三个动作不做等于没换。
第一个是清缓存。yum 会把仓库元数据缓存在/var/cache/yum/下,换源之后旧缓存还在,容易报Metadata file does not match checksum这类鬼问题:
yum clean all第二个是重建缓存,这一步会真正去新地址拉元数据,能把网络不通、路径写错、证书失败这些问题一次性暴露出来:
yum makecache顺利的话会看到base | 3.6 kB、updates | 2.9 kB这类进度输出,结尾是Metadata Cache Created。如果中途报错,看是哪一路,具体排查见第 5 章。
第三个是实测装一个包。我习惯用vim-enhanced或wget这种小包做验证:
yum install -y wget yum info wget | head -20yum info的输出里会有Repo一行,看到Repo : base或Repo : local-dvd,就说明这个包确实是从你新配的源里取的,换源成功了。这一条比任何日志都直观。
3. yum 装软件,姿势对不对差别很大
换源只是把路修好,接下来才是日常使用。yum 这东西命令看着简单,但"装什么、从哪装、装着不动手能不能看见"这几个问题,每个人踩的坑都不一样。
3.1 先搞懂 yum 装一个包时到底做了哪些事
执行yum install nginx,背后其实跑了六七步,理解了这几步,报错就能自己对号入座。
它先去读/etc/yum.repos.d/下所有enabled=1的 repo,拉取每个仓库的repodata元数据——这些元数据是压缩过的 XML,记录了每个包的名称、版本、依赖、文件列表。然后拿nginx去这些元数据里做匹配,匹配到候选包后,解析依赖树:nginx 依赖 pcre、zlib、openssl 这些库,yum 会算出需要装哪几个包、哪几个已经满足。接着进入事务检查,算出下载总量和安装后的磁盘占用变化,等你确认。确认后才开始下载到/var/cache/yum/,下载完做 GPG 校验和哈希校验,最后交给 rpm 执行安装,把每个包的文件释放到磁盘,并更新/var/lib/rpm里的数据库。
理解了这套流程,就能明白几个常见现象为什么会出现。yum install刚开始那几秒的卡顿,是在拉元数据;看到Resolving Dependencies之后停一会儿,是在算依赖树;报Public key is not installed,是卡在 GPG 校验那步;报文件冲突,是卡在最后 rpm 释放文件那步。
3.2 安装和查询最常用的那几条命令
日常用得最多的就这几条,我按使用频率排一下:
| 命令 | 用途 | 备注 |
|---|---|---|
yum install -y 包名 | 安装并自动确认 | -y省去交互,脚本里必加 |
yum search 关键词 | 按名称和描述搜包 | 搜出来的是包名,不是命令名 |
yum provides 文件名 | 反查某个文件属于哪个包 | 找不到命令时最好用 |
yum info 包名 | 查看版本、来源、说明 | 能看到Repo一行 |
yum list installed | 列出已安装的包 | 配合 grep 用 |
yum reinstall 包名 | 重装,覆盖文件 | 配置文件被改坏时有用 |
yum update 包名 | 升级指定包 | 不加包名是全系统升级 |
yum provides这条命令特别值得拎出来讲。新手最常见的困惑是"我知道命令叫ifconfig,但不知道要装哪个包",这时候:
yum provides "*bin/ifconfig"输出里会告诉你net-tools-2.0-0.25.el7.x86_64提供这个文件,然后yum install -y net-tools就行。同理,mkfontscale、xdotool这类命令找不到时,都可以这样反查。
再说个中文环境下的老坑:yum groupinstall的组名。你想装开发工具,写yum groupinstall "Development Tools",在中文 locale 下可能报Warning: Group Development Tools does not exist。这是因为组的显示名被翻译成了中文。解决办法有两个,一个是先LANG=C yum grouplist用英文把组名列出来,另一个是直接用组 ID:
LANG=C yum groupinstall "Development Tools" -y3.3 EPEL 扩展源,那些官方源里找不着的东西
base和extras里的软件数量其实很有限,因为你问的那些"官方源里到底有没有",答案往往是"没有"。这时候就得请出 EPEL(Extra Packages for Enterprise Linux)。
安装方式简单到离谱:
yum install -y epel-release装完之后/etc/yum.repos.d/下会多出epel.repo和epel-testing.repo。epel-testing默认是关的,别手贱打开,里面的包是刚构建完还没经过充分测试的,产线上不要碰。
装完 EPEL 记得再跑一次yum clean all && yum makecache,让新仓库的元数据进来。之后yum install -y htop、yum install -y ncdu、yum install -y fail2ban这些就都能装了。
有个坑要提前打招呼:epel-release这个包本身并不在 EPEL 仓库里,它在extras仓库里。所以如果你的extras源是坏的,一条命令下去会报No package epel-release available,这时候别怀疑 EPEL 出问题,回头检查extras的地址。
另外 EPEL7 本身也随着 CentOS7 一起进入归档状态了。如果你发现yum install -y epel-release装上了但里面的包拉不到,去epel.repo里看看baseurl和metalink是否还指向活动地址,必要时换成归档地址。
3.4 指定版本、只下不装、批量离线搬运
生产环境里"装最新版"往往是危险的,需要锁版本。yum 支持在包名后面带版本号:
yum install -y nginx-1.20.1-1.el7版本号写不全没关系,yum list nginx --showduplicates可以把该包的所有可用版本列出来,照着抄。
比锁版本更实用的是只下载不安装,这是内网离线部署的核心技能:
yum install --downloadonly --downloaddir=/opt/rpms nginx这行命令只在本地缓存目录里放一个 nginx 的 rpm,不执行安装。但注意,它只下 nginx 本身,不连带依赖。要连依赖一起下,得用yumdownloader,它在yum-utils包里:
yum install -y yum-utils yumdownloader --resolve --destdir=/opt/rpms nginx--resolve就是"把依赖也一并算进来"的意思。用这条命令可以一次性把某个软件的全部 rpm 拖下来,拷进内网机器,再yum localinstall /opt/rpms/*.rpm或者rpm -ivh /opt/rpms/*.rpm装上。
如果内网机器有好多台,每次都拷一堆 rpm 太笨,可以在内网搭一个私有仓库:
yum install -y createrepo createrepo /opt/rpms然后在内网机器的/etc/yum.repos.d/里加一个指向它的 repo:
cat > /etc/yum.repos.d/private.repo <<'EOF' [private] name=Private Repo baseurl=file:///opt/rpms gpgcheck=0 enabled=1 EOF这套组合拳在离线部署 kkfileview 这类需要一堆 Java 依赖的服务时特别好使:外网机器上yumdownloader --resolve把 rpm 全拖下来,内网机器上配好私有源,一条yum install搞定,比手动rpm -ivh一个个试依赖顺序强太多。
4. yum 卸载软件,动手之前先想清楚
装软件出问题是小麻烦,卸软件删错东西是大事故。yum remove和yum install最大的区别在于:install 是加法,最坏结果是装不上;remove 是减法,它会连带删除依赖它的包,最坏结果是系统起不来。
4.1 remove、erase、autoremove 到底有什么区别
三个命令看着像,行为上确实有差异。
yum remove 包名和yum erase 包名在 CentOS7 上基本等价,erase是remove的别名,两个都能用,行为一致。真正要小心的是它的依赖处理逻辑:yum 不但会删除这个包,还会删除所有"因为这个包而存在、且没有其他包依赖"的依赖包。
举个实际例子。你yum install -y postfix dovecot搭了套邮件服务,后来想卸掉,执行yum remove -y postfix。yum 算完依赖发现,postfix依赖cyrus-sasl,而cyrus-sasl同时被别的服务用着,所以不会动它;但它如果发现某个库只有 postfix 在用,就会一起删掉。
yum autoremove是另一回事。它是用来清理"孤儿依赖"的——某些依赖包当初是为了某个主包装进来的,后来主包被卸了,这些依赖就悬空了。yum autoremove专门扫这些悬空包并清掉。这条命令在 CentOS7 上需要装了yum-plugin-remove-with-leaves或者依赖较新的 yum 版本才完整支持,使用时务必先看一眼它打算删哪些东西,别直接-y。
卸载前一定要做的动作:先跑一遍不带
-y的命令,看它列出的"将要删除"清单。如果清单里出现了glibc、systemd、kernel、openssh-server、python这类核心包,立刻Ctrl+C停下。这类误删基本等于重装系统。
4.2 history 回滚,删错了之后的急救手段
yum 有个特别好用但很多人不知道的功能:它把每一次事务都记了账,存在/var/lib/yum/history/里。
yum history list输出是一个编号列表,每行有事务 ID、执行用户、操作类型(Install、Erase、Update)、涉及包数量和结果。找到你刚才那次误操作的行号,比如是 23:
yum history info 23这一步先看清楚它到底干了什么。确认无误后:
yum history undo 23undo会把这次事务反向执行:装了的包卸掉,卸了的包装回来。这个机制在"手滑卸了某个依赖导致服务起不来"的场景下非常好用,也是我强烈建议保留/var/lib/yum目录、不要为了省磁盘去删它的原因。
还有一个更强的命令是yum history rollback N,它会把系统状态回滚到第 N 次事务之后的样子,中间的所有事务全部反向执行。功能很强,但也更危险,用它之前最好先做个快照。虚拟机的话直接打快照,物理机的话先yum history list把要回滚的范围算清楚。
补充一个限制:yum history 的回滚依赖当时的仓库元数据,如果换过源、旧源已经下线,回滚时可能因为找不到对应版本的包而失败。所以换源之前先做一次 history 全量记录,或者干脆打快照,比什么都可靠。
4.3 缓存清理和磁盘空间回收
老机器上/var/cache/yum能长到几个 GB,尤其是做过多次yum update的机器,那里堆着历次下载的 rpm 残留。
清理分几个层次,看你要清多干净:
yum clean packages # 只删下载的 rpm 包,保留元数据 yum clean metadata # 删元数据,下次操作会重新拉 yum clean all # 全清,包+元数据+缓存,最彻底yum clean all之后第一次yum install会因为要重新拉元数据而稍慢,这是正常的,别以为出问题了。
想看看缓存到底占了多少:
du -sh /var/cache/yum/ du -sh /var/cache/yum/* | sort -h第二个命令能把每个仓库占的空间排序列出来。如果某台机器磁盘告急,清缓存能立刻腾出几百 MB 到几 GB 不等。极端情况下把整个/var/cache/yum/目录rm -rf掉也不会坏系统,yum 下次运行会自动重建,但这样一来连历史元数据都没了,yum history的记录虽然还在/var/lib/yum里,可回滚时会更容易失败。
另外提醒一句,yum update之后旧内核不会自动删除,会一直堆在/boot里。/boot分区通常只有 200MB 到 500MB,装了三四个内核就满了,满了之后新内核装不进去,yum update会报错。处理办法是用package-cleanup(在yum-utils里):
package-cleanup --oldkernels --count=2这条命令保留最近 2 个内核,其余的清掉。这是 CentOS7 上一条实打实的续命命令,值得记进备忘录。
5. 报错现场:那些年 yum 塞给我的一屏红字
yum 的报错信息性质其实不错,它会告诉你是哪个仓库、哪一步出的问题,只是红字太多容易让人慌。下面这几个是我遇到频率最高的。
5.1 五个高频报错的逐条拆解
第一个:Cannot find a valid baseurl for repo: base/7/x86_64
这是换源不彻底最典型的表现。说明 yum 拿不到 base 仓库的有效地址——要么CentOS-Base.repo里的baseurl还是旧的mirror.centos.org,要么mirrorlist没注释掉,yum 优先用了那个失效的动态列表。处理办法:grep -n "mirrorlist\|baseurl" /etc/yum.repos.d/CentOS-Base.repo,看看有没有漏网的mirrorlist,全部注释掉,确保每个仓库都有可用的baseurl。
第二个:[Errno 14] curl#6 - "Could not resolve host: mirrors.aliyun.com"
这是 DNS 层面的问题,不是 yum 的问题。先cat /etc/resolv.conf看有没有nameserver配置,没有的话加一条nameserver 223.5.5.5。如果配了还是不行,ping -c 3 8.8.8.8试一下纯 IP 能不能通:能通说明是 DNS 问题,不能通说明是网络出口问题,得找网络层面的人。
第三个:Another app is currently holding the yum lock; waiting for it to exit...
说明有个 yum 进程还在跑,或者上一次 yum 异常退出留下的锁文件没清掉。先ps aux | grep yum确认真没有活动进程,然后:
rm -f /var/run/yum.pid这里必须强调:一定要先确认没有正在跑的 yum,两个 yum 同时操作 rpm 数据库会导致数据库损坏,麻烦比等一会儿大得多。
第四个:Error: rpmdb open failed
rpm 数据库打不开了,通常是异常断电或强制杀 yum 进程导致的。解决方法是重建数据库:
rm -f /var/lib/rpm/__db.00* rpm --rebuilddb第一条删掉的是 Berkeley DB 的锁和环境文件,第二条重建索引。重建过程可能几十秒到几分钟,看包数量,期间别中断。重建完再跑yum clean all && yum makecache验证。
第五个:Public key for xxx.rpm is not installed
GPG 校验失败。系统里的 CentOS7 签名密钥丢了或者没导入。恢复办法:
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7或者临时跳过校验(仅限本地源、私有源这类可控场景):
yum install -y --nogpgcheck 包名--nogpgcheck是全局跳过,能不用就不用,一旦包在传输过程中被篡改或损坏,就没有任何机制拦得住它。
5.2 几个让人抓头的具体案例
先说yum install -y fontconfig mkfontscale报errors during downloading metadata for repository 'base'这个。这个报错本身和 fontconfig 一点关系都没有,真正的问题在base仓库的元数据下不下来。往上看几行,一般能看到Curl error (6): Couldn't resolve host或Curl error (35): SSL connect error。前者是 DNS 或网络,后者是 HTTPS 握手失败——CentOS7 老机器系统时间跑偏是 SSL 错误的头号原因,date一看发现时间是 2020 年,跟证书有效期对不上。修法:
yum install -y ntpdate ntpdate ntp.aliyun.com时间对了再回头装 fontconfig,一次就过。
再说"装了个软件之后系统里莫名其妙多了一堆包"。这不是 bug,是依赖树解析的正常结果。比如装docker-ce会连带装containerd.io、container-selinux,装python-devel会连带一堆python-*的库。想看清楚到底会装哪些,用:
yum install --assumeno 包名--assumeno在确认环节自动回答"否",等于把清单打完给你看然后取消操作,用来预演再合适不过。
还有"内网装了私有源之后,yum install特别慢"。原因通常是某个enabled=1的网络源不可达,yum 在它上面反复超时重试。解决思路是把所有用不上的源enabled=0关掉,只留私有源和本地源,速度立刻上去。
| 报错关键词 | 根本原因 | 处理动作 |
|---|---|---|
| Cannot find a valid baseurl | 源地址失效或 mirrorlist 未注释 | 改 baseurl 指向 vault 或镜像站 |
| Could not resolve host | DNS 不通 | 检查/etc/resolv.conf |
| yum lock | 残留进程或锁文件 | 确认无进程后删/var/run/yum.pid |
| rpmdb open failed | rpm 数据库损坏 | rpm --rebuilddb |
| Metadata does not match checksum | 旧元数据与源不匹配 | yum clean all && yum makecache |
| Public key not installed | 签名密钥缺失 | rpm --import对应 KEY 文件 |
| SSL connect error | 系统时间错误或证书链问题 | 校准时间ntpdate |
| No package available | 包不在任何已启用仓库 | 装 EPEL 或用yum provides反查 |
| No space left on device | 磁盘或/boot满 | 清缓存、package-cleanup --oldkernels |
5.3 我自己的几条实操心得
最后分享几条从实际折腾里攒下来的经验,都是文档里不太会写的。
第一条:所有换源脚本,第一行必须是备份。我见过太多"执行完脚本后所有 repo 文件变成空文件"的案例,原因往往是cat > file写了一半被中断。养成习惯,脚本开头cp -a /etc/yum.repos.d /root/repo-bak-$(date +%F),出事了两分钟恢复。
第二条:永远不要在没看清单的情况下加-y。特别是yum remove和yum update。yum update不加参数会把系统里所有能升的包全升一遍,包括内核。生产环境上跑这个之前,先yum check-update看看有多少包,超过一百个的,分批次升,别一把梭。
第三条:yum update -y --exclude是个好搭档。有些环境必须锁住内核版本(比如装了特定驱动),那就用:
yum update -y --exclude=kernel* --exclude=centos-release*--exclude可以写多次,把不想动的包排除掉。这条命令在做批量维护时特别有用,配合--security只打安全补丁,能把升级风险压到最低。
第四条:把换源后的机器做成模板。如果你管着几十台 CentOS7,别一台台去改源。找一台改好、验证通过,把/etc/yum.repos.d/整个目录打包,其他机器scp过去、/etc/pki/rpm-gpg/确认有 KEY、yum clean all刷新一遍就行。这套动作我用sshpass配合一个循环脚本跑过,几十台机器五分钟内全部搞定——热词里有人搜centos7 sshpass,大概就是在干这件事。
第五条:本地源和网络源的取舍,本质是稳定性和完整性的取舍。本地源永远可用但内容有限,网络源内容全但会受网络影响。我的做法是本地源常开、网络源常开、本地源优先级更高,同时把yum-plugin-priorities装进基础镜像里,新机器开箱就是这个状态。这套配置跑了两年多,唯一遇到的问题就是本地 ISO 里的包比网络源老,装完某些包之后需要yum update 包名手动升一次,可控。
第六条:耐心看待"慢"。yum 第一次在新源上跑总是慢的,因为要拉元数据、建缓存。第二次开始就快了。很多人第一次换完源发现yum makecache花了两分钟,以为配错了,又改回去,来回折腾。给自己定个规矩:第一次跑超过三分钟再去查原因。
第七条:给系统留条后路。换源、装包、卸包这些操作,风险最低的做法永远是在虚拟机上先跑一遍。我现在做任何涉及依赖树的动作,都是先在虚拟机里yum install --assumeno走一遍看清单,确认没有异常再上物理机。这套习惯帮我躲过至少三次"卸了某个库导致 SSH 连不上"的事故。
第八条:文档要写给自己看。每台机器的换源方式、本地 ISO 存放路径、私有源地址,都记在机器上的/root/README.repo里。半年后回来维护的时候,你会感谢当时的自己。