资讯详情

Linux 内网私有 yum 源搭建:同步、元数据与客户端接入

📅 2026/10/26 4:12:24 | 华诺云谱 👁 阅读
Linux 内网私有 yum 源搭建:同步、元数据与客户端接入
内网里装机器这件事只要规模上了两位数早晚会撞上同一个问题几十台服务器同时去公网拉软件包出口带宽被占满装一台机器要等十几分钟碰上上游源抽风的时候整批装机任务全卡在那里。我第一次遇到这个场景是在一个离线的机房环境根本不允许访问公网那时候才真正意识到把软件源搬到内网来不是优化项是必需项。这篇内容就把 Linux 搭建私有 yum 源仓库这件事从头到尾拆一遍包括为什么要做、目录怎么规划、同步怎么做、元数据怎么生成、客户端怎么接、出问题怎么查。无论你是刚接手运维的新手还是已经管着一批机器想把手动装包改成内部统一分发的老手下面的内容都能直接拿去用。1. 内网自建 yum 源到底解决什么问题先把话说清楚私有 yum 源不是把光盘挂上去当源这么简单的事它是一套软件包分发体系。核心逻辑是——把上游发行版仓库里的 RPM 包和元数据按原有目录结构搬到内网服务器上再用一个 Web 服务把它暴露出去内网所有机器把 repo 文件的 baseurl 指向这台服务器从此装包不再走公网。1.1 三类真实场景对号入座第一类是完全隔离的内网环境。生产网、测试网、某些工业场景的内网物理上就不通外网机器装完系统之后啥也没有连 vim 都装不上。这种场景下私有源不是可选项是唯一的软件来源。做法通常是用一台能上公网的机器做同步同步完再搬进去或者定期用移动介质倒一次数据。第二类是批量部署时的带宽与效率问题。一百台机器同时yum install同一个包出口带宽会被瞬间吃满而且每台机器都要独立去解析元数据、下载、校验重复劳动。内网源把这份流量收敛成一次客户端从局域网拉包速度从几百 KB/s 变成几十 MB/s装机时间从小时级压到分钟级。第三类是版本可控性。上游源是滚动的今天装和三个月后装拿到的可能是不同的小版本出问题时很难复现。私有源可以固定某一次同步的快照整个环境的软件版本保持一致这在需要长期维护的项目里价值极高。注意如果你的机器数量在十台以内而且能正常访问上游源其实不必急着自建。自建源会带来额外的磁盘成本、同步成本和维护成本规模不到阈值的时候性价比是负的。1.2 三种技术方案怎么选搭建私有 yum 源有几种主流路径选错了后面全是返工。我把它们的差异整理成一张表你按自己的条件挑方案数据来源空间占用适合场景主要限制全量同步上游仓库reposync从上游源拉取大单个发行版常见 15–30GB内网需要完整软件生态首次同步慢需定期增量本地 ISO 挂载安装镜像小单张 ISO 约 10GB只需要基础包环境极端受限包不全无更新自建 RPM 包仓库自己编译或收集的包按需通常几百 MB分发内部自研软件需要自己处理依赖与签名实际生产中常见的组合是用全量同步做基础仓库再挂一个自建包仓库放内部软件。两个仓库在目录上并列客户端 repo 文件里写两条配置互不干扰。这种方式既解决了系统包的问题也解决了内部软件分发的问题后面扩容也方便。还有一种取巧做法是把 ISO 挂载和全量同步结合先用 ISO 快速把基础仓库搭起来应急再后台慢慢同步完整仓库同步完了切换 baseurl。这在赶工期的时候很实用。1.3 目录结构必须提前规划这是最容易被忽略、后面最难改的一环。目录结构一旦铺开客户端 repo 文件就绑死了改一次要动几十台机器的配置。我的建议是三层结构/data/yum/ ├── rocky/ │ ├── 9/ │ │ ├── BaseOS/x86_64/os/ │ │ ├── AppStream/x86_64/os/ │ │ └── CRB/x86_64/os/ │ └── 8/ ├── epel/ │ └── 9/x86_64/ └── internal/ └── noarch/第一层是发行版或仓库来源第二层是大版本号第三层保持上游的仓库名/架构/os原始路径。保持原始路径的好处是客户端配置的 baseurl 能和上游文档一一对应出问题时对照官方文档直接就能看懂不用在脑子里做路径映射。os这一层是上游的习惯命名代表这是一个发行版发布仓库对应地还有updates之类的目录不同发行版叫法不同。如果你同步的源本身就是这种结构reposync会自动帮你保持别手动去改。2. 环境准备与核心组件认知动手之前先把需要的东西和它们的职责搞清楚比照着教程敲命令靠谱得多。很多人搭完之后不知道repodata目录是干嘛的一出问题就只能瞎试。2.1 服务器规格与磁盘容量估算私有源服务器的压力主要在磁盘和网络出口CPU 和内存要求很低。一台 2 核 4G 的虚拟机跑几十个客户端完全够用真正要算的是盘。容量估算可以按这个思路来以某个主流企业级发行版 9 为例BaseOS 大约 2GBAppStream 大约 15GBCRB 大约 2GB加上 EPEL 的十来 GB一套完整的基础源在 25–30GB 量级。如果同时保留两个大版本就是 60GB 左右。再留出 50% 的余量用于同步过程中的临时文件和后续增量实际规划 100GB 是比较舒服的。同步过程中的临时占用经常被低估reposync下载时会在目标目录里写.tmp文件createrepo重新生成元数据时会先写临时目录再替换这两个动作叠加时瞬时占用可能比最终体积多出 10–20%。盘写满了导致元数据生成中断是新手最常见的翻车点之一。磁盘类型上机械盘完全够用因为这是顺序读为主的场景。但如果客户端数量上百同时发起的 HTTP 请求会很多用 SSD 能让响应更干脆。文件系统用 ext4 或 xfs 都行xfs 在大量小文件场景下表现更好一些。2.2 四个核心工具各自干什么reposync负责把上游仓库的 RPM 包拉到本地。它读的是本地已经配好的 repo 文件所以你得先在服务器上把上游源的配置写好再用它去同步。记住这个顺序很多人上来就敲reposync然后报找不到仓库。createrepo_c负责扫描目录里的 RPM 包生成repodata目录。这个目录里是元数据文件客户端yum或dnf装包时第一步就是拉这些文件从中知道有哪些包、什么版本、依赖谁。没有 repodata这个目录对客户端来说就是一堆无意义的二进制文件。httpd或nginx负责把目录通过 HTTP 暴露出去。选哪个都行httpd 配置简单、和系统集成好nginx 并发性能更好、静态文件服务效率高。我一般用 nginx配置文件短排查起来直观。createrepo_c里的_c是 C 语言重写版本比老的 Python 版createrepo快一个数量级处理上万包时差距非常明显。新系统上直接装createrepo_c别装老的。# 一次性把工具装齐 dnf install -y createrepo_c nginx dnf-plugins-corednf-plugins-core提供dnf reposync和dnf config-manager前者是同步主力后者用来管理 repo 配置开关非常顺手。2.3 防火墙与 SELinux别急着关我见过太多人第一反应是systemctl stop firewalld加setenforce 0。这在临时测试环境无所谓生产环境这么干是给自己埋雷。正确的做法是精确放行。防火墙放行 80 端口firewall-cmd --permanent --add-servicehttp firewall-cmd --reload firewall-cmd --list-servicesSELinux 是更隐蔽的坑。你把仓库放在/data/yum这种非标准路径下nginx 或 httpd 默认没有权限读浏览器访问直接 403日志里写的是Permission denied。解决办法是给这个目录打上正确的安全上下文标签semanage fcontext -a -t httpd_sys_content_t /data/yum(/.*)? restorecon -Rv /data/yumsemanage来自policycoreutils-python-utils包。这两条命令的意思是把/data/yum及其所有子目录的默认标签设为 Web 服务可读然后立即应用。做完之后ls -Z能看到httpd_sys_content_t字样就对了。提示如果你发现访问 403 但文件权限明明是 755先别改权限去看/var/log/audit/audit.log里有没有avc: denied记录。有的话基本就是 SELinux 标签问题用ausearch -m avc -ts recent能快速定位。3. 实操第一步把上游软件包同步下来这一步是整个流程里最耗时的环节也是最需要耐心调参的。同步策略定得好后面维护轻松定得不好每天都要盯着磁盘余量。3.1 先配好上游源再谈同步同步服务器本身要能访问上游源。配好 repo 文件后用dnf repolist确认能列出来dnf repolist输出里能看到每个仓库的 ID 和包数量。记住这些 IDreposync的--repoid参数用的就是它们。如果某个仓库不想要用dnf config-manager --set-disabled repoid关掉避免同步时误拉。接下来是同步命令这是核心参数逐个说dnf reposync \ --repoidbaseos \ --repoidappstream \ --download-metadata \ --newest-only \ --delete \ -p /data/yum/rocky/9逐个拆解--repoid可重复指定一次同步多个仓库。比一个个跑效率高因为连接复用。--download-metadata把上游的repodata目录一起下下来包括comps.xml组信息和模块元数据。这个参数非常关键用了它就不用再手动createrepo而且能保住模块化包的信息。老版本的yum reposync没有这个参数只能后续手动生成这是个重要的版本差异。--newest-only只下每个包的最新版本。不加的话会把仓库里所有历史版本全拉下来体积可能翻三到五倍。除非你有明确的版本回退需求否则一定要加。--delete本地有但上游没有的包同步时删掉。保持本地和上游一致避免陈年垃圾堆积。-p目标路径。reposync会在该路径下按仓库 ID 建子目录所以最终结构是/data/yum/rocky/9/baseos/这样。注意这里生成的目录名是 repoid不是上游原始路径跟你前面规划的BaseOS/x86_64/os/结构不一样。这是很多人第一次搭的时候会懵的地方。3.2 路径对齐的两种处理方式上面那个路径偏差必须处理掉否则客户端配置会很别扭。两个办法第一种是同步时就对上。reposync的-p指定到父级配合后续mv调整mv /data/yum/rocky/9/baseos /data/yum/rocky/9/BaseOS mkdir -p /data/yum/rocky/9/BaseOS/x86_64/os mv /data/yum/rocky/9/BaseOS/* /data/yum/rocky/9/BaseOS/x86_64/os/ 2/dev/null坦白说这个操作有点笨容易出错。我更推荐第二种直接接受 repoid 目录名别强求和上游一致。因为路径是你自己定的客户端配置里写清楚就行没必要为了看起来像上游折腾自己。统一用/data/yum/发行版/版本/repoid/这种结构简单直接脚本也好写。3.3 只同步需要的包别一把梭全量同步在带宽紧张的环境里可能跑一整夜。如果你的需求只是内网能装常用工具完全可以按需下载体积能从几十 GB 压到几百 MB。做法是先配一个指向内网的源或者直接用上游源用--downloadonly把指定的包连同依赖一次性下到目录里dnf install --downloadonly \ --downloaddir/data/yum/internal/noarch \ --resolve \ vim-enhanced tar gzip net-tools lsof tcpdump--resolve会自动把依赖链上的所有包一起解决掉这是关键。不加的话你只下到一个主包装的时候还是缺依赖。下完之后再跑createrepo_c生成元数据一个精简版的内部源就有了。这个方式的局限是不会自动更新。上游发新版本了你不主动去下源里永远是旧包。适合只求能装上、不追求最新的场景。3.4 增量同步与磁盘清理的节奏首次全量同步之后日常维护就靠增量。增量同步的命令和首次完全一样reposync会自动比对本地已有文件跳过已下载的包只拉新增和变更的。实际耗时通常在几分钟量级。建议用 systemd timer 或者 cron 定时跑时间选在业务低峰。下面是一个 cron 的例子# /etc/cron.d/yum-sync 30 3 * * * root /usr/local/bin/sync-repo.sh /var/log/yum-sync.log 21脚本里做的事同步、清理、生成元数据、写日志。日志一定要留出问题时这是唯一的线索。日志按天切割保留两周避免把根分区写满。磁盘清理方面--delete已经处理了大部分。补充一个容易被漏掉的点reposync中断时会留下.tmp后缀的残file这些文件不会被--delete清掉日积月累能占好几个 G。定期跑一次清理find /data/yum -name *.tmp -mtime 7 -delete-mtime 7是只删七天前的避免误删正在下载中的临时文件。这个细节不注意清理脚本跑在同步任务中间会把正在下的包删掉然后同步报错非常难查。4. 实操第二步生成元数据并对外发布包下完了只是原料元数据才让这些原料变成可用的仓库。这一步的坑比同步环节更隐蔽因为出错时往往不报错只是客户端装不上或者装到旧版本。4.1 什么时候需要手动 createrepo如果你用了--download-metadata理论上不需要再手动生成元数据上游的repodata已经跟着下来了。但以下几种情况必须手动跑用--downloadonly按需下载的包没有上游元数据自己编译或收集的内部 RPM 包你需要重建元数据来修正某些异常同步过程中元数据下载失败包全了但repodata缺失手动生成的命令createrepo_c /data/yum/internal/noarch/如果是更新已有仓库只处理新增或变更的包速度快很多createrepo_c --update /data/yum/internal/noarch/--update的原理是读旧的元数据只对新增包做处理然后合并。但有个坑如果删了包--update不会把旧元数据里的记录清掉客户端会看到一个已经不存在的包下载时 404。所以删包之后要跑一次不带--update的完整重建或者干脆每次都完整重建包量不大时差异可以忽略。4.2 模块化元数据的坑必须单独说这是我认为整个搭建过程中最容易踩的坑。某些发行版 8 之后的版本引入了模块化modularityAppStream仓库里除了普通的 RPM 包还有一套模块元数据modules.yaml描述哪些包属于哪个模块流。createrepo_c不会生成这个文件它只处理 RPM 包。结果就是你用createrepo_c手动重建了AppStream的元数据客户端dnf install某个模块里的包时报错提示找不到模块或者装上了但版本不对。排查起来非常痛苦因为repolist显示仓库正常包也在目录里躺着就是装不上。正确做法只有两条一是用--download-metadata让上游的modules.yaml原样下来别手动重建二是如果必须重建重建完之后手动把上游的modules.yaml拷贝到新生成的repodata/目录里。记住modules.yaml文件名里带哈希值拷贝的时候要保持一致或者用modules.yaml这个通用名加个modules.yaml.gz。判断方法很简单看目录里有没有这个文件ls /data/yum/rocky/9/AppStream/x86_64/os/repodata/ | grep -i modules4.3 Web 服务的配置要点nginx 配置静态文件服务短小精悍server { listen 80; server_name _; root /data/yum; autoindex on; autoindex_exact_size off; autoindex_localtime on; location / { try_files $uri $uri/ 404; } access_log /var/log/nginx/yum-access.log; error_log /var/log/nginx/yum-error.log; }autoindex on打开目录浏览好处是用浏览器直接能验证目录结构和文件是否可访问排查时省很多事。生产环境不想暴露目录结构可以关掉但搭建阶段建议开着。autoindex_exact_size off会把文件大小显示成 KB/MB比字节数好读。autoindex_localtime on让时间显示为本地时区否则默认 UTC看日志时容易算错时间。配置完重载nginx -t systemctl reload nginx systemctl enable --now nginxnginx -t先测语法通过了再 reload别直接 reload 一个语法错误的配置进去。验证方式就是浏览器或者 curl 访问curl -I http://127.0.0.1/rocky/9/BaseOS/x86_64/os/repodata/repomd.xml返回 200 就通了。返回 403 基本是 SELinux 标签或文件权限返回 404 是路径不对返回 500 去看 error_log。这三种情况覆盖了九成问题。4.4 权限配置的最小化原则仓库目录的权限不用给太宽。推荐做法chown -R root:nginx /data/yum chmod -R 755 /data/yum find /data/yum -type d -exec chmod 755 {} \; find /data/yum -type f -exec chmod 644 {} \;目录 755、文件 644属组给 Web 服务用户这样 nginx 能读其他用户只能读不能写。千万别图省事chmod -R 777一个对内网开放的软件源目录权限全开意味着任何能访问的机器都能往里塞文件被人替换一个 RPM 包就是供应链问题。5. 实操第三步客户端接入与验证服务器端搭好只是做了一半客户端配置写不对前面全白干。这一节讲怎么配、怎么验、怎么防止看起来通了其实没通。5.1 repo 文件的写法与关键字段客户端配置放在/etc/yum.repos.d/下一个仓库一个.repo文件或者多个仓库放一个文件里用段落区分[local-baseos] nameLocal BaseOS baseurlhttp://10.0.0.10/rocky/9/BaseOS/x86_64/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-rocky metadata_expire3600 [local-appstream] nameLocal AppStream baseurlhttp://10.0.0.10/rocky/9/AppStream/x86_64/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-rocky metadata_expire3600几个字段值得细说baseurl必须指向包含repodata目录的那一层。这是新手第一大错误来源——把 baseurl 写成.../os/repodata/或者.../os/BaseOS/客户端就找不到元数据。判断标准baseurl 后面拼上repodata/repomd.xml这个 URL 能用浏览器打开就对了。gpgcheck1和gpgkey一起用对包做签名校验。内网源同样要开校验因为内网不等于可信包在传输或存储过程中被替换、损坏都有可能。gpgkey 可以直接指向本地文件也可以指向你服务器上的公钥地址。首次配置时要把公钥导入rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-rockymetadata_expire控制元数据缓存过期时间。默认值比较保守私有源更新频率不高的话设成 3600 秒一小时能减少重复请求。如果你的源一天才同步一次设成86400也行。enabled1之外建议把系统自带的公网源全部禁用避免客户端在私有源出问题时悄悄回退到公网源导致明明内网有源却装了个不同版本的诡异情况。禁用命令dnf config-manager --set-disabled * # 先全关 dnf config-manager --set-enabled local-baseos local-appstream # 再开私有源*这个写法会匹配所有仓库操作前确认一下repolist的输出别把不该关的关了。5.2 一套完整的验证清单配置完别急着下结论按这个清单走一遍每一项都有明确的预期结果# 1. 清缓存避免用旧数据骗自己 dnf clean all # 2. 重建缓存这一步会拉所有仓库的元数据 dnf makecache # 3. 列出所有可用仓库确认私有源在里面且状态正常 dnf repolist -v # 4. 查一个具体的包确认能看见 dnf list available vim-enhanced # 5. 看包的信息确认来源是私有源而不是别的 dnf info vim-enhanced # 6. 实际装一个做端到端验证 dnf install -y lsof第 5 步的dnf info输出里有Repo字段显示包来自哪个仓库。这一步很多人跳过结果装完发现是从公网源下的白折腾。第 2 步的dnf makecache如果报错错误信息非常关键直接看关键字就能定位Cannot download repomd.xml是路径或 Web 服务问题repomd.xml signature could not be verified是 GPG 问题Metadata file does not match checksum是元数据和实际文件不一致通常是同步中途被打断。5.3 用脚本批量下发客户端配置机器一多手动配一百遍不现实。写个脚本通过自动化工具推下去#!/bin/bash set -e REPO_HOST10.0.0.10 REPO_BASEhttp://${REPO_HOST}/rocky/9 mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ 2/dev/null || true cat /etc/yum.repos.d/local.repo EOF [local-baseos] nameLocal BaseOS baseurl${REPO_BASE}/BaseOS/x86_64/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-rocky metadata_expire3600 [local-appstream] nameLocal AppStream baseurl${REPO_BASE}/AppStream/x86_64/os/ enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-rocky metadata_expire3600 EOF dnf clean all dnf makecacheset -e保证任何一步失败就退出避免半成品状态。把原有 repo 文件挪到 backup 而不是直接删出问题时能快速回滚。然后执行bash client-setup.sh。提示批量下发前先在一台机器上跑通全流程确认无误再推。我见过有人脚本里 baseurl 少写了一个斜杠一百台机器全部配错第二天早上才发现回滚又是一轮。6. 常见问题排查实录搭建过程中会遇到各种报错这里把高频的整理成速查表再补几个查起来特别费劲的隐性问题。6.1 报错速查表现象可能原因排查方向与解法Cannot download repomd.xmlbaseurl 路径错 / Web 服务未起 / 防火墙拦截浏览器直接访问 baseurl 看是否返回 200访问目录返回 403SELinux 标签不对 / 文件权限不足ls -Z检查标签ausearch -m avc看审计日志repomd.xml signature could not be verifiedGPG 公钥未导入 / 公钥不匹配rpm -q gpg-pubkey查看已导入公钥重新 importMetadata file does not match checksum元数据与包不一致同步中断重新同步并完整重建元数据客户端能看到包但下载 404元数据里有记录实际文件被删完整重建元数据别用--update模块包装不上、提示找不到模块modules.yaml缺失检查 repodata 目录补回模块元数据同步跑了一夜还没结束未加--newest-only拉全量历史版本加参数重跑或先清理本地已有文件磁盘写满导致同步中断容量估算不足清理.tmp残file扩容或改按需同步这张表覆盖了我实际遇到过的绝大部分情况。遇到问题时先按现象对号比盲目搜报错信息效率高得多。6.2 三个特别隐蔽的问题第一个元数据没更新客户端装到旧版本。现象是上游已经发了新版本你在服务器上看目录里也有新包但客户端dnf list看不到。原因是同步只拉了包没有重建元数据。--download-metadata模式下拉包和元数据是同步进行的但如果同步中途失败可能出现包下了一部分、元数据没更新的中间状态。排查方法比对repodata/repomd.xml的时间戳和最新包的时间戳。如果包比元数据新说明元数据过期了手动重建一次即可。这个问题最恶心的地方在于它不报错客户端一切正常只是版本不对靠肉眼看很难发现。第二个--update模式下的幽灵包。前面提过createrepo_c --update不会清理已删除包的元数据记录。场景是这样的你发现某个包有问题从目录里删掉了然后跑createrepo_c --update客户端依然能dnf info到它装的时候报 404。解决办法是删除包之后跑完整重建createrepo_c /data/yum/internal/noarch/包量大的时候完整重建要几十秒到几分钟可以接受。只要做过任何删除或替换操作就别用--update。第三个客户端 cache 导致的假故障。有时候你明明在服务器上确认了包存在、元数据也对客户端就是装不上。八成是客户端缓存问题。dnf的缓存在/var/cache/dnf/元数据过期时间内不会重新拉。快速验证dnf clean all dnf makecache如果清完缓存就好了说明是缓存问题把客户端的metadata_expire调小一点比如同步完之后主动推一次dnf clean all到所有机器。6.3 几个实操心得心得一搭建阶段先在测试机上把整个流程跑三遍包括故意制造错误再修复。比如故意写错 baseurl、故意删掉 repodata、故意不给 SELinux 打标签。这些错误你在测试环境见过一次生产环境遇到时就不会慌。心得二同步脚本一定要加日志和失败告警。reposync是静默的失败了不会通知你第二天早上才发现源是空的。脚本里加个判断同步后检查目标目录的大小或文件数量低于阈值就发告警。心得三源服务器的 Web 服务一定要设成开机自启systemctl enable nginx。这个太基础了但我确实遇到过重启之后忘了 enable第二天全公司的机器都装不上包的情况。同理同步的定时任务也要确认生效。7. 长期维护版本、空间与监控搭起来只是开始能长期跑住不出问题才算真的搭好了。这部分讲讲日常维护里需要持续关注的东西。7.1 多版本并存的目录策略一个常见的需求是同时维护两个大版本的源比如老系统还在跑版本 8新系统已经上版本 9。前面规划的目录结构已经支持这个/data/yum/发行版/8/和/data/yum/发行版/9/并列客户端按需指向。同步脚本要按版本分开跑别混在一个reposync命令里。原因是不同版本的 repoid 可能重名混在一起容易搞乱。分开跑还有个好处是能分别控制同步频率——新版本同步勤一点老版本一周一次就够。老版本的生命周期到了之后不要立刻删目录。保守做法是先在客户端配置里禁用观察两周确认没有机器在用再删。删之前先mv到一个archive目录再观察一周。这个流程看着繁琐但能避免某个没人记得的老系统突然装不上包的事故。7.2 空间与同步耗时的日常监控两个核心指标磁盘使用率和同步耗时。磁盘使用率低于 70% 比较安全超过 85% 就该处理了。最简单的监控就是一条 cron配合简单的阈值判断#!/bin/bash THRESHOLD85 USAGE$(df /data | awk NR2 {gsub(/%/,,$5); print $5}) if [ $USAGE -ge $THRESHOLD ]; then echo yum repo disk usage ${USAGE}% on $(hostname) at $(date) | mail -s yum源磁盘告警 opsexample.internal fi同步耗时也需要记录。把每次同步的开始结束时间写进日志定期看一眼趋势。如果某天耗时突然翻倍可能是上游仓库结构调整了也可能是网络变差了。耗时异常往往是容量问题的前兆早点发现能省很多事。7.3 元数据完整性的定期校验这是个很少人做但很有价值的动作定期校验元数据里记录的包是否真实存在。repomd.xml里有校验和可以用createrepo_c的验证能力或者简单脚本核对。一个轻量的做法是每次同步完成后随机抽几个包做rpm -qp校验确认文件没损坏find /data/yum -name *.rpm | shuf -n 20 | while read f; do rpm -qp --nosignature $f /dev/null 21 || echo CORRUPT: $f doneshuf -n 20随机抽 20 个成本低但能发现大面积的损坏问题。文件损坏的原因可能是磁盘故障、传输中断、或者存储层的静默错误。抽样发现的概率不高但一旦发现就说明存储有问题值得立刻深查。7.4 内部自研包怎么纳入进来最后说说内部软件的发布。自己打的 RPM 包扔进/data/yum/internal/noarch/或者对应架构的目录然后跑一次createrepo_c就完事了。有几个细节值得注意包的Name、Version、Release要规范因为客户端判断有没有新版本就是靠这三个字段比较。Release里带上构建号比如1.el9、2.el9每次发包递增客户端才能正确识别为升级。依赖声明要写全。自己打的包如果依赖了某个系统库但没在 spec 里声明客户端装的时候不会自动拉运行时报找不到库。打包时在干净的容器里用rpmrebuild或者ldd检查一遍动态依赖能避免大部分这类问题。签名这件事内网源也可以做。如果嫌 GPG 签名的流程麻烦至少要在客户端把gpgcheck打开针对系统包内部包可以单独建一个仓库把gpgcheck0但要清楚这是在降低安全等级得配合其他手段比如发布前的包哈希校验补回来。把一个完整的内部发布流程串起来大概是开发提交构建产出的 RPM 到制品库发布脚本把包同步到源服务器的对应目录跑createrepo_c重建元数据然后触发客户端dnf clean all。这套流程跑顺了内网软件分发基本不用再人工干预。我自己在这套东西上栽得最狠的一次是早期用reposync没加--newest-only一个 AppStream 目录拉出了一个多 T 的体量磁盘直接爆掉还把上游源的请求频率搞得太高被限了速。后来改成先估算、再小范围试跑、确认体积合理之后再全量跑再没出过类似问题。慢一点比返工快。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