☰
内网离线环境自建 yum 源仓库:从规划、同步到排障实战
2026/10/27 3:04:23 网站建设 项目流程

1. 什么情况下才值得自建一个 yum 源仓库

聊 yum 源仓库这件事,我一般先问对方一句:你手上有多少台机器要装包?如果答案是三五台、而且能连公网,那我劝你别折腾,直接配个就近的镜像地址就够了。但只要出现"几十上百台、内网不通外网、要保证每次装出来版本一致"这三种情况里的任意一种,自建源仓库立刻从"可选项"变成"基础设施"。

我见过太多团队的做法是:拿个 U 盘把 rpm 包拷来拷去,缺依赖了再回去拷,装到第五百次的时候发现两台机器的 glibc 版本对不上,排查两天。这种做法本质上是把包管理退化成了文件复制,yum/dnf最值钱的两样东西——依赖解析和元数据索引——全被扔掉了。自建源仓库干的事,就是把这两样东西重新捡回来:你有一份带索引的包集合,客户端指过去,install一条命令就完事。

所以这篇东西适合谁看?做内网环境交付的、要批量初始化服务器的、做离线环境运维的、以及被"客户现场没有外网"折磨过的同行。内容从目录规划一路写到故障排查,中间所有参数和命令我都按能直接抄的标准给,同时把"为什么这么配"讲清楚,因为照抄命令只能解决一次问题,理解逻辑才能解决一类问题。

1.1 四个真正促成自建源的场景

第一个是内网隔离。生产网段不通公网是常态,哪怕通,很多单位也不允许生产机直连外部软件仓库,因为拉取行为不可控、包来源不可审计。

第二个是批量交付。同一批机器要在几小时内全部初始化完成,如果每台都去外网拉几百兆的包,交付窗口根本不够用。

第三个是版本漂移。上游仓库的包是会更新的,今天装的是nginx-1.20.1-10,三个月后同一台机器重装可能变成nginx-1.20.1-14。对于需要长期维持环境一致性的场景,这种漂移是事故来源。自建源可以把包集合冻结在某个时间点,重装一百次结果都一样。

第四个是带宽成本。这点常被忽略。一百台机器同时执行全量更新,出口带宽瞬间打满,业务流量跟着抖。本地源放在内网千兆甚至万兆环境里,这个瓶颈直接消失。

1.2 自建源与"本地装 rpm 包"的本质区别

这两件事经常被混为一谈。rpm -ivh xxx.rpm是单包安装,依赖缺了自己想办法;yum install走的是仓库,它会去读repodata/下的元数据文件,知道"这个包依赖哪些包、这些依赖包在哪个位置、版本要求是什么",然后一次性把依赖链全装完。

所以一个合格的源仓库,核心不是那些 rpm 文件,而是 repodata 目录。很多人把几百个 rpm 拷到目录里,客户端配置好地址却报"找不到包",原因就一个:没有生成元数据。createrepo这个工具存在的唯一意义,就是扫描目录里的 rpm,把包头信息抽出来,生成repomd.xml和一堆压缩的索引文件。理解这一点,后面所有排查思路都会顺很多。

1.3 先把成本算清楚再动手

自建源仓库不是零成本的。全量同步一个企业级发行版的完整软件集合,光主仓库就要十几到二十几 GB,加上附加仓库、开发工具链、常见第三方源,很容易冲到五十 GB 以上。如果还要保留历史的多个版本快照,翻倍是常事。

除了磁盘,还有两个隐性成本:同步窗口和维护责任。同步窗口指的是每次上游更新后,你要在多长时间内把新包拉下来、重建索引、并保证客户端不会在索引重建的中间态访问到半成品。维护责任指的是这个仓库从此归你管了——包坏了、索引错了、签名过期了,都是你的事。

我的建议是:第一次做,先只同步你最常用的两三个仓库,把流程跑顺,磁盘留出三倍余量,再考虑扩展。一上来就全量同步、结果磁盘爆掉导致元数据写坏,这个剧本我见过不止一次。

2. 三种拓扑怎么选:单机源、HTTP 源、镜像型源

选型这件事,很多教程直接跳过,上来就教你装 httpd。但实际场景差别很大,装错了后面返工很痛苦。我按复杂度和适用面把常见做法分成三类,你可以直接对号入座。

2.1 单机本地源:用 file:// 或光盘挂载

