ARTICLE DETAIL

资讯详情

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

openEuler本地与内网yum仓库搭建:从createrepo到Nginx共享

openEuler本地与内网yum仓库搭建:从createrepo到Nginx共享 如果你手头有openEuler 22.03 LTS SP1的机器联网状态下装个包、换个源敲几条命令就解决了基本不用多想。但等你真正接手生产环境或者要给一批内网服务器做批量部署时情况就完全不一样了外网访问受限、软件版本要统一、几十台机器同时 yum install 能把出口带宽打满有时候干脆就是纯离线环境。这时候“本地/内部yum软件仓库”就成了绕不开的基础设施。这篇文章我会围绕 openEuler 22.03 LTS SP1把两种仓库搭建方式都讲透一种是最常用的单机本地源用 ISO 镜像或者自建 rpm 目录喂给本机 yum另一种是把仓库放到一台服务器上通过 HTTP 共享给整个内网使用。包括背后的仓库原理、createrepo 元数据到底在干嘛、reposync 怎么同步、nginx 怎么托管、SELinux/防火墙怎么放行以及我实际踩过的一些坑。内容适合刚接手 openEuler 的运维、做离线交付的工程师也适合所有想把 yum 仓库机制彻底搞明白的人。1. 为什么自己动手搭仓库需求与方案选型1.1 本地/内部仓库解决了什么问题先说需求。很多人觉得“yum 仓库”不就是服务器默认带的那几个官方源吗默认就能用为什么要自己搭实际工作中遇到的问题往往是这样几类第一离线环境。机房在客户现场或者安全分区严格服务器根本连不上外网。这时候系统自带的官方源全是废的你必须有本地源才能装任何软件。我见过不少项目交付时安装人员一开始没准备本地源等现场部署才发现连一个 tar 包都解不开、一个编译工具都装不上非常被动。第二多机版本一致性。联网环境下 yum install 装出来的软件可能今天装的是 1.0下周另一台机器装出来就是 1.2同样是“装好了”版本却对不上。对于需要长期维护的集群软件版本漂移是隐性灾难。有了内部仓库所有机器都指向同一个源装出来的东西完全一致排查问题也容易得多。第三网络与效率问题。几十台服务器同时从一个公网源拉包慢不说还可能被限流、断流。内网自建仓库后带宽消耗只在内网速度提升是数量级的。这个我实测过同样是批量部署原来要耗一两个小时走内网源可能十分钟就完成了。第四安全审计需求。内部仓库可以对所有进入生产环境的 rpm 做一次集中检查和安全管控而不是让每台机器各自去公网抓包。这在一部分地区、行业的合规场景下几乎是硬性要求。1.2 单机源、内网共享源到底该选哪种搭仓库之前先想清楚自己的使用范围。方案选错后面维护起来会很难受。单机本地源的典型场景是就一两台服务器或者一台完全不联网的机器。做法很简单把 ISO 镜像挂载到某个目录或者自己搞一个 rpm 目录用 createrepo 生成元数据然后在 /etc/yum.repos.d/ 里写一个指向 file:// 路径的仓库文件这台机器就能正常用 yum 了。优点是零额外依赖、不需要任何服务端软件、改起来也快缺点就是只能自己用别的机器没法共享。内网共享源则是把仓库目录放到一台服务器上用 Nginx 或者 Apache 之类的 HTTP 服务暴露给局域网内的所有机器。客户端把 baseurl 写成 http://服务器IP/仓库路径 就能直接用。适合服务器数量多、需要统一版本、需要集中维护的场景。这两种方案并不冲突实际项目里我通常是先做单机源做验证等包的数量和机器数量上来了再平滑升级成 HTTP 共享源。本地源的 repo 文件、目录结构换到 HTTP 源时几乎原样保留只是把 file:// 前缀改成 http:// 而已。所以这篇文章的顺序也是先讲本地源再讲共享源。1.3 openEuler的yum仓库机制和CentOS有哪些不一样玩过 CentOS 7/8 的人上手 openEuler 会很快但有几个细节必须注意。openEuler 22.03 LTS SP1 的包管理工具底层实际是 dnf但命令仍然兼容 yum。也就是说你敲 yum install、yum repolist、yum clean all 都没问题系统内部会转向 dnf 执行。这带来了一个好处很多 CentOS 时期的脚本可以直接用也带来了一个坑如果你在自动化脚本里写死了检测 yum 包名可能会发现有些工具包在 openEuler 里叫 dnf-xxx 而不是 yum-xxx。仓库配置目录同样是 /etc/yum.repos.d/默认配置文件是 openEuler.repo。里面分的仓库有 OS、EPOL、debuginfo、source 等几类。OS 是最基础的系统仓库绝大多数系统组件都在这EPOL 相当于扩展仓库很多不属于系统基础包的第三方软件会放在这里。咱们做本地源通常先把 OS 仓库搞明白EPOL 按需补充。还有一个容易忽略的区别OpenEuler 对 GPG 签名的配置路径和 CentOS 不完全一样公钥文件通常在 /etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler。内网自建仓库时我们一般图省事直接 gpgcheck0但如果你希望保留签名校验就得把公钥一并管理好。2. 动手前要备齐的材料与环境确认2.1 核对系统版本和CPU架构避免下错包搭建本地仓库的第一步不是执行命令而是确认自己机器到底是什么版本、什么架构。别小看这一步我见过有人拿着 x86_64 的 ISO 给 aarch64 机器做本地源结果 yum 里面全是“No package matched”折腾半天才发现基础架构就没对上。版本查看命令很简单cat /etc/openEuler-release uname -m正常情况下输出类似openEuler release 22.03 (LTS-SP1) x86_64如果是 aarch64那后面下载 ISO、同步仓库、写 baseurl 时架构目录都要跟着变。openEuler 官方仓库的目录结构里x86_64 和 aarch64 是分开的比如https://repo.openeuler.org/openEuler-22.03-LTS-SP1/OS/x86_64/ https://repo.openeuler.org/openEuler-22.03-LTS-SP1/OS/aarch64/自己建本地目录时最好也遵循这个习惯把架构分清方便以后多架构机器共用一套仓库服务器。2.2 ISO镜像里的仓库结构长什么样openEuler 官方发布的 ISO 镜像本身就是“活”的仓库。这一点很多人没意识到它里面除了安装介质该有的东西还有完整的 repodata 元数据。挂载或者解压后你会看到类似这样的结构/mnt/openEuler/ ├── Packages/ # 所有 rpm 包 ├── repodata/ # yum/dnf 读取的仓库元数据 ├── RPM-GPG-KEY-openEuler # 官方公钥 ├── ...其中 repodata 目录是整个仓库的核心。yum 安装任何软件时先访问的就是 repodata/repomd.xml 这个文件它相当于整个仓库的索引里面记录了所有包清单、文件位置、校验值、分组信息等。只要这个目录在客户端就能把这个目录当作一个可用的 yum 源不一定非得自己重新生成元数据。所以如果你只是想让本机或者内网机器使用 ISO 里的软件包最简单的办法是直接把 ISO 挂载出来baseurl 指向挂载点即可连 createrepo 都省了。什么时候才需要自己跑 createrepo当你往仓库里添加了 ISO 以外的 rpm 包时原装的 repodata 里并不包含这些新包的信息这时候就必须重新生成或增量更新元数据。2.3 需要用到的工具与安装方式搭建过程中主要用到两个工具createrepo_c 用于生成仓库元数据dnf-utils或 dnf-plugins-core用于 reposync 同步在线仓库。Nginx 则用于把仓库目录通过 HTTP 共享出去。如果你手头机器能联网安装很简单dnf install -y createrepo_c dnf-utils nginx注意openEuler 的 OS 基础源里可能没有 nginx它通常在 EPOL 仓库里。所以如果上面命令提示找不到 nginx需要先配置并启用 EPOL 在线源cat /etc/yum.repos.d/openEuler-epol.repo EOF [EPOL] nameopenEuler-22.03-LTS-SP1 EPOL baseurlhttps://repo.openeuler.org/openEuler-22.03-LTS-SP1/EPOL/main/$basearch/ enabled1 gpgcheck0 EOF dnf install -y nginx如果是在纯离线环境下那就先把 createrepo_c 和 nginx 的 rpm 包在联网机器上提前用 dnf download 拉下来再拷贝进去安装。这里顺带提一句 dnf download 的用法后面也会细讲dnf download createrepo_c nginx --resolve --destdir/tmp/rpms--resolve 会把依赖包一起拉下来拷到内网后逐个安装即可。3. 单机本地yum仓库从挂载ISO到yum makecache全流程3.1 挂载ISO或解压到磁盘两种方式怎么选我习惯把 ISO 直接挂载到 /mnt/openEuler 目录这样不需要额外占磁盘空间适合临时验证或者长期不关机的小场景。命令如下mkdir -p /mnt/openEuler mount -o loop /opt/iso/openEuler-22.03-LTS-SP1-x86_64-dvd.iso /mnt/openEuler挂载之后直接 ls /mnt/openEuler确认看到 Packages 和 repodata 目录说明这个 ISO 可以作为仓库根目录使用。但挂载方式有一个隐患机器重启后挂载会消失。如果这是生产机器的唯一软件源一旦忘了重新挂载yum 就会报错而且容易影响正在跑的任务。解决办法是写入 /etc/fstab 实现开机自动挂载echo /opt/iso/openEuler-22.03-LTS-SP1-x86_64-dvd.iso /mnt/openEuler iso9660 loop,defaults 0 0 /etc/fstab mount -amnt/openEuler 这个路径可以自己定但后面所有 repo 配置都要保持一致。如果你的磁盘空间充裕我其实更推荐把 ISO 里的内容完整解压到磁盘目录比如 /data/repo/openEuler-22.03-LTS-SP1。原因有三个一是访问速度比循环挂载设备更快二是之后在此基础上添加新 rpm 包会更方便createrepo 更新元数据时不受只读文件系统限制三是为了后面做内网 HTTP 共享源时目录管理更灵活。解压命令mkdir -p /data/repo/openEuler-22.03-LTS-SP1 cp -a /mnt/openEuler/* /data/repo/openEuler-22.03-LTS-SP1/cp -a 保留文件属性和权限rpm 包里有些符号链接权限信息比较敏感不要用简单 cp 或者 tar 解压后再传容易出问题。3.2 createrepo生成repodata的正确姿势如果你只用 ISO 原装包这节可以略过。但如果你需要往仓库里加自己的软件包、补丁包、第三方 rpm就必须理解 createrepo 的工作方式。createrepo 做的事情简单说就是扫描一个目录下所有的 rpm 文件把它们的基本信息包名、版本、依赖、分组、校验值提取出来生成 repodata/repomd.xml 以及相关的 metadata 文件。以后客户端 yum 安装时先下载这些元数据再根据依赖关系决定要装哪些包整个过程跟“图书馆书目检索”很像——图书rpm要上架必须先把书目repodata编好读者才能查得到。操作过程如下假设我们建一个独立的仓库目录存放自定义 rpm 包mkdir -p /data/custom-repo cp 你自己的rpm包 /data/custom-repo/ cd /data/custom-repo createrepo_c .命令执行完目录下会出现 repodata 文件夹。如果以后往这个目录里不断加新包不需要每次全量重建用增量更新模式更快createrepo_c --update /data/custom-repo--update 会基于已有的元数据做增量更新只扫描文件变化包数量多的时候能省下大量时间。但这里有一个我踩过的坑如果你不仅添加了包还删除了某些旧包--update 有时候会在元数据里残留旧包信息。所以大版本变更、删包较多时老老实实全量重建一次更稳妥方法很简单把 repodata 和隐藏缓存清掉再跑一遍 createrepo_c rm -rf /data/custom-repo/repodata /data/custom-repo/.repodata createrepo_c /data/custom-repo3.3 手写repo文件与基础验证仓库目录准备好了接下来要在 /etc/yum.repos.d/ 下新建一个仓库配置文件让 yum 知道去哪里找包。文件名可以随意后缀必须是 .repo建议带序号方便后面和其他仓库区分比如 01-local.repo。cat /etc/yum.repos.d/01-local.repo EOF [local] nameLocal Repository for openEuler 22.03 LTS SP1 baseurlfile:///data/repo/openEuler-22.03-LTS-SP1 enabled1 gpgcheck0 EOF几个字段拆开解释一下[local] 是仓库 ID必须唯一。如果和已有仓库 ID 重复yum 会互相覆盖导致配置“看起来改了实际没生效”。name 是仓库描述随便写但建议写清楚版本和用途。baseurl 是仓库根目录file:// 后面跟绝对路径。注意是三个斜杠file:///data/...很多人漏写一个 /写成 file://data/...yum 会把它当成访问 data 主机上的文件结果必然失败。enabled1 表示启用。gpgcheck0 表示不检查 GPG 签名。内网自建仓库为了方便通常这么设置如果要求严格后面我会讲怎么配签名校验。配置文件写好后按顺序跑这几条命令验证yum clean all yum makecache yum repolistyum makecache 会下载仓库元数据并生成缓存如果 baseurl 有问题基本在这步就会报错。看到 repolist 里有 local 这个仓库说明仓库已经可用了。最后随便装一个包测试比如热词里常见的 xdotoolyum install -y xdotool装成功后你再 yum list installed | grep xdotool看到版本号来自本地仓库整个单机本地源就算完全跑通了。4. 内网多机共享仓库服务器端Nginx托管与客户端配置4.1 为什么共享仓库优先选HTTP而不是NFS/FTP当你有多台机器需要共用同一份仓库时有人会想到 NFS 挂载或者 FTP 共享。这两种方式在特定场景下能用但维护体验差别很大。NFS 的问题在于客户端机器把远程目录挂载成 file:// 路径后yum 确实能访问到但 NFS 对连接数、锁、权限比较敏感服务器重启、网络抖动时客户端挂载点容易变成“僵尸目录”yum 直接卡死而且跨网段、跨防火墙时 NFS 端口需要额外放行配置起来很烦。FTP 的问题则是 yum 对 FTP 协议的支持不算活跃偶尔会遇到被动模式、目录列表解析之类的兼容性问题排查成本高。HTTP 是 yum/dnf 原生支持最好的协议而且内网里用 Nginx 托管静态目录非常简单客户端只要一个 URL 就能访问断点续传、并发下载都由 Nginx 处理稳定性和性能都远好于 NFS/FTP。这是我推荐 HTTP 的核心原因。4.2 服务器端用Nginx把仓库目录暴露出去现在假设你已经按照第 3 节把仓库目录整理好了比如 /data/repo 下既有 openEuler 官方 OS 目录也有自己维护的 custom-repo 目录。接下来在仓库服务器上装好 Nginx写一个最简单的 server 配置vim /etc/nginx/conf.d/repo.conf内容如下server { listen 80; server_name _; root /data/repo; autoindex on; autoindex_exact_size off; autoindex_localtime on; charset utf-8; }autoindex on 很关键开启后浏览器直接访问 http://服务器IP/ 可以看到仓库目录结构方便人工检查。这配置写好后启动 Nginxsystemctl enable --now nginx此时如果你有个自定义仓库在 /data/repo/custom-repo 目录那客户端的 baseurl 就是 http://服务器IP/custom-repo/。不过要先确认有没有被 SELinux 和防火墙挡掉这两处是新手最常卡住的点。先看 SELinux 状态getenforce如果结果是 Enforcing需要给 /data/repo 目录打上 httpd 可访问的上下文标签否则 Nginx 虽然启动了客户端请求却会 403dnf install -y policycoreutils-python-utils semanage fcontext -a -t httpd_sys_content_t /data/repo(/.*)? restorecon -Rv /data/repo然后放行防火墙的 80 端口firewall-cmd --zonepublic --add-servicehttp --permanent firewall-cmd --reload到这里可以用本机 curl 验证curl -I http://127.0.0.1/repodata/repomd.xml如果返回 200 OK说明仓库服务已经在正常工作了。4.3 用dnf reposync把外部仓库同步成内网源前面第 3 节用的都是 ISO 镜像但 ISO 里的包往往不够全而且版本不更新。内网仓库更常见的一个需求是在一台能联网的机器上把 openEuler 官方源整体同步到本地然后供内网使用。这就要用到 dnf reposync。先确认有对应工具dnf install -y dnf-utils然后同步 OS 仓库到本地dnf reposync --repoidOS --download-path/data/repo --downloadcomps --norepopath参数说明--repoidOS 指定要同步的仓库 ID这里对应官方源配置文件里的 [OS]。--download-path 指定下载到哪个目录。--downloadcomps 下载软件包分组信息后面才能用 yum groupinstall。--norepopath 表示不在下载目录下再创建一个以仓库 ID 命名的子目录让包直接落到 /data/repo 下。如果想去掉这个参数也可以但你要自己注意最终 repo 文件里的 baseurl 指向哪一层。同步完成后检查目录结构。正常情况下找到那个包含 Packages 子目录的层级然后执行cd /data/repo createrepo_c .如果下载了分组信息还需要把分组元数据合入 repodata。createrepo 本身不负责处理 comps 分组需要用 modifyrepo_cfind /data/repo -maxdepth 2 -name comps*.xml modifyrepo_c --mdtypegroup /path/to/comps.xml /data/repo/repodata/这样客户端就能用 yum groupinstall “Development Tools” 之类的分组安装了。同步 EPOL 扩展仓库的方法是同样的把 --repoidEPOL 加上即可。同步整个官方仓库会占用不少磁盘空间几十 GB 很常见建议事先确认磁盘容量也可以只同步自己用得到的某些目录或架构比如只同步 x86_64 的 OS 和 EPOL。如果只是临时给内网某台机器带几个 rpm 包过去不用大动干戈同步整个仓库用 dnf download 定向拉包就够了dnf download xdotool --resolve --destdir/tmp/rpms然后把 /tmp/rpms 下的文件拷到目标机器用 yum install ./xxx.rpm 或直接放进自己的仓库目录再 createrepo_c --update都能救急。4.4 客户端repo文件与批量下发服务器端好了客户端配置非常简单。在每台内网机器上新建一个仓库文件比如 /etc/yum.repos.d/internal.repo内容如下cat /etc/yum.repos.d/internal.repo EOF [internal] nameInternal openEuler 22.03 SP1 Repo baseurlhttp://10.0.0.10/repo/ enabled1 gpgcheck0 EOF这里 10.0.0.10 是仓库服务器的 IP 地址实际替换成你自己的。如果 Nginx root 配置的是 /data/repo而 /data/repo 下又有 OS、EPOL、custom-repo 等多个仓库目录客户端每个仓库可以单独写一个安装源。最省事的方法是把 baseurl 指向一个包含 repodata 的目录一个仓库一个入口。如果客户端原先配置了官方在线源为了避免装包时从外网拉取需要把在线源禁用。可以用 yum-config-manager 直接操作dnf install -y dnf-utils yum-config-manager --disable OS EPOL或者手动把 /etc/yum.repos.d/openEuler.repo 里的 enabled1 改成 enabled0。然后再次刷新缓存yum clean all yum makecache yum repolist多台机器配置时不要一台台手动操作。用 Ansible 批量下发 repo 文件或者直接写个 Shell 循环 scp 都能搞定。如果机器数量特别多还可以在 repo 文件下发前先做一次 curl 测试确认哪个 IP 的源是通的。4.5 仓库日常更新与版本切换内网仓库不是建完就一劳永逸的生产环境的管理者必须有一个日常更新节奏。更新流程建议分三步走先在一台联网机器上重新执行 dnf reposync把官方源的新包同步到本地再执行 createrepo_c --update 刷新元数据最后确认 repomd.xml 的生成时间已更新客户端下次 makecache 就能看到新包。这个过程可以做成定时任务比如每天凌晨同步一次30 2 * * * /usr/bin/dnf reposync --repoidOS --download-path/data/repo/os --downloadcomps --norepopath /usr/bin/createrepo_c --update /data/repo/os /tmp/repo-sync.log 21注意 cron 里尽量写命令的绝对路径否则环境变量问题会让你查半天。版本切换也是一个高频操作。比如 openEuler 22.03 LTS SP1 维护期结束后你要把内网源升级到 SP2 甚至更高版本。我建议不要在原目录上覆盖升级而是保留多个版本目录比如/data/repo/openEuler-22.03-LTS-SP1/ /data/repo/openEuler-22.03-LTS-SP2/然后把客户端 repo 文件里的 baseurl 从 SP1 改成 SP2只改一个 URL其他全部不动。这样做的好处是回滚极其方便出问题还能即时切回旧版本而不是被一次覆盖操作逼到墙角。5. 常见问题与排查技巧实录5.1 报“Errors during downloading metadata”的排查顺序这是 yum 使用过程中出现频率最高的一类报错报错信息长这样Errors during downloading metadata for repository internal: - Curl error (6): Couldnt resolve host name for http://... - Curl error (7): Failed to connect to 10.0.0.10 port 80: Connection refused遇到这种报错按顺序做三步检查。第一步先确认 URL 能不能访问。在客户端机器上执行curl -I http://10.0.0.10/repo/repodata/repomd.xml如果 curl 都连不上问题一定在网络层、防火墙或者服务进程别去翻 yum 配置。第二步确认仓库服务器上的 Nginx 是否在运行、目录是否存在、SELinux 是否放行。在服务器本机 curl http://127.0.0.1/...本机能通、客户端不通重点查防火墙和监听地址。第三步如果之前 yum 是好的突然某一天报这个错优先怀疑服务器磁盘满了或者 Nginx 进程挂了用 df -h 和 systemctl status nginx 看一眼。我实际碰到最诡异的一次是服务器上仓库目录好好的Nginx 也正常但客户端始终报 metadata 下载失败。后来才发现是仓库服务器的磁盘满了createrepo 在写元数据时并没有报错但写出的 repomd.xml 是半个空文件客户端解析失败。从此我养成了每个仓库目录用完之后立刻 curl 验证的习惯。5.2 GPG签名与公钥问题内网源该不该关gpgcheckGPG 签名校验是 yum 安全体系的重要部分。官方源默认 gpgcheck1下载的每个 rpm 包都会校验签名防止包被篡改。如果你自建内网仓库后仍然开着 gpgcheck1但系统里没有对应公钥就会出现这类报错Public key for xxx.rpm is not installed. Failing.解决办法有两个一是把官方公钥导入系统rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler或者直接在 repo 文件里指定 gpgkeygpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler第二个办法就是直接 gpgcheck0。对于纯内网、自建仓库、没有专人对 rpm 做签名的团队这个做法非常普遍。但你要明白代价任何能写进仓库目录的人都能往里面塞篡改过的包客户机会毫无抵抗力地安装。所以如果环境安全要求高建议保留签名校验并且对自建仓库单独做签名而不是图省事全部关闭。5.3 repo文件写错引发的各种玄学问题repo 文件语法看起来简单出错却最隐蔽。常见的几种坑仓库 ID 重复。比如 /etc/yum.repos.d/ 下有两个文件都写了 [OS] 这种 IDyum 会用后解析的那个覆盖前面的有时候你以为改的是 A 文件实际生效的是 B 文件排查时会非常抓狂。baseurl 路径层级不对。很多人自建目录时把仓库根目录理解成“只要有 rpm 就行”然后把 baseurl 写到了包含 Packages 目录的父目录没有指向 repodata 所在的那一层。客户端报错通常是 404 或者 “Cannot retrieve repository metadata”。记住一个判断标准baseurl 指向的 URL 后面必须能直接拼出 repodata/repomd.xml否则层级就错了。文件名编码问题。有些从 Windows 环境拷贝过来的 rpm 包或者 repo 文件在 Linux 上会出现中文乱码、行尾多了 \ryum 解析时会给出非常奇怪的错误。建议手工在 Linux 上创建仓库文件别从 Windows 记事本直接传。5.4 加包后元数据不更新的经典场景这是非常高频的问题管理员往仓库目录里拷了几个新 rpm然后在客户端执行 yum install 新包名结果提示“No package xxx available”。网上一搜一堆人让 clean all、makecache但清完缓存还是找不到。原因大概率是管理员忘了在服务器端执行 createrepo 或 createrepo --update。yum 客户端只认 repodata 里的清单你光把 rpm 文件放进目录仓库的“书目”不会自动更新。所以每次加包后记住这一条完整链路cp 新包.rpm /data/repo/custom-repo/ createrepo_c --update /data/repo/custom-repo/ # 如果有HTTP共享源不用重启Nginx元数据是即时读取的然后到客户端执行yum clean all yum makecache yum install -y 新包名还有一种是客户端本地缓存过期问题。即使服务器端元数据已经更新客户端也可以能因为缓存了旧的 repomd.xml 而看不到新包。这时候 yum clean all 再 makecache 就能解决。5.5 常见问题速查表我把运维中最常遇到的 yum 仓库问题整理成一张速查表方便后面排查时直接对照。现象优先检查点参考处理Errors during downloading metadatabaseurl 可达性、Nginx 状态、磁盘/SELinuxcurl -I 测试systemctl status nginxdf -hsemanage/restoreconPublic key not installed是否导入公钥、gpgcheck 设置rpm --import 公钥或按安全策略关闭 gpgcheckNo package xxx available仓库元数据是否包含该包、仓库是否启用、EPOL 是否开启createrepo --updateyum repolistyum-config-manager --enable404 错误baseurl 层级、目录路径、Nginx root确认 URL 后能拼出 repodata/repomd.xml仓库 ID 覆盖/etc/yum.repos.d/ 下重复 IDgrep -r ^[ /etc/yum.repos.d/装包速度慢是否仍走了公网源、enabled 状态yum repolist -v 确认源禁用多余源缓存不更新客户端缓存、服务器端元数据两端链路检查yum clean all makecache6. 写在最后几个值得长期坚持的小习惯最后分享几个我在实际项目中养成的习惯看起来不起眼但长期维护时非常管用。第一个习惯是给仓库文件按序号命名比如 01-local.repo、02-internal.repo、03-openEuler.repo。yum 处理多个 repo 文件时enabled 状态一目了然而且日常排查时 grep 一下序号就能快速定位机器当前优先用的是哪个源。第二个习惯是每次对仓库目录做任何修改都顺手把操作记录追加到一个变更日志文件里比如 date 时间、加了什么包、运行了什么命令。仓库出问题的时候这条日志能帮你把调查范围缩小一半以上尤其是团队里有多个人同时维护的时候。第三个习惯是不要贪心同步太多仓库。我见过有人图省事把 OS、EPOL、debuginfo、source 全部同步到本地结果磁盘空间白白占了上百 GB而生产环境里根本没人会去用 source 仓库。只同步你需要的内容更新频次和磁盘成本都会立刻降下来。最后一个建议是无论单机源还是内网源搭建完成后第一件事就是写一行 curl 验证 repomd.xml 是否能访问然后再去客户端执行 yum makecache。这是一个很简单的动作但能一次性绕开 90% 的“配置完了但不好使”的尴尬。仓库建设本身不难难的是把每一步都做成可验证、可回溯的工程习惯。希望这篇文章能帮你把这条路走顺。
返回列表