内网 Rocky 9.2 批量装软件:基于 HTTP 的 YUM 源搭建实战

发布时间:2026/10/8 1:41:16
内网 Rocky 9.2 批量装软件:基于 HTTP 的 YUM 源搭建实战
简介这份文档面向在内网隔离环境中运维多台 Linux 服务器的工程师针对无法访问互联网、逐台配置本地源或手动安装 rpm 包效率低下的痛点给出基于 HTTP 搭建局域网 YUM 源的完整方案。内容以 Rocky Linux 9.2 为例涵盖 YUM 服务器与客户机的角色划分、镜像挂载、仓库配置文件编写、httpd 服务部署以及客户机缓存刷新与验证等关键环节并附有可直接参考的配置片段与命令示例。资源包共 1 个 docx 文件约 120KB以图文步骤形式组织便于按章节对照实操。已有 1693 人学习下载适合需要统一软件版本、提升批量部署效率的运维人员参考也可为其他基于 RPM 的发行版迁移配置提供思路。1. 内网几十台 Rocky 9.2 装软件为什么我最后选了 HTTP 做 YUM 源项目现场有几十台 Rocky Linux 9.2 服务器全部跑在跟 Internet 物理隔离的内网里。每次装个软件要么把 rpm 包一个个 scp 上去手动rpm -ivh依赖报错能报一屏要么每台机器单独挂 ISO 配本地源几十台重复劳动版本还容易对不齐。这两种方式我都踩过前者费时费力后者维护成本高得离谱。后来我把思路换了一下与其每台机器各自为战不如在内网里找一台机器当软件仓库把 Rocky 9.2 的 DVD ISO 挂上去用 HTTP 服务暴露出来其他机器通过baseurlhttp://内网IP/...直接拉包。这就是基于 HTTP 的局域网 YUM 源。它解决的核心问题就一个——内网环境下让所有 Rocky 机器共享同一份软件源装包、升级、版本一致性一次搞定。适合谁手上有一批内网 Linux 服务器、需要统一软件管理的运维和交付工程师。下面我把整套流程拆开讲包括我实际踩过的坑。2. 服务端搭建挂载 ISO、装 httpd、配本地源这一章是整件事的地基。服务端这台机器下面统一叫 linux1IP 192.168.15.100要同时扮演两个角色一是通过 HTTP 把 ISO 里的软件包目录暴露出去二是自己也得能装 httpd 这个软件所以它需要先有一个能用的本地 YUM 源。顺序不能乱——先挂 ISO、配本地源、装 httpd再谈对外服务。2.1 挂载 ISO 到 Web 根目录Rocky 9.2 的 DVD ISO 里软件包分在两个目录BaseOS和AppStream。这两个目录就是后面 YUM 源要指向的 baseurl。挂载点我直接选在/var/www/html/opt因为 httpd 默认的 Web 根目录就是/var/www/html挂到这里HTTP 访问路径天然就是/opt/...省得再改 httpd 配置。# 创建挂载点目录-p 保证父目录不存在时一并创建 mkdir -p /var/www/html/opt # 把 ISO 挂载到 Web 根目录下的 opt # 注意ISO 文件本身要先放到服务器上比如 /opt 目录 mount -o loop /opt/Rocky-9.2-x86_64-dvd.iso /var/www/html/opt # 验证挂载结果应该能看到 BaseOS 和 AppStream 两个目录 ls /var/www/html/opt这里有个参数值得说-o loop是让内核把普通文件当成块设备来挂载ISO 就是这种用法。挂载完ls一下如果只看到BaseOS、AppStream、EFI这些目录说明挂对了。如果报mount: wrong fs type八成是 ISO 路径写错或者文件没传完。提示mount是临时的机器重启后挂载就没了。生产环境建议写进/etc/fstab用loop选项或者干脆写个开机脚本重新挂。我一般会在 fstab 里加一行避免重启后源突然失效这种玄学问题。2.2 配置服务端自己的本地 YUM 源linux1 要装 httpd但它现在还没有任何可用的源。所以先给它配一个指向本地挂载目录的 repo 文件。Rocky 9 的 repo 目录是/etc/yum.repos.d/注意别写成/etc/yum.repo.d/少个 s 直接不生效这个拼写坑我见过不止一次。# 文件路径/etc/yum.repos.d/local.repo [Rocky-BaseOS] nameRocky-BaseOS baseurlfile:///var/www/html/opt/BaseOS/ enabled1 gpgcheck0 [Rocky-AppStream] nameRocky-AppStream baseurlfile:///var/www/html/opt/AppStream/ enabled1 gpgcheck0逐项说明baseurl用file://协议指向本地挂载点这是服务端自己用的enabled1表示启用gpgcheck0是关闭 GPG 签名校验——内网自建源图省事通常这么干但如果你们有安全合规要求应该导入 Rocky 的 GPG key 并设成gpgcheck1。两个仓库缺一不可BaseOS 放基础系统包AppStream 放应用流包只配一个的话装 httpd 时依赖可能找不全。配好之后把系统自带的那些 repo 文件清掉避免它们干扰内网访问不到外网源留着只会拖慢 yum 操作# 进入 repo 目录 cd /etc/yum.repos.d/ # 删除除 local.repo 以外的所有 repo 文件 # 注意这条命令依赖 extglob先确认 shell 支持 shopt -s extglob rm -rf !(local.repo) # 刷新缓存验证本地源可用 yum clean all yum makecacherm -rf !(local.repo)这个写法用的是 bash 的扩展通配意思是删掉除了 local.repo 之外的所有东西。执行前务必ls确认一下当前目录手一抖删错目录就是血泪教训。稳妥点的做法是先mkdir /tmp/repo_bak mv *.repo /tmp/repo_bak/再单独把 local.repo 放回来。2.3 安装并启动 httpd本地源通了装 httpd 就是一条命令的事。httpd 是 Apache 的 RPM 包名在 Rocky 9 里由 AppStream 仓库提供。# 安装 httpd yum install -y httpd # 启动 httpd 并设为开机自启 systemctl start httpd systemctl enable httpd # 放行防火墙如果 firewalld 在跑 # 临时关闭方式测试环境常用生产建议按端口放行 systemctl stop firewalld # 关闭 SELinux 强制模式临时 setenforce 0 # 验证 httpd 是否在监听 80 端口 ss -tlnp | grep :80关于防火墙和 SELinux这里我要多说一句。原文里直接systemctl stop firewalld和setenforce 0测试环境图快可以但生产环境这么干等于把安全策略全卸了。更合理的做法是防火墙只放行 80 端口firewall-cmd --add-servicehttp --permanent firewall-cmd --reloadSELinux 如果不想关需要给 Web 目录打上正确的上下文标签chcon -R -t httpd_sys_content_t /var/www/html/opt否则 httpd 读不到挂载目录里的文件浏览器访问会报 403。这个 403 是新手最容易卡住的地方——服务明明起来了就是访问不了十有八九是 SELinux 在拦。配完之后在服务端本机先自测一下# 本机访问应该返回目录列表或欢迎页 curl -I http://127.0.0.1/opt/BaseOS/ # 如果返回 200说明 HTTP 服务正常 # 如果返回 403检查 SELinux 上下文和目录权限看到HTTP/1.1 200就说明服务端这半边成了。接下来才是客户机的事。3. 客户机接入repo 文件怎么写、缓存怎么刷服务端跑通只是完成一半客户机能不能正确拉到包取决于 repo 文件写得对不对、网络通不通、缓存刷没刷干净。这一章把客户机linux2192.168.15.101的配置和验证讲透。3.1 客户机 repo 文件的关键差异客户机的 repo 文件结构跟服务端几乎一样唯一的区别是baseurl从file://换成了http://服务端IP。这个 IP 必须写服务端真实的内网 IP别写127.0.0.1也别写主机名除非你配了 DNS 或 hosts。# 文件路径/etc/yum.repos.d/local.repo [Rocky-BaseOS] nameRocky-BaseOS baseurlhttp://192.168.15.100/opt/BaseOS/ enabled1 gpgcheck0 [Rocky-AppStream] nameRocky-AppStream baseurlhttp://192.168.15.100/opt/AppStream/ enabled1 gpgcheck0注意原文里客户机部分写的是192.168.1.100而环境准备里服务端是192.168.15.100这两个 IP 段不一致。这大概率是原文笔误实际配置时以你真实的服务端 IP 为准。IP 写错是客户机报Could not resolve host或Connection refused的头号原因配完先ping 192.168.15.100确认网络可达。同样客户机上也要清掉系统自带的 repo 文件只留这一个cd /etc/yum.repos.d/ shopt -s extglob rm -rf !(local.repo)3.2 刷新缓存并验证源可用repo 文件放好后必须清缓存再重建否则 yum 可能还在用旧的元数据。这一步是让配置真正生效的关键动作。# 清除所有缓存包括元数据和包 yum clean all # 重新生成缓存这一步会去 HTTP 源拉 repodata yum makecache # 列出所有可用的包验证源工作正常 yum list # 更精准的验证查一个具体包 yum list available httpdyum makecache如果成功会显示类似Metadata cache created的字样。如果卡住或报错按这个顺序排查先curl http://192.168.15.100/opt/BaseOS/repodata/看能不能列出文件能列出说明 HTTP 层通了再看服务端 httpd 是否在跑、防火墙是否放行最后检查客户机 repo 文件里的 URL 拼写。yum list能刷出一大串包名基本就成功了。想更直观直接装个包试试# 实际安装一个包验证完整链路 yum install -y tree # 装完确认 tree --version能装上说明从客户机到服务端的整条链路——网络、HTTP、repo 元数据、包下载——全部打通。3.3 多台客户机的批量落地思路几十台机器一台台手配 repo 文件显然不现实。常见做法是写一个配置脚本把 repo 文件内容和服务端 IP 作为变量通过批量工具比如 Ansible、pssh或者你们现场用的任何批量执行手段推下去。核心逻辑就三步写 repo 文件、清缓存、makecache。#!/bin/bash # 批量配置客户机 YUM 源的脚本骨架 # 用法把 SERVER_IP 改成你的服务端 IP然后批量执行 SERVER_IP192.168.15.100 REPO_FILE/etc/yum.repos.d/local.repo # 备份并清理旧 repo mkdir -p /tmp/repo_bak mv /etc/yum.repos.d/*.repo /tmp/repo_bak/ 2/dev/null # 写入新的 repo 配置 cat ${REPO_FILE} EOF [Rocky-BaseOS] nameRocky-BaseOS baseurlhttp://${SERVER_IP}/opt/BaseOS/ enabled1 gpgcheck0 [Rocky-AppStream] nameRocky-AppStream baseurlhttp://${SERVER_IP}/opt/AppStream/ enabled1 gpgcheck0 EOF # 刷新缓存 yum clean all yum makecache这个脚本用 heredoc 把变量SERVER_IP嵌进 repo 文件改 IP 只改一处。批量执行时只要目标机器能访问服务端 80 端口脚本跑完就能用。注意mv那步做了备份万一新源有问题把/tmp/repo_bak/里的文件挪回去就能回滚算是留了颗后悔药。4. 避坑与排查那些让 YUM 源看起来配好了却用不了的问题这套方案步骤不多但坑都藏在细节里。下面这几条是我在实际项目里真金白银踩出来的每条按现象 → 原因 → 解决说清楚。4.1 客户机报 403 Forbidden现象yum makecache报错curl http://服务端IP/opt/BaseOS/返回 403。原因SELinux 拦住了 httpd 对/var/www/html/opt的读取。挂载进来的目录默认上下文不是httpd_sys_content_thttpd 没权限读。解决临时setenforce 0验证是不是 SELinux 问题确认后用chcon -R -t httpd_sys_content_t /var/www/html/opt给目录打标签或者用semanage fcontext做持久化规则。别一上来就永久关 SELinux那是把问题盖住而不是解决。4.2 重启后 YUM 源突然失效现象服务端重启一次所有客户机yum全报错curl服务端返回 404。原因ISO 是mount挂上去的重启后挂载丢失/var/www/html/opt变成空目录HTTP 自然找不到文件。解决把挂载写进/etc/fstab加loop选项例如/opt/Rocky-9.2-x86_64-dvd.iso /var/www/html/opt iso9660 loop,ro 0 0。或者写个 systemd 服务/开机脚本重新挂载。这个坑最阴因为配的时候一切正常重启后才爆。4.3 repo 文件目录拼错导致配置不生效现象repo 文件明明写了yum repolist里却看不到自定义的仓库。原因目录写成了/etc/yum.repo.d/少个 s或者文件扩展名不是.repo。yum 只认/etc/yum.repos.d/下的.repo文件。解决ls /etc/yum.repos.d/确认路径和文件名yum repolist all看仓库有没有被识别。拼写这种事检查一遍比 debug 半小时快。4.4 客户机和服务端 IP 段不一致现象客户机yum makecache卡很久然后超时ping服务端不通。原因repo 文件里的 IP 写错或者客户机和服务端不在同一网段、路由不通。原文里服务端是192.168.15.100客户机配置却写了192.168.1.100这种笔误在实际操作中很常见。解决先ping服务端 IP 确认三层可达再curl确认 80 端口通最后核对 repo 文件里的 URL。三层排查法从下往上定位。4.5 gpgcheck 开启后报签名错误现象把gpgcheck改成 1 后yum install报Public key for xxx.rpm is not installed。原因开启了签名校验但没导入 Rocky 的 GPG 公钥。解决从 ISO 里找到 GPG key通常在 ISO 根目录的RPM-GPG-KEY-Rocky-9用rpm --import导入或者在 repo 文件里用gpgkeyfile:///...指定路径。内网测试环境用gpgcheck0没问题但生产环境建议老老实实导入 key。5. 进阶把 YUM 源做成可持续维护的内网软件仓库基础版跑通之后这套东西还能再往前走一步。ISO 里的包是固定的但项目上经常需要装一些 ISO 里没有的第三方 rpm或者要同步更新。这时候可以在 HTTP 根目录下再建一个自定义仓库目录把额外收集的 rpm 放进去用createrepo生成元数据然后在客户机 repo 文件里追加一个指向它的仓库段。# 在服务端创建自定义仓库目录 mkdir -p /var/www/html/custom/Packages # 把额外的 rpm 包拷进去 cp /path/to/your/*.rpm /var/www/html/custom/Packages/ # 安装 createrepo_c 工具Rocky 9 里包名带 _c yum install -y createrepo_c # 生成仓库元数据 createrepo_c /var/www/html/custom/ # 客户机追加 repo 段 cat /etc/yum.repos.d/local.repo EOF [Custom] nameCustom baseurlhttp://192.168.15.100/custom/ enabled1 gpgcheck0 EOF # 客户机刷新缓存 yum clean all yum makecachecreaterepo_c会在目录下生成repodata/子目录里面是 yum 需要的元数据。每次往Packages里加了新 rpm都要重新跑一次createrepo_c --update /var/www/html/custom/否则新包不会被识别。这个--update参数只更新变化部分比全量重建快。验证方法很简单客户机yum repolist应该能看到Custom仓库yum list available | grep 你的包名能查到就说明自定义仓库生效了。如果查不到先确认createrepo_c跑没跑、repodata目录在不在、HTTP 能不能访问到。再进阶一点如果内网机器多、对可用性要求高可以考虑用 rsync 定期从上游镜像站同步前提是有一台能出网的跳板机或者把 ISO 内容直接解压到磁盘而不是挂载避免挂载丢失的问题。解压方式占磁盘空间但胜在稳定重启不受影响# 解压 ISO 到 Web 目录替代挂载方案 mkdir -p /var/www/html/opt mount -o loop /opt/Rocky-9.2-x86_64-dvd.iso /mnt cp -a /mnt/. /var/www/html/opt/ umount /mnt这样/var/www/html/opt就是真实目录重启后依然在。代价是多占几个 G 磁盘但对内网服务器来说这点空间通常不是问题。从那以后我每次搭内网源都会先把挂载方式确认清楚——要么写 fstab要么直接解压绝不留一个重启就失效的临时挂载在生产环境里。这个习惯帮我省了好几次半夜被叫起来排查的麻烦。希望帮到你。本文还有配套的精品资源点击获取