最轻量的方案。把安装镜像挂到某个目录,客户端.repo文件里baseurl=file:///mnt/iso/BaseOS,完事。适合单机、临时、或者给一台机器做最小化安装后补包。

优点是零依赖、不占额外磁盘(镜像本身除外)、不需要任何服务进程。缺点也很明显:只能本机访问,镜像内容固定,缺包就是缺包。如果你只是想让一台离线机器能装几个基础包,这个方案足够,不要过度设计。

mkdir -p /mnt/iso mount -o loop,ro /data/images/sysinst.iso /mnt/iso

记得写进/etc/fstab,加loop,ro和defaults 0 0,否则重启就没了——这个低级失误造成的问题量,比大多数复杂故障都多。

2.2 局域网 HTTP 源:httpd 或 nginx 挂目录

这是绝大多数团队最终会落到的地方。目录放在一台配置还算过得去的机器上,前面挂个轻量 Web 服务,客户端通过http://内网IP/repo/...访问。这个方案的好处是扩展性好——加机器只是加客户端配置,服务端不用动;同时可以配合反向代理做缓存、做访问日志、做限速。

Web 服务选哪个其实无所谓,我倾向 httpd,因为它的目录列表和 MIME 处理对 yum 这种"按路径取文件"的场景几乎是零配置。nginx 也行,性能更好,但要记得打开autoindex,否则客户端拿不到目录列表(虽然正常拉取不需要列表,但人工核对时很有用)。

2.3 镜像型源:用 reposync 把上游搬回本地

严格说这不是另一种拓扑,而是"包从哪来"的另一种答案。前两种方案的包来源是镜像文件或手工拷贝,镜像型方案则是定期从上游仓库把包和元数据整份同步下来,本地重建索引后对外提供。

它的价值在于可持续。上游发了安全更新,你这边跑一次同步脚本就能跟进;想冻结版本,就把同步任务停掉或者锁定快照目录。代价是需要脚本化运维,还要处理增量、清理、失败重试。

方案适用规模磁盘占用维护成本版本可控性
光盘/镜像挂载1-3 台低(镜像本身)极低完全冻结
HTTP 静态目录10-200 台中低手工控制
reposync 镜像50 台以上高(数十 GB)中高可按批次冻结
多级镜像 + 缓存代理500 台以上很高高强

我个人的实际经验是:先做 HTTP 静态目录,把客户端配置和验证流程跑通,再上 reposync 做自动化同步。倒过来做,往往在同步脚本还没稳定的时候就被客户端各种报错误导,分不清是同步问题还是配置问题。

3. 目录规划与空间估算:把坑提前埋掉

这一步最容易被轻视,但它决定了你半年后还能不能维护。我见过所有包平铺在一个目录里的仓库,一千多个 rpm 混在一起,想删个旧版本都得靠ls | grep;也见过把源目录放在根分区、跑三个月磁盘满、然后元数据写坏、整个仓库报废的。

3.1 目录结构:一层仓库一层目录

我的习惯是按"来源仓库"分一级目录,按"发行版大版本"分二级,包目录交给工具自己管:

/data/yum-repo/ ├── os-baseos/ # 基础系统仓库 │ ├── Packages/ # rpm 实体 │ └── repodata/ # 元数据 ├── os-appstream/ # 应用流仓库 ├── os-extras/ ├── epel-extra/ # 第三方扩展 └── tools-dev/ # 内部打包的工具链

每个一级目录是一个独立的 yum 仓库,客户端可以单独启用或禁用。这种划分的好处是故障隔离:某个仓库同步失败,不影响其他仓库可用;也是权限隔离:可以只让某类机器访问某个目录。

千万不要把所有东西塞进一个仓库目录。一旦混在一起,createrepo每次都要扫全量,索引文件会变得巨大,客户端makecache慢得离谱,而且没法做粒度控制。

3.2 磁盘容量怎么估

不要凭感觉。估算是这样的:先统计目标仓库的包数量和平均体积,再乘一个安全系数。

  • 企业级发行版的主仓库(BaseOS 一类):包数约 1500-2500,总容量 10-15 GB
  • 应用流仓库(AppStream 一类):包数更多,含模块化内容,容量 15-20 GB
  • 常见第三方扩展源:包数 1 万以上,容量 30-50 GB
  • 开发工具链、语言运行时等:视需求,5-30 GB 不等

安全系数我给2.5 到 3 倍。原因有三:同步过程中新旧包会同时存在;索引重建时会产生临时文件;再加上日志和备份。一个实际占用 20 GB 的仓库,分区至少给 60 GB。

