
做服务器运维的人几乎都绕不过这么一件事在一台不能联网、或者网络条件很差的机器上装软件。软件包本身倒是好说麻烦的是依赖关系——一拉一串没个源根本没法下手。最常见的解法就是把系统ISO镜像挂载成本地yum源软装硬装都能兜底。CentOS 10 时代虽然dnf早就替代了yum但配置文件路径、仓库写法和过去一脉相承配置一套本地源的底层思路也没变过。这篇记录的是我最近在一台 CentOS 10 测试机上配置yum源挂载的完整过程从准备ISO到验证软件安装都有适合刚接触服务器运维、或者要在离线环境部署服务的读者参考。先说结论整个流程就四步——准备ISO、挂载目录、写repo文件、验证安装。中间会踩的坑基本集中在路径、签名、缓存三件事上后面我会逐个展开说。1. 先搞清楚为什么需要挂载ISO做本地yum源1.1 离线环境下的软件安装困境生产环境里“断网装包”是常态尤其是一些保密要求高的机房、内网办公网或者带了独立安全域的部署环境。这些地方根本访问不了外网的软件仓库而业务系统又必须装运行时、装编译工具链、装监控插件。你要是傻乎乎用dnf install几分钟后就会看到满屏的“Could not resolve host”或者长时间卡在重试上。在线源最大的问题不是“不能访问”而是“不可控”。即便能连外网源服务器本身的稳定性、速度、某个时间段内是否限流都不可控。我之前在一台跨境部署的机器上装某个基础库连着拉了一下午速度就没上过50KB/s最后超时失败浪费时间不说还把环境搞乱了。离线源一旦配置好所有包都从本地磁盘或者内网其他机器来速度是毫秒级的失败概率几乎为零。1.2 挂载ISO与在线源、目录源怎么选配置“软件包来源”其实有几种常见做法直接用在线仓库、把ISO挂载成目录做本地仓库、把rpm包手动放进某个目录后用createrepo生成元数据、或者用HTTP服务把本地目录共享给局域网内的多台机器。这几种方案各有利弊我整理了一张表方案优点缺点在线官方源软件新、依赖全、无需本地准备依赖外网速度不稳定版本不可控ISO挂载本地源离线可用、版本固定、速度快只有随镜像发布的快照版本需维护挂载手动rpm目录源灵活搭配任意软件依赖包得自己全部收集费时费事内网HTTP共享源多台机器共用、维护成本低需要一台机器常驻服务对于“单台机器或者一个小型机柜”的场景ISO挂载是最省心的。系统安装镜像本身就是一个被官方打包好的完整仓库目录结构、repodata元数据都是现成的不需要再额外处理软件包。更重要的是ISO镜像里的软件包版本是经过整体测试的互相之间的依赖几乎是“铁锁连环”不会出现从多个源拼装出来导致版本冲突的情况。1.3 CentOS 10 的 yum 与 dnf 到底是什么关系标题沿用“yum源”是因为大家在习惯上还这么叫。实际上从 CentOS 8 开始包管理器就换成了dnfCentOS 10 里执行yum命令基本上是dnf的兼容入口配置目录和机制一样。你输入yum install xxx或dnf install xxx走的都是同一个软件仓库。仓库文件统一放在/etc/yum.repos.d/目录下以.repo结尾。在CentOS 10中RHEL系列的仓库划分延续了新的结构BaseOS系统核心包、AppStream应用和模块化包、CRB构建扩展包早期叫PowerTools。有人说那我不写repo文件直接把ISO里的rpm包拷出来手动装行不行行但手动装包时依赖会让人崩溃。配置成yum源后就等于让系统帮你自动解析并拉取所有依赖这才是正路。2. 环境准备与ISO镜像挂载操作详解2.1 下载镜像并做完整性校验先把ISO弄到手。CentOS 10对应的安装镜像大小通常在10GB左右如果你面向的机器架构不是最常见的x86_64下载前先确认一下架构免得后面对不上。下载完成后千万别跳过校验这步。我见过有人ISO下到一半丢包挂载时也不报错但repo列表里始终缺某个包排查了老半天才发现是镜像坏了。官方网站一般会给出SHA256校验值下载后顺手比对一下sha256sum CentOS-10.iso如果计算出的值与官方给出的一致说明文件完整可以放心使用。这一步可以帮你省掉后续一堆莫名其妙的坑。2.2 创建挂载目录与loop回环设备说明ISO其实是一个光盘镜像文件它里面模拟了光盘文件系统的结构。Linux要用它需要一个“把文件当作块设备来读”的机制这就是loop设备。挂载命令很简单mkdir -p /mnt/cdrom mount -o loop /opt/iso/CentOS-10.iso /mnt/cdrom我习惯先把ISO文件统一放到/opt/iso目录下这样系统盘和工作目录之间有清晰界限后续做局域网共享也更好管理。mount -o loop的意思是告诉内核把这个普通文件当成一个回环块设备来挂载。某些老环境可能需要加-t iso9660显式指定文件系统类型但现在的系统一般都能自动识别。挂载后一定要验证一下df -h | grep cdrom ls /mnt/cdrom/如果看到BaseOS、AppStream、CRB等目录说明挂载成功。这里有个关键点要检查看看每个仓库目录下有没有repodata子目录里面必须有repomd.xml文件。这个文件就是软件仓库的“索引清单”dnf就是靠它知道仓库里有哪些包、依赖关系是什么。2.3 将挂载固化到fstab防止重启失效很多人栽在这里挂载是成功了yum源也配置好了一切运行正常。结果某天机器重启所有软件都装不了了一查发现/mnt/cdrom是空的——挂载关系是临时的重启后自动没了。解决方法是把挂载信息写进/etc/fstab/opt/iso/CentOS-10.iso /mnt/cdrom iso9660 loop,defaults 0 0每一列分别表示设备或镜像文件、挂载点、文件系统类型、挂载参数、是否需要dump备份、fsck检查顺序。写入后先用mount -a测试一下这条命令会按照fstab重新挂载所有条目。如果控制台报错立即检查路径和参数避免带着错误配置重启。顺手提一个经验不要在/etc/fstab中省略挂载点目录。有的环境/mnt/cdrom不存在系统启动时挂载会失败进而可能导致进入紧急模式。先把mkdir -p做好再写fstab顺序不要反。3. 手写本地yum源repo文件及参数解析3.1 repo文件结构与关键参数说明挂载完成只是第一步真正让dnf认这个源需要在/etc/yum.repos.d/下新建一个.repo文件。文件名可以随意一般建议写成local-centos.repo避免和系统自带仓库文件混淆。每次配置源前先看一眼现有仓库文件确认哪些在线源处于启用状态。如果机器本身能联网那本地源和在线源可以共存但在线源慢时会拖累整体体验。我倾向于把不需要的repo文件搬到备份目录或者把enabled1改成enabled0只保留本地源这样整体行为可控。一个repo文件里可以同时定义多个仓库段每段以方括号括起来的仓库ID开头。关键参数有四个name仓库的显示名称可以随意写。baseurl仓库的实际路径本地用file://协议开头。enabled是否启用1启用0禁用。gpgcheck是否校验包的GPG签名生产环境建议保留1。3.2 针对CentOS 10仓库结构的repo配置示例以CentOS 10的仓库结构为基准我给出一份可以直接改来用的配置。先说明不同版本的ISO内部仓库目录名称可能微调配置前一定先ls确认实际目录名再落到配置里。[local-baseos] nameCentOS 10 Local BaseOS baseurlfile:///mnt/cdrom/BaseOS enabled1 gpgcheck1 gpgkeyfile:///mnt/cdrom/RPM-GPG-KEY-CentOS-10 [local-appstream] nameCentOS 10 Local AppStream baseurlfile:///mnt/cdrom/AppStream enabled1 gpgcheck1 gpgkeyfile:///mnt/cdrom/RPM-GPG-KEY-CentOS-10 [local-crb] nameCentOS 10 Local CRB baseurlfile:///mnt/cdrom/CRB enabled1 gpgcheck1 gpgkeyfile:///mnt/cdrom/RPM-GPG-KEY-CentOS-10这里有个最容易踩的雷baseurl的写法。本地文件路径需要用file://开头后面跟绝对路径也就是file:///mnt/cdrom/BaseOS三条斜线一个不能少。我记得初次配置时写成了file://mnt/cdrom/BaseOS结果dnf怎么都不认。另外gpgkey指向的文件名要以ISO目录下实际存在的文件为准不一定就叫RPM-GPG-KEY-CentOS-10。如果找不到对应文件可以先ls /mnt/cdrom/ | grep -i gpg看看实际名字然后填进配置。注意从维护角度看gpgcheck建议保持为1。虽然临时测试时把它改成0能绕开签名问题但生产环境关闭签名校验等于让系统在装未知来源的软件风险太大。3.3 验证本地源是否生效并完成首次缓存配置写完接下来是验证环节。依次执行dnf repolist这个命令会列出所有已启用的仓库。如果刚修改过配置建议先清理再重建缓存dnf clean all dnf makecachednf clean all会把已经缓存的仓库元数据清掉makecache重新拉取当前所有启用仓库的元数据。这一步很重要因为dnf有缓存机制改完repo配置后不清理有时候会遇到“仓库元数据过期”的奇怪报错。真正验证一个源能不能用得实际装一次包。我一般会装一个小工具比如tcpdumpdnf install -y tcpdump安装完成后注意观察终端日志里“下载软件包”的来源路径。如果显示file:///mnt/cdrom/...说明安装确实走的是本地源。多试几个包也能验证BaseOS和AppStream两个仓库是否都正常。至于CRB仓库如果需要编译工具链或者一些扩展库再启用即可。4. 本地源配置高频踩坑与排查思路4.1 挂载成功但repolist显示0个软件包症状dnf repolist能列出本地仓库但软件包数量是0装什么都说找不到包。排查路径很简单先看baseurl指向的路径下有没有repodata目录ls /mnt/cdrom/BaseOS/repodata/如果没有repomd.xml说明这个目录根本不是仓库根。常见原因是ISO目录结构变了或者挂载点写错。另外要确认每段repo的baseurl是否指向了正确的仓库子目录而不是直接指向挂载根目录。还有一种情况是路径对、文件也在但dnf因为权限问题读不到目录。检查一下挂载点权限ls -ld /mnt/cdrom如果连普通用户都读不到就调整目录权限或确认SELinux上下文配置。4.2 GPG签名校验失败错误信息里通常能看到类似“GPG key retrieval failed”或者“Public key for xxx.rpm is not installed”。原因分两种一是gpgcheck1但没有写gpgkey二是gpgkey路径写错dnf找不到公钥文件。最简单的排查方式是把配置里的gpgkey路径复制出来直接用ls看文件是否存在。不存在就找ISO根目录下实际的key文件名。临时测试时可以把gpgcheck改成0确认源本身没问题但装完包后记得改回来。4.3 切换源后仍然从在线源拉包如果你保留着官方在线源并且本地源和在线源同时启用dnf默认会并行使用所有启用仓库。有些软件包在多个仓库里都存在dnf会根据优先级和版本选择可能不会优先走本地。要让本地源真正变成首选最直接的方法是把不用的在线源禁用比如把/etc/yum.repos.d/下其他.repo文件里所有enabled1改成enabled0。也可以用优先级插件但对单机场景来说没必要复杂化。4.4 挂载在重启后失效导致装不上包症状很明显重启机器后df -h看不到挂载点dnf安装时报找不到仓库元数据。原因就是没写fstab或写了但挂载失败。处理方法前面说过把挂载条目固化到/etc/fstab并测试mount -a。写好后可以通过systemctl查看挂载单元是否正常激活。4.5 常见问题速查表症状排查方向解决思路仓库显示0个包baseurl路径下缺repodata确认目录层级与repomd.xmlGPG签名失败gpgkey路径或公钥文件缺失找到正确key名并配置安装走在线源多源并存未限制优先级禁用在线源或启用优先级机制重启后源失效fstab未配置或配置错误固化挂载并用mount -a验证报错“元数据过期”修改repo后未清缓存执行dnf clean all 和 makecache5. 从单机本地源扩展到内网共享源5.1 用最小代价把ISO目录变成HTTP源单机本地源解决的是“我这台机器装包难”的问题。如果机柜里有十台机器都要装同样的软件一台台挂载ISO显然不现实。更合理的做法是选一台机器挂载ISO然后用HTTP服务把这个目录共享出去其余机器把这个HTTP地址写进repo文件。最小代价的做法是用Python自带HTTP服务python3 -m http.server 8080 --directory /mnt/cdrom如果只是临时用这个命令足够。但要长期跑服务我会把它放到nginx或者Apache里并且让该服务开机自启。用nginx时配一个root /mnt/cdrom;加autoindex on;就可以局域网内访问速度很快。5.2 客户端配置HTTP方式的repo文件局域网内其他机器的repo配置与本地配置几乎一样唯一区别是把baseurl从file://换成http://。示例[remote-baseos] nameCentOS 10 Remote BaseOS baseurlhttp://内网服务器IP:8080/BaseOS enabled1 gpgcheck1 gpgkeyhttp://内网服务器IP:8080/RPM-GPG-KEY-CentOS-10这样一来所有机器共享同一套软件包版本完全一致后续想做版本变更也只要在一台机器上换镜像客户端重新makecache就行。我用这种方式给一个模拟项目X的小集群做过软件分发省掉的带宽和时间相当可观。5.3 构建自定义离线仓库有时候ISO里没有我们需要的软件包尤其是某些商业软件、闭源中间件或者内部自研包。这时可以建一个自定义目录把所有rpm包丢进去用createrepo_c生成元数据dnf install -y createrepo_c mkdir -p /data/myrepo cp /path/to/rpms/*.rpm /data/myrepo/ createrepo_c /data/myrepo执行完成后/data/myrepo下会出现repodata目录这个目录就可以当做一个独立的yum源。在repo文件里指向它即可。自定义源最适合配合本地ISO源使用ISO解决基础依赖自定义源补充业务软件两者互不干扰。配置yum源这种活麻烦不在于命令本身而在于细节——路径对不对、签名有没有、缓存刷没刷。我见过不少人卡在这些细节上一整天其实只要按“挂载ISO、检查repodata、写repo、清缓存装包”这个流程走一遍基本不会再兜圈子。最后再提一句生产环境别图省事把gpgcheck关掉签名校验是你对软件来源的最后一道确认留着它踏实。