给内网服务器装软件,最头疼的莫过于敲下 yum install 之后,屏幕上刷出一片 Could not resolve host。没有外网访问权限的机器,包管理器直接废掉一大半。这个场景我遇到过太多次:业务系统在内网隔离区,装个基础的编辑器、图形自动化工具,都得靠运维手动找 rpm 包,一层层解决依赖,运气不好能折腾一下午。后来我把离线 yum 源这套流程彻底跑通以后,同类环境基本半小时之内就能铺完。这篇文章就把我实际用下来的方案、步骤和踩过的坑一次说清楚,适合正在给内网机器、国产化环境或临时测试环境搭建本地软件源的人参考。
1. 内网机器的痛:为什么离线环境离不开一个本地yum源
1.1 离线yum源解决的核心问题
Linux 的 yum/dnf 包管理器默认配置全是官方仓库地址,这些地址在能上网的机器上才访问得了。内网环境一旦断外网,yum 会尝试连接 mirror 列表并超时,最后给出一个 Could not retrieve mirrorlist 或 Cannot find a valid baseurl 的报错,整个软件安装流程瞬间停摆。
有人会想,那我直接用 rpm 包安装不就行了?单包安装确实可以,但 rpm 依赖关系是一个网,不是一条线。装一个 xdotool,可能牵扯到 libX11、libXtst、libXext 等一堆基础库,这些库又可能被系统里其他软件共享。手动找包时,版本稍微对不上就装不进去,强制忽略依赖又可能把系统装坏。离线 yum 源的价值就在这儿:把某个可靠的软件集合以标准仓库的形式提供给本机或内网的其他机器,让 yum 自己去解析依赖,它比人脑可靠得多。
再往深一层说,yum 源解决了“软件来源可信”的问题。内网环境往往对安全有要求,如果每个人都从 U 盘、网盘拷贝来源不明的 rpm 包进来,系统被植入恶意软件的概率会直线上升。把离线源统一搭建、统一维护,等于对内网服务器提供了受控的软件分发入口。
1.2 什么时候值得建离线源,什么时候别浪费时间
先说结论:不是每个环境都需要完整离线源。如果你只是给一台机器装一个一次性工具,更快的做法是找一台同版本系统的联网机器,用 yumdownloader 把目标包和依赖下载好拷过去,直接 rpm 安装。但如果你碰上下面这些情况,离线 yum 源就是正确选项:
- 服务器数量多,比如几十台以上,每台都手动传 rpm 会累死人;
- 业务需要长期运行,后续还要增补软件,需要一个稳定统一的安装入口;
- 环境对安全合规有要求,不允许在搭建过程中随意拷贝来源不明的 rpm;
- 网络隔离是长期状态,之后还会有新机器陆续入场。
我个人的判断标准其实很简单:如果同一批软件需要在超过三台机器上安装,或者这台机器以后还会反复装东西,那就把离线源搭起来。搭一次源做的事,比后续反复手动处理依赖要省得多。之前帮一个医疗信息系统的项目搭内网环境,20 多台服务器全是离线状态,起初他们打算每台机器单独处理依赖,结果一周还没装完基础设施。后来我花半天搭了个局域网 HTTP 源,剩下所有机器都是半小时内完成的。这就是典型的高投入产出场景。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动手前的选型:ISO挂载源和同步包仓库源,该怎么选
2.1 基于ISO镜像的轻量离线源
所谓 ISO 挂载源,就是把系统安装光盘镜像挂载到某个目录,然后把该目录作为 yum 的仓库根目录。这是最快速、最原始的离线源形式。DVD 或 Everything 镜像里面包含了系统安装所需的大部分软件包,根目录下一般有 repodata 目录,里面存着仓库元数据,yum 可以直接识别。
这个方案的好处是搭建成本极低:一个镜像文件加一条 mount 命令就能跑起来。受限也很明显:镜像内置的软件包版本在发版时就固定了,新软件或更新版不会出现;部分外置仓库(EPEL、extras)里的软件也不在里面。所以它适合做基础系统源,不适合当“全能软件仓库”。
选镜像的时候有讲究。以 CentOS 7 为例,DVD 镜像只有 4GB 左右,软件包相对有限;Everything 镜像有 8-10GB,覆盖的包更全。如果离线源要服务的机器比较多、涉及中间件或数据库安装,我会优先选择 Everything 或对应的完整版本镜像。省下的时间远比那几 GB 磁盘空间值钱。
2.2 基于同步工具搭建的完整离线源
如果业务需要更完整、更接近公网仓库的内容,就得先用一台能联网的机器,用 reposync、yumdownloader 或 dnf reposync 把远程仓库的 rpm 包同步到本地,再用 createrepo 重新生成元数据,最后把整个目录同步到内网。这种源能做到和公网仓库一致地持续更新,但同步耗时、占用磁盘空间大,维护动作也多。
这里解释一下为什么同步完必须重新生成元数据:公网仓库的 repodata 里记录的包路径、校验和都是针对公网文件布局生成的,你同步到本地后文件路径变了,如果直接拿原元数据给 yum 用,yum 会按错误的相对路径去找包。createrepo 的作用就是扫描当前目录下所有 rpm 包,重新生成一套完整的 repomd.xml 和元数据文件,让仓库和文件路径严格对应。软件千万可以只拷一部分,元数据必须重新生成。
实际项目里我会把两种源组合使用:ISO 镜像源作为基础底座,保证系统组件装得上;再用一台“摆渡机”(有网机器)定期同步一些业务需要的扩展仓库,打包成增量源放进内网。这让离线环境的软件覆盖面与版本可控性都好了许多。
2.3 两种方案的适用场景对比
| 维度 | ISO 挂载源 | 同步包仓库源 |
|---|---|---|
| 搭建速度 | 几分钟内完成 | 视网络和仓库大小,可能数小时 |
| 软件包数量 | 依赖镜像类型,通常几百到几千 | 可完整复制全量仓库 |
| 版本时效 | 固定在镜像发布时 | 可随同步周期更新 |
| 空间占用 | 单个ISO约4-10GB | 一般几十GB起 |
| 维护复杂 | 基本不需要维护 | 需要定期同步和重新生成元数据 |
| 适用场景 | 系统安装、基础组件、快速应急 | 业务软件多样、需要全量软件的长期环境 |
选型时先问自己一个问题:这个离线源是要“满足一次部署”,还是要“长期支撑业务”。前者直接挂 ISO,后者就踏实做同步源。最怕的是明明只需要基础软件,却非要去同步几十 GB 的全量仓库,把时间和带宽都浪费在永远不会用到的东西上。
3. 基于ISO镜像搭建离线yum源:CentOS/Rocky完整实操
3.1 挂载ISO并确认镜像内容
先把 ISO 镜像放到服务器上,我一般习惯放在 /data 这种单独的数据分区,避免系统盘空间紧张。然后创建挂载目录并挂载:
bash复制mkdir -p /mnt/iso
mount -o loop /data/CentOS-7-x86_64-DVD-2009.iso /mnt/iso
挂载成功后不要急着写配置,先确认镜像内容结构:
bash复制ls /mnt/iso
ls /mnt/iso/repodata
看到 repodata 目录并确认里面有 repomd.xml 文件,说明这确实是一个可以被 yum 识别的仓库根目录。有些精简版镜像或 mini 镜像不包含完整软件包,根目录下根本没有 repodata,那种镜像只能用来装系统,不能当软件源用。这个检查步骤几秒钟,但能帮你提前排除掉大量配置完才发现源不可用的无效劳动。
3.2 编写repo文件并刷新缓存
默认系统里 /etc/yum.repos.d/ 下有一堆官方源配置文件,离线环境下这些文件只会让 yum 反复尝试联网然后超时。标准做法是先备份它们,再新建本地源配置:
bash复制mkdir -p /etc/yum.repos.d/backup
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/
我习惯用“备份”而不是“删除”,因为以后机器如果恢复外网权限,或者需要对照系统默认配置时,这些文件还能找回来。然后把新建的 /etc/yum.repos.d/local.repo 写进去:
ini复制[local-base]
name=Local ISO Repository
baseurl=file:///mnt/iso
enabled=1
gpgcheck=0
这里 gpgcheck=0 是我在离线环境下的默认选择。ISO 本身已经过官方介质校验,放到内网后基本可信。如果你所在的公司安全基线要求必须校验 GPG,那也可以保留 gpgcheck=1,并导入镜像里的官方公钥:
bash复制rpm --import /mnt/iso/RPM-GPG-KEY-*
配置写完后刷新:
bash复制yum clean all
yum makecache
yum repolist
正常情况下 repolist 输出的条数和仓库包数量列表就会正常显示。如果这里报错,先回去检查路径和挂载状态,这是整个流程里最常出错的一步。
3.3 用yum install xdotool验证离线源可用
写配置只是第一步,真正决定源能不能用的,是实际安装一个软件。我习惯用 xdotool 来验证,因为它是 X11 桌面自动化工具,依赖面小、体积适中,而且很多内网环境里的自动化测试、远程桌面控制场景真的需要它:
bash复制yum install -y xdotool
如果 yum 能顺利解析出依赖并完成安装,说明本地源已经被正确识别,元数据和软件包都可用。安装过程中观察一下依赖解析的日志:如果它从 file:///mnt/iso 拉取软件包,那说明 baseurl 指对了;如果源列表里还有其他仓库参与,说明之前的 backup 步骤没做干净。另外,xdotool 这类小工具装完后可以立即 xdotool --version 验证可执行文件是否完整,避免“yum 显示成功但命令用不了”的假成功。
3.4 重启后源失灵的解决方案(fstab自动挂载)
ISO 挂载在重启后会失效,如果服务器重启后别人再执行 yum install,就会发现 repolist 变空,源被“莫名奇妙”弄丢。解决方式是写入 /etc/fstab 让它开机自动挂载:
code复制/data/CentOS-7-x86_64-DVD-2009.iso /mnt/iso iso9660 loop,defaults 0 0
加上这一行后,最好用 mount -a 验证一下语法没有写错。需要特别提醒:如果挂载项指向的 ISO 文件不存在或路径变更,开机流程可能会在挂载这一步卡住,所以我会建议把 ISO 文件放到一个固定、稳定、不会被人随手清理的目录。用 systemd-mount 服务管理会更稳,但对大多数场景来说 fstab 已经够用了。
4. 把单机源升级成局域网源:HTTP共享与客户端配置
4.1 用Nginx或HTTPD把离线源共享出去
单机源解决了“这一台机器”的问题,但内网经常有几十台机器要装同样的东西,这时把挂载目录通过 HTTP 共享出去,让所有机器统一从这台“源服务器”拉包,是最省事的做法。共享方式有不少,HTTP、FTP、NFS 都行,我通常直接用 HTTP 加 httpd,因为精简安装里它占空间小、配置简单,而且 yum 对 HTTP 仓库的支持最成熟,不需要额外客户端。
bash复制yum install -y httpd
systemctl enable --now httpd
Apache 的默认站点根目录是 /var/www/html,接下来要把 ISO 挂载目录暴露给它。我最推荐的方式是 bind mount,而不是软链接。软链接有时候会因为 SELinux 或目录权限导致访问异常,bind mount 直接把 /mnt/iso 绑定到 Web 目录的子路径下,行为更可预期:
bash复制mkdir -p /var/www/html/iso
mount --bind /mnt/iso /var/www/html/iso
如果系统开了 SELinux 且处于 enforcing 模式,还需要给源目录打上 httpd 可读的上下文标签:
bash复制semanage fcontext -a -t httpd_sys_content_t '/mnt/iso(/.*)?'
restorecon -Rv /mnt/iso
最后放行防火墙:
bash复制firewall-cmd --permanent --add-service=http
firewall-cmd --reload
在源服务器本机先验证一下:
bash复制curl -I http://127.0.0.1/iso/repodata/repomd.xml
能返回 200 就说明共享层已经通了。
4.2 内网其他主机的repo配置
客户端机器的配置和单机源几乎一样,区别只是 baseurl 从 file:// 变成 http://。同样先备份原有源文件:
bash复制mkdir -p /etc/yum.repos.d/backup
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/
新建 /etc/yum.repos.d/lan.repo:
ini复制[lan-base]
name=LAN HTTP Repo
baseurl=http://192.168.1.10/iso
enabled=1
gpgcheck=0
然后:
bash复制yum clean all
yum makecache
yum repolist
确认 repolist 正常后,随便装一个包试试网络链路。如果局域网内有多个网段,记得检查源服务器的监听地址和防火墙规则,只监听 127.0.0.1 的话内网其他机器肯定访问不到。这里多说一句,客户端机器的系统版本和源服务器越一致越好,混用大版本容易出现依赖不兼容,装到一半报错会非常难受。
4.3 baseurl配置里最容易踩的路径坑
HTTP 方式比 file 方式更容易出错,核心原因在于很多人搞不清 URL 路径和磁盘路径的对应关系。比如 Apache 配置中 /var/www/html/iso 对应 URL 是 http://IP/iso,那么仓库的 repodata 文件必须在 /var/www/html/iso/repodata/repomd.xml。如果客户端配置 baseurl=http://192.168.1.10/mnt/iso,那实际上等于去访问 /var/www/html/mnt/iso,自然找不到。
排查路径问题最快的方法是先在客户端用 curl 探测:
bash复制curl -I http://192.168.1.10/iso/repodata/repomd.xml
如果 URL 返回 404,去源服务器确认目录结构;如果返回 403,多半是 SELinux 或权限问题。这类问题往往不是配置文件写错,而是“路径映射”没对齐,养成先 curl 再 yum 的习惯能省很多时间。
5. 国产化与多发行版适配:麒麟v10、openEuler、Rocky为什么不能照抄CentOS教程
5.1 麒麟v10搭建本地yum源时的差异
国产化环境这几年越来越多,银河麒麟 V10 是其中常见的系统。麒麟 V10 的不同版本对应不同上游:有的基于 CentOS 7 生态,有的基于 openEuler 或 CentOS 8 生态,这就导致你网上搜到的教程可能在自己版本上不通用。核心思路不变,但有几个差异点要留意。
第一,默认仓库文件名称不是 CentOS 那种 CentOS-*.repo,可能是 Kylin-*.repo 或 kylin_x86_64.repo,备份时不要只针对某个文件名写死命令,用通配符更稳妥。第二,部分麒麟 ISO 的仓库布局不完全一样,有的根目录直接有 repodata,有的需要进入子目录才能找到。所以挂载后先 find /mnt/iso -name repomd.xml 确认实际位置