提示:把源目录单独挂一个分区或独立卷,不要和系统根分区共享。这条不是洁癖,是保命。根分区写满会导致系统层面的连锁故障,比仓库坏掉严重得多。

3.3 权限、SELinux 与防火墙三件套

Web 服务读不到文件,九成是这三样之一没配对。我按顺序走一遍。

目录权限要让 Web 服务的运行用户可读可进入:

chown -R root:root /data/yum-repo chmod -R 755 /data/yum-repo

SELinux 如果是 enforcing 状态,光改权限没用,必须给目录打上正确的上下文标签:

semanage fcontext -a -t httpd_sys_content_t "/data/yum-repo(/.*)?" restorecon -Rv /data/yum-repo

注意semanage fcontext只是写规则,必须再执行restorecon才真正生效。这一步是新手最常漏的:规则加了,标签没打,然后对着一堆 403 抓头发。

防火墙放行 HTTP:

firewall-cmd --permanent --add-service=http firewall-cmd --reload firewall-cmd --list-services

如果改了非标准端口,要用--add-port=8080/tcp的形式,并且同步在 SELinux 侧放行该端口(semanage port -a -t http_port_t -p tcp 8080),否则 httpd 起不来,日志里会明确说权限被拒。

3.4 时间同步这件事,和源仓库的关系比想象中大

客户端判断元数据是否过期,靠的是本地记录的下载时间和metadata_expire参数。如果服务端和客户端时间差了几个小时,可能出现"刚同步的新包,客户端认为缓存还新鲜,死活不去拉"的情况。

服务端统一跑时间同步服务,客户端也保证同步,这条在离线环境里常被忽略,因为离线机器往往连不上时间源。稳妥做法是在内网放一台时间服务器,其余机器指向它;实在没有条件,至少保证所有机器的时钟偏差在分钟级以内,并且调大客户端的metadata_expire值,让它少依赖时间判断。

4. 从零搭起来:同步、建索引、发布、验证

前面都是准备,这一节是真正动手。流程是四步:把包弄到本地、生成元数据、通过 Web 暴露出去、客户端配置并验证。每一步我都会指出验证方法,别等最后一起调。

4.1 拿到包:reposync 的正确用法

reposync属于dnf-utils(老版本在yum-utils里),作用是按仓库 ID 把远程仓库的包拉到本地。

# 先确认源仓库定义存在 dnf repolist # 同步指定仓库到目标目录,只取最新版本,并删除本地多余的包 reposync \ --repoid=os-baseos \ --download-metadata \ --newest-only \ --delete \ --download-path=/data/yum-repo

几个参数值得单独说:

--download-metadata会连元数据一起拉下来,这样大部分情况下本地不用再跑createrepo。但这个参数在部分版本的reposync里不支持,报"unrecognized arguments"就是版本问题,遇到就退回手动建索引的路子。

--newest-only只取每个包的最新版本,能省大量空间。但如果你需要保留多版本回滚能力,就去掉它。

--delete会删掉本地存在而上游已经没有的包,保持严格镜像。第一次同步千万别加这个参数,万一源配置指错了目录,一条命令能把你的仓库清空。

同步完检查一下:

du -sh /data/yum-repo/os-baseos ls /data/yum-repo/os-baseos/Packages | wc -l

4.2 生成元数据:createrepo_c 与增量更新

包到位了但没有repodata,客户端就是瞎子。生成索引:

createrepo_c /data/yum-repo/os-baseos

如果目录里已经有索引,只是新增或删除了部分包,用增量模式快得多:

createrepo_c --update /data/yum-repo/os-baseos

--update的原理是读旧索引、只处理变化的包,包多的时候能把几分钟压到几秒。但要注意:如果你删除了包,--update也可能留下残留索引项,稳妥做法是定期做一次全量重建,或者删除包之后直接全量跑一次。

需要支持yum groupinstall这类分组安装的,还要带上分组定义文件:

createrepo_c -g /data/yum-repo/os-baseos/comps.xml /data/yum-repo/os-baseos

分组文件一般能从安装镜像的repodata目录里找到,名字类似*-comps.xml。没有它,group list是空的,groupinstall会报找不到组。

4.3 对外发布:httpd 配置要点

配置文件扔到/etc/httpd/conf.d/yum-repo.conf:

Alias /repo "/data/yum-repo" <Directory "/data/yum-repo"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory>

