内网环境里批量装软件这件事,只要机器数量超过五台,靠一台台挂载光盘、一个个手动装包,效率低到让人怀疑人生。我最早接触这类需求是在一个完全隔离的机房项目里,几十台服务器没法访问外网,每次装个监控代理都要抱着U盘来回跑,后来索性花半天时间搭了个本地yum源仓库,从此所有节点统一指向内网地址,装包、更新、补依赖一条命令搞定。这篇内容就围绕Linux-CentOS如何搭建yum源仓库展开,把我从零搭建到后期维护的完整过程拆开讲清楚。
yum源仓库说白了就是一个存放RPM软件包、并带有元数据索引的目录服务,客户端通过HTTP或FTP协议访问它,yum工具读取索引后自动解决依赖关系。它能解决的核心问题是:在无外网或网络受限的环境下,让多台机器高效、统一地获取软件包。适合谁看?刚接触Linux运维的新手、需要管理内网集群的工程师、以及想搞明白yum底层逻辑的开发者,都能从下面这套流程里拿到可以直接复现的东西。
1. 搭建前的整体设计与方案选型
动手之前先把思路理清楚,比上来就敲命令重要得多。yum源仓库的搭建本质上分三块:软件包的来源、仓库服务的发布方式、客户端的接入配置。这三块怎么选,直接决定了后续维护是轻松还是痛苦。
1.1 软件包来源的三种路径与取舍
软件包从哪来,是第一个要定的事。常见的有三种路径:挂载系统安装光盘、从官方镜像站同步、以及从已有环境打包迁移。
挂载光盘是最省事的做法,CentOS的安装ISO里自带Base、AppStream等仓库的完整RPM包,挂载后直接指向光盘目录就能用。它的优势是零网络依赖、包版本与系统版本严格匹配,缺点是包不全,只有发行版自带的那些,第三方软件还得另想办法。我早期项目里就是光盘源打底,够用但不够灵活。
从官方镜像站同步适合需要完整仓库的场景,用reposync之类的工具把远端仓库全量或按需拉到本地,包最全,但占用磁盘大、同步耗时长,而且得有能访问镜像站的网络条件。全量同步一个Base仓库动辄几个GB到十几GB,磁盘规划要提前做好。
从已有环境打包迁移则是把一台已经装好各种软件的机器上的RPM包收集起来,做成自定义仓库。这种方式适合软件版本被严格管控的场景,比如某些内部定制的包,官方源里根本没有。缺点是包之间的依赖关系需要自己梳理,容易漏包。
实际项目里我通常采用组合策略:光盘源作为基础仓库保证系统级依赖,再叠加一个自定义仓库放业务相关的第三方包。这样既稳又灵活。
1.2 发布方式:HTTP还是FTP
仓库目录建好后,得让其他机器能访问到。HTTP是最主流的选择,用httpd或nginx起一个静态文件服务,把仓库目录暴露出去即可。它的好处是配置简单、客户端兼容性好、排查问题直观,浏览器打开地址就能看到目录结构。
FTP也能用,yum支持ftp协议,但配置比HTTP繁琐,防火墙和被动模式容易出问题,现在新项目里基本不选了。除非历史环境已经有一套FTP体系,否则没必要给自己找麻烦。
还有一种file://本地路径的方式,只适合单机使用,多机场景下没有意义。所以结论很明确:多机共享选HTTP,单机自用直接file://。
1.3 目录结构规划与磁盘预估
仓库目录怎么组织,直接影响后期扩展。我习惯按“系统版本/仓库类型”两级来分,比如/data/yum-repo/centos7/base、/data/yum-repo/centos7/extras,这样以后加新版本、加新仓库都不会乱。
磁盘空间要提前算。一个CentOS 7的完整Base仓库大约4到5GB,加上Extras、Updates等,全量下来十几GB很正常。如果只放光盘内容,一张DVD大概4GB出头。规划时留出至少两倍余量,因为后续可能追加自定义包和同步新版本。我见过有人把仓库放在根分区,同步到一半磁盘满了,服务直接挂掉,这种坑提前算好空间就能避开。
提示:仓库目录不要放在系统盘,单独挂一块数据盘,既方便扩容,也避免仓库写满拖垮系统。
2. 核心环境准备与基础配置
方案定了,接下来是环境层面的准备。这一步看着琐碎,但配置不到位,后面每一步都会卡壳。
2.1 系统环境确认与依赖检查
先确认系统版本,因为不同大版本的仓库配置差异不小。执行cat /etc/centos-release看发行版,uname -r看内核。CentOS 7和CentOS 8在仓库结构上就有明显区别,CentOS 8之后引入了AppStream和BaseOS的拆分,仓库路径和配置都不一样,所以第一步必须把版本对齐。
然后检查是否已安装httpd。用rpm -qa | grep httpd查一下,没有的话需要装。这里有个细节:如果目标机器本身没有可用yum源,装httpd也会卡在依赖上。解决办法是先挂载系统光盘,临时配一个本地file://源,把httpd装上,再继续后面的步骤。这个先后顺序很多人第一次搭会搞反,结果卡在第一步。
防火墙和SELinux也要提前确认状态。CentOS 7默认开firewalld,80端口不放行的话客户端访问会被拦。SELinux在 enforcing 模式下可能阻止httpd读取非标准目录,这个后面单独说。
2.2 挂载系统光盘并提取软件包
把CentOS安装ISO上传到服务器,或者直接用物理光驱。挂载命令很直接:
mkdir -p /mnt/cdrom mount -o loop /path/to/CentOS-7-x86_64-DVD.iso /mnt/cdrom挂载后ls /mnt/cdrom应该能看到Packages目录和repodata目录。Packages里是全部RPM包,repodata里是元数据索引,这两个是仓库的核心。如果只想要包不想要索引,也可以只拷Packages,但那样客户端没法直接用,得自己createrepo生成索引,所以光盘自带的repodata直接拿来用最省事。
把光盘内容整体拷到仓库目录:
mkdir -p /data/yum-repo/centos7/base cp -r /mnt/cdrom/* /data/yum-repo/centos7/base/拷贝过程视磁盘速度而定,几GB的内容几分钟到十几分钟不等。拷完确认一下Packages数量和repodata是否完整。
2.3 安装并配置HTTP服务
装httpd:
yum install -y httpd如果前面临时配了光盘源,这一步能顺利过。装完后启动并设开机自启:
systemctl start httpd systemctl enable httpdhttpd默认的网站根目录是/var/www/html。有两种做法:一是把仓库目录软链接或拷贝到根目录下,二是改httpd配置把仓库目录映射出去。我倾向后者,用别名配置更干净,仓库目录不用挪位置。
在/etc/httpd/conf.d/下新建一个配置文件,比如yum-repo.conf:
Alias /yum-repo /data/yum-repo <Directory /data/yum-repo> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory>Options Indexes让目录可以列出文件,方便浏览器直接查看;Require all granted放行访问。改完重启httpd生效。
2.4 SELinux与防火墙的放行处理
SELinux这块是新手最容易踩的坑。httpd默认只能读/var/www下的内容,仓库放在/data下会被拒绝访问,表现为客户端403或者httpd日志里报permission denied。
处理方式有两种。临时把SELinux设为permissive能验证问题,但不是长久之计。正规做法是给仓库目录打上正确的安全上下文:
semanage fcontext -a -t httpd_sys_content_t "/data/yum-repo(/.*)?" restorecon -Rv /data/yum-reposemanage命令来自policycoreutils-python包,没装的话先装上。打完标签后httpd就能正常读取了。
防火墙放行80端口:
firewall-cmd --permanent --add-service=http firewall-cmd --reload这两步做完,用浏览器访问http://服务器IP/yum-repo/,能看到目录列表就说明服务通了。
3. 仓库索引生成与客户端接入实操
服务通了只是第一步,仓库能不能被yum正确识别,关键在元数据索引和客户端配置。
3.1 createrepo生成元数据索引
光盘自带的repodata可以直接用,但如果是自己收集的RPM包目录,就必须用createrepo生成索引。先装工具:
yum install -y createrepo然后在仓库目录执行:
createrepo /data/yum-repo/centos7/base/执行完目录下会多出repodata文件夹,里面是repomd.xml等索引文件。以后每次往仓库里加了新包,都要重新执行一次createrepo,否则客户端看不到新包。这个“加包必重建索引”是硬性规则,忘了就会遇到“明明包在目录里,yum却找不到”的怪现象。
如果包数量多,createrepo耗时会长一些,可以加--workers参数并行处理。另外有个--update参数用于增量更新,只处理变化的包,比全量重建快,适合仓库很大且只加少量包的场景。
3.2 客户端repo文件配置详解
客户端要接入仓库,靠的是/etc/yum.repos.d/下的repo文件。新建一个,比如local-repo.repo:
[local-base] name=Local CentOS Base Repository baseurl=http://192.168.1.100/yum-repo/centos7/base/ enabled=1 gpgcheck=0逐项说下含义。[local-base]是仓库ID,必须唯一,客户端用它来区分不同仓库。name是描述,随便写但建议写清楚。baseurl指向仓库地址,注意结尾的斜杠,指向的是包含repodata的那一级目录。enabled=1表示启用。gpgcheck=0关闭签名校验,内网自建仓库通常这么设;如果要开校验,得配gpgkey指向公钥文件。
配好后执行yum clean all清缓存,再yum repolist看仓库是否被识别。能列出仓库ID和包数量就说明接入成功。
注意:baseurl指向的目录必须是repodata的父目录,多一层或少一层都会报“Cannot find a valid baseurl”或者“repomd.xml not found”。
3.3 完整验证流程与实测记录
配置完别急着大规模推广,先在一台客户端上做完整验证。我通常按这个顺序走:
yum clean all清掉旧缓存yum repolist all确认仓库状态是enabledyum list available看能否列出可用包- 挑一个没装的包装一下,比如
yum install -y tree,观察是否从本地仓库下载
实测时我遇到过一个情况:repolist能列出仓库,但install时报404。排查发现是baseurl路径写错了一层,指向了仓库的上级目录,repolist读到了索引但下载包时路径拼错。所以验证一定要走到真正安装这一步,光看repolist不够。
还有一次是客户端能访问但速度极慢,查下来是DNS解析问题,baseurl里用了主机名而DNS没配好,改成IP就正常了。内网环境建议baseurl直接用IP,省去解析环节。
4. 常见问题排查与长期维护经验
仓库搭起来只是开始,真正考验人的是后续的维护和排错。这一块我踩过的坑最多,整理出来供参考。
4.1 典型故障速查表
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 客户端403 Forbidden | SELinux拦截或httpd目录权限不足 | 检查安全上下文,restorecon修复;确认目录权限 |
| repomd.xml not found | baseurl路径层级错误 | 确认baseurl指向repodata父目录 |
| 包在目录里但yum找不到 | 未重建索引 | 执行createrepo重建repodata |
| 连接超时 | 防火墙未放行或服务未启动 | 检查firewall-cmd和httpd状态 |
| 下载速度极慢 | DNS解析或网络链路问题 | baseurl改用IP,检查网络 |
| GPG校验失败 | gpgcheck开启但无正确公钥 | 关闭gpgcheck或配置正确gpgkey |
这张表基本覆盖了八成以上的常见故障,遇到问题先对号入座,能省不少时间。
4.2 仓库扩容与多版本共存策略
业务增长后,仓库往往要扩容。加新仓库时,我建议在原有目录结构下平行新增,比如再加一个/data/yum-repo/centos7/custom放自定义包,客户端repo文件里追加一段配置即可,互不影响。
多版本共存也是常见需求,比如同时维护CentOS 7和CentOS 8的仓库。按版本分目录,各自独立createrepo,客户端按自己系统版本选对应baseurl。这样一套HTTP服务能同时服务多个版本的机器,管理上清晰。
磁盘扩容方面,如果仓库目录在独立数据盘上,直接扩分区或加新盘挂载即可,httpd配置不用动。这也是前面强调仓库别放系统盘的原因之一。
4.3 定时同步与自动化维护脚本
如果需要定期从上游同步新包,可以写个简单的同步脚本配合定时任务。核心逻辑是:同步包、重建索引、清理旧缓存。用reposync拉取远端仓库,再createrepo重建,最后通知客户端yum clean all。
脚本里要注意加日志和错误判断,同步失败时别把旧索引覆盖掉,否则客户端会突然不可用。我习惯先同步到临时目录,校验完整后再替换正式目录,这样即使中途失败也不影响线上服务。
定时任务用cron,比如每天凌晨执行一次。频率别太高,仓库同步本身有开销,一天一次对多数场景足够。
4.4 实操心得与避坑清单
最后分享几条实打实的经验。第一,仓库目录权限和SELinux上下文是两大隐形杀手,配置完先用浏览器和curl各验证一遍,别只信命令行。第二,createrepo重建索引这个动作要养成肌肉记忆,每次加包必做,我见过太多人栽在这上面。第三,baseurl结尾斜杠和路径层级要反复确认,这是最高频的低级错误。第四,内网环境baseurl优先用IP,减少DNS依赖。第五,仓库盘单独规划,留足余量,别等写满了才想起来扩容。
这套流程我在多个内网项目里反复用过,从单机自用到几十台节点的集群都跑得稳。真正花时间的不是搭建本身,而是把这些细节提前想到、把维护习惯养好。仓库这东西,搭一次用很久,前期多花半小时把结构和配置理清楚,后面能省下大量排错时间。