Options Indexes允许浏览目录,方便人工核对;Require all granted是访问控制,内网环境通常直接放开,如果要限制网段可以写Require ip 10.0.0.0/8。

启动并自启:

systemctl enable --now httpd systemctl status httpd --no-pager

验证方式不要用浏览器,用命令行更准:

curl -I http://127.0.0.1/repo/os-baseos/repodata/repomd.xml

返回200才算通。返回403查 SELinux 和目录权限,404查路径拼写和 Alias 配置,连不上查防火墙。

4.4 客户端配置与三道验证

客户端.repo文件写到/etc/yum.repos.d/local.repo:

[local-baseos] name=Local BaseOS baseurl=http://10.0.0.10/repo/os-baseos/ enabled=1 gpgcheck=0 metadata_expire=3600

如果做了签名校验,把gpgcheck改成1并指定gpgkey。关于签名后面单独讲,这里先跑通连通性。

三道验证,缺一不可:

# 第一道:仓库能被识别 dnf repolist all # 第二道:元数据能拉下来 dnf clean all && dnf makecache # 第三道:包能被搜索和安装 dnf list available | head -20 dnf install -y --downloadonly some-basic-package

很多人只做第一道就以为成功了。repolist显示仓库存在,只代表配置文件被解析,不代表元数据能下载。第二道才会真正去请求repomd.xml,这里失败才是最常见的情况。

4.5 模块化内容与 repo_gpgcheck 的额外注意

较新的发行版把一部分内容做成了模块(module),元数据里有单独的modules.yaml。用reposync --download-metadata拉下来的通常已经包含,如果是手工组装的仓库,需要单独注入:

modifyrepo_c --mdtype=modules modules.yaml /data/yum-repo/os-appstream/repodata/

另外gpgcheck和repo_gpgcheck是两个不同的开关,前者校验 rpm 包的签名,后者校验元数据本身的签名。启用repo_gpgcheck需要在repodata目录里放repomd.xml.asc,否则客户端直接报错拒绝使用该仓库。内部仓库如果包来源可控,我一般只开gpgcheck,元数据签名按需再加。

5. 日常运维:同步节奏、缓存一致性与磁盘水位

仓库搭起来只是开始,真正的成本在后面的日常。这一节讲三件长期要做的事:定期把上游的更新搬回来、让客户端及时看到更新、别让磁盘慢慢爬满。

5.1 同步脚本要写成幂等的

定时任务里跑的脚本,最重要的特性是可重复执行不出错。我用的骨架大概是这个:

#!/bin/bash set -euo pipefail REPO_ROOT=/data/yum-repo LOG=/var/log/repo-sync.log LOCK=/var/run/repo-sync.lock exec 9>"$LOCK" flock -n 9 || { echo "another sync is running" >> "$LOG"; exit 1; } for repo in os-baseos os-appstream epel-extra; do echo "=== $(date '+%F %T') syncing $repo ===" >> "$LOG" reposync --repoid="$repo" --download-metadata --newest-only \ --download-path="$REPO_ROOT" >> "$LOG" 2>&1 || { echo "sync $repo failed" >> "$LOG" continue } createrepo_c --update "$REPO_ROOT/$repo" >> "$LOG" 2>&1 done echo "=== $(date '+%F %T') done ===" >> "$LOG"

三个细节值得说明。flock是防止上一轮还没跑完、下一轮又起来,两个进程同时写索引会造成元数据损坏,这个坑非常隐蔽。|| continue让单个仓库失败不中断整个流程。把日志统一追加到文件,出问题时有据可查。

5.2 客户端什么时候能看到新包

服务端的索引更新了,客户端不一定立刻知道。这里有三个层级的缓存:

第一层是客户端的metadata_expire,默认可能是 48 小时或更久,具体看发行版。超过这个时间,下一次执行命令时才会重新拉元数据。

第二层是dnf的本地缓存目录/var/cache/dnf,里面存着下载过的元数据和包。

第三层是makecache生成的时间戳文件。

所以一个典型的现象是:你凌晨两点同步完,上午十点同事说"装不到新版本"。解决方式有两种——要么把metadata_expire调小(比如 900 秒),代价是客户端请求变频繁;要么在同步脚本结束后主动通知客户端执行dnf clean expire-cache。

我倾向第二种,因为同步是周期性事件,主动清理比全局缩短缓存时间更精准。clean expire-cache只把元数据标记为过期,不动已下载的包,比clean all温和得多。

5.3 磁盘水位与旧版本清理

同步半年之后,磁盘占用会明显上涨,尤其是没加--newest-only的情况。我一般分两步处理。

先看哪些包有多版本:

repomanage --old /data/yum-repo/os-baseos/Packages | head -30 repomanage --old /data/yum-repo/os-baseos/Packages | wc -l

确认数量合理后,可以直接删:

repomanage --old /data/yum-repo/os-baseos/Packages | xargs -r rm -f createrepo_c --update /data/yum-repo/os-baseos

删完必须重建索引,否则客户端会去请求已经不存在的文件,报 404。

注意:删旧包前先确认没有机器的yum history回滚需求。回滚依赖旧版本包还在仓库里,删了就回不去了。保守做法是保留最近两到三个版本,用repomanage --keep 3 --old配合。

另外监控磁盘不能只看剩余空间,要看增长速率。我的经验是给出 70%、85%、95% 三档告警,到 85% 就该介入清理,别等到 95% 才动手——那时候正在跑的同步任务很可能已经把索引写了一半。

6. 六个真实故障的排查链路

这一节是全文我最想写的部分。下面每个故障我都实际遇到过,排查顺序按"从最可能到最不可能"排列,你可以直接照这个顺序走,能省很多时间。

6.1 客户端报 repomd.xml 404

这是出现频率最高的一条,报错长这样:Cannot download repomd.xml: ... Status code: 404。

排查顺序:先在服务端用curl请求完整 URL,确认服务端本身没问题。如果服务端也 404,往下走;如果服务端正常,那就是客户端baseurl有问题。

服务端 404 的常见原因只有三个。路径拼错,包括少了或多了一层目录。baseurl结尾斜杠的处理——目录型地址建议以/结尾,让客户端在拼接时行为确定。Alias 与 DocumentRoot 冲突,如果baseurl用的是/repo/...而实际配置里没加 Alias,那就指向了 DocumentRoot 下的同名目录,自然是空的。

还有一个隐蔽情况:repodata目录存在但里面只有.xml.gz而没有repomd.xml,说明createrepo中途被打断。删掉repodata整个目录,重新生成。

6.2 索引重建到一半磁盘满,仓库整体报废

这个故障杀伤力最大,因为现象是"昨天还好好的,今天全挂了"。

createrepo生成索引时会先在临时目录写入新文件,再替换旧的。磁盘满的时候,旧索引可能已经被移走、新索引没写完,repomd.xml引用了不存在的文件,客户端报Failed to synchronize cache或者各种repodata/*.xml拉取失败。

修复方式:清出空间,删掉repodata目录,全量重建。

df -h /data rm -rf /data/yum-repo/os-baseos/repodata createrepo_c /data/yum-repo/os-baseos

预防手段比修复重要:同步脚本开头加磁盘检查,低于阈值直接退出;日志里记录每次同步前后的df数值;监控单独给/data分区配告警。

6.3 GPG 校验失败,包明明是对的

现象:Package xxx.rpm is not signed或GPG key retrieval failed。

先分清是哪一层。如果报的是 rpm 包签名问题,那是gpgcheck=1但客户端没导入对应公钥,或者包本身没签名。导入公钥:

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-local

如果报的是元数据签名问题,那是repo_gpgcheck=1但没有repomd.xml.asc,或者签名文件与repomd.xml不匹配。

最常见的坑是:元数据重新生成之后,旧的.asc文件还留在repodata里,与新的repomd.xml对不上。每次重建索引后都要重新签名:

gpg --detach-sign --armor \ -o /data/yum-repo/os-baseos/repodata/repomd.xml.asc \ /data/yum-repo/os-baseos/repodata/repomd.xml

内部仓库我通常建议:如果包的来源完全可控、只在封闭内网流转,gpgcheck可以先用0把流程跑通,等稳定了再补签名体系。反过来做,容易卡在签名环节出不来。

6.4 403 Forbidden:权限看着都对就是不行

这条基本是 SELinux。判断方法很直接:临时把 SELinux 设为 permissive,如果立刻恢复正常,问题就确认了。

getenforce setenforce 0 # 验证是否恢复,恢复则说明是 SELinux setenforce 1

确认后按前面 3.3 节打标签。另外记得检查父目录的上下文,只给最末级目录打标签是不够的,restorecon -Rv的-R不能省。

还有一种情况是目录权限链断裂:/data/yum-repo权限是 755 但/data是 700,httpd 进不去。用namei -l /data/yum-repo/os-baseos/repodata/repomd.xml一次性看完整个路径的权限链,比逐层ls高效。

6.5 客户端能看到包但装不上,提示依赖缺失

元数据索引的是"这个仓库里有哪些包",依赖解析是基于这些索引做的。如果依赖包在另一个仓库里、而那个仓库没启用,就会报依赖缺失。

排查方法:

dnf repoquery --whatprovides "libxxx.so.1" dnf --showduplicates list 包名

第一条查哪个仓库提供了这个依赖,第二条看有哪些版本可选。找到之后确认那个仓库是否enabled=1。

另一个高频原因是多仓库同名包冲突。同一个包在本地源和外部源里都有,版本不同,dnf可能挑了一个你没有完整依赖链的版本。这种情况我一般直接禁用外部源,只留本地源,把环境收紧。

6.6 同步很慢,或者干脆卡死

reposync卡住通常是网络层问题,但也会有磁盘层的表现。

先看是卡在"列包"还是"下载"。日志停在Downloading metadata就是元数据拉取慢,停在某个包名就是单包下载慢。

如果源站响应慢,可以给dnf加超时和重试:

# /etc/dnf/dnf.conf timeout=60 retries=3 minrate=100k

minrate是个很有用的参数,低于这个速率的连接会被主动放弃重试,避免一个慢连接把整个同步拖死。

如果包数量很大但只想更新增量,用--newest-only配合rsync只搬变化的文件,比全量reposync快一个数量级。

7. 规模上去之后要补的几件事

单台机器、几十个客户端,前面那套就够了。但如果客户端到了几百台,或者仓库要跨多个网段服务,有几件事必须补上,否则运维会变成一件很累的事。

7.1 就近访问:多级镜像

单点 HTTP 服务在几百台客户端同时makecache的时候会扛不住。解决办法是分层:中心节点做大仓库,各网段放一台镜像节点,只从中心拉取,客户端指向就近的镜像节点。

镜像节点同步用rsync最省事,因为它只传变化的文件:

rsync -avz --delete --partial \ rsync://center-node/repo/ /data/yum-repo/

--partial支持断点续传,第一次同步几十 GB 的中断是常态,没有这个参数就得从头再来。--delete保持严格一致,但要注意它是按目录树删的,路径写错会误删本地目录,执行前先用--dry-run跑一遍。

同步完成后再在镜像节点上跑一次createrepo_c --update,因为rsync只搬文件不建索引(如果中心节点的索引已经生成并一起同步,可以省掉这步)。

7.2 客户端侧的参数调优

客户端调优的目标是:减少不必要的请求、加快缓存命中、避免带宽尖峰。

[main] cachedir=/var/cache/dnf keepcache=0 metadata_expire=900 max_parallel_downloads=5

keepcache=0表示装完就删包,节省磁盘。但在批量部署场景下我会临时改成1,让一批机器可以用同一份缓存——当然前提是它们共享缓存目录,实际很少这么干。

max_parallel_downloads默认比较保守,改成 5 到 10 能明显提速,但要注意服务端的并发承载能力,几百台客户端同时调高这个值,服务端可能先扛不住。

7.3 监控:哪些指标值得盯

我盯四个:

  • 仓库元数据时间戳。repomd.xml的修改时间超过同步周期两倍,说明同步任务已经挂了。
  • 分区使用率。前面说过,看速率比看绝对值重要。
  • HTTP 服务错误率。403突然增多通常是权限或 SELinux 被改动了,404增多通常是索引重建出了问题。
  • 客户端makecache失败数。这个最能反映真实可用性,比服务端自己的指标更有意义。

采集方式用最简单的就行:一个定时任务跑curl -o /dev/null -s -w "%{http_code}"请求repomd.xml,非 200 就告警。不需要上复杂系统。

7.4 版本冻结:真的需要"永远不变"吗

前面提过版本冻结的价值,但这里补一个反向的经验:冻结是有代价的。

冻结意味着上游的安全修复你也拿不到。所以我的做法是分仓库策略:基础系统仓库跟安全更新走,紧跟上游;工具链和特定业务依赖的仓库做冻结;两者在客户端.repo里分开配置,需要严格一致的环境只启用冻结仓库。

这样既能保证核心环境的稳定,又不至于让整批机器长期停在有已知问题的版本上。策略写在文档里,交接的时候才不会有争议——这条是从一次很痛苦的交接里换来的教训。

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

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

立即咨询