资讯动态

CentOS Stream 10本地yum源配置:ISO挂载与离线安装实战

发布时间:2026/10/23 7:06:27 来源:尧图企业网站定制
前两天处理一台内网测试服务器系统是最小化安装的 CentOS Stream 10也就是很多人习惯写的 Centos10。装完想装个 vimdnf install -y vim-enhanced一执行就卡住等了半天直接超时原因是这台机器既访问不了官方 mirrorlist也没配置任何可用源。我当时的处理方式很简单把手头那张 CentOS Stream 10 的 DVD ISO 挂载到系统目录写一个本地 yum 源几分钟后 vim、wget、tree 就都装好了。这篇东西就围绕这个场景展开Centos10 环境下配置 yum 源挂载到底应该怎么做、为什么这么做、哪些地方容易出错。适合正在搭建离线环境、内网测试机或者刚接触 RHEL 系包管理不久、对仓库机制还有点懵的读者。我会把挂载、repo 文件、createrepo、gpg 校验这几个关键点一次讲透最后附上我在实战里踩过的坑。1. 先说清楚Centos10 的 yum 源到底要解决什么问题1.1 版本命名Centos10 与 CentOS Stream 10先厘清一个叫法。标题里写的是 Centos10在官方术语里具体对应的是 CentOS Stream 10。前几年 CentOS Linux 8 停止更新之后社区把重心放到了 CentOS Stream 这条滚动构建的发行线上Stream 10 就是基于 RHEL 10 上游的那一档。很多人仍然习惯叫它 Centos10这没问题但心里要清楚它和老 CentOS Linux 不太一样老的发行版有固定的生命周期Stream 则更偏向滚动跟随上游适合想在正式版本发布前就体验新特性的环境。另一个要确认的事情是包管理器。从 CentOS Stream 9 开始系统默认的包管理工具就是 dnfyum命令只是 dnf 的兼容入口基本等价。所以后面我写命令时统一用dnf你写成yum也能跑只是新系统不太建议刻意去依赖yum这个兼容层。为什么要把版本和工具先掰扯清楚因为网上大量教程还是 CentOS 7/8 时代的写法yum、Createrepo、repodata这些概念虽然还通用但路径结构、仓库分区、gpg 密钥文件命名都有差异。如果一上来就照抄老教程很可能在repomd.xml找不到或者公钥校验失败这一步卡住。1.2 本地ISO源、公共网络源、内网HTTP源怎么选yum 源这个词老运维一听就懂但对新人来说有个容易混淆的地方源有三种常见形态而且挂载在不同形态下含义不太一样。我把它们放在一张表里对比。形态典型访问方式适用场景主要缺点本地ISO挂载源file:///mnt/repo/BaseOS单台内网机、离线环境、临时装机只能服务本机包版本固定公共网络源https://mirrors.xxx/...能正常访问外网的机器内网受限或机器较多时不可控内网HTTP仓库http://内网IP/...成批机器、离线机房统一分发需要一台服务器做同步和发布这篇文章主攻第一种把 ISO 镜像挂到本地目录然后让 dnf 通过file://去读。原因很简单它是挂载二字最直接的体现也是另外两种源的基础——你正儿八经搭内网 HTTP 仓库时往往也是先把 ISO 挂载到某台服务器上再用 web 服务发布出去。1.3 挂载这个动作是整个方案的地基很多新手第一次接触挂载会困惑ISO 是个文件怎么变成源这里的关键是 mount 这个动作。Linux 里挂载本质是把一个块设备这里是把 ISO 文件通过 loop 设备模拟成块设备钉到某个目录上。钉完之后你在那个目录里看到的文件就是 ISO 里面的内容。打个比方ISO 文件就像一箱密封的货物mount 就是把箱门打开让你能直接站在仓库里看见每一件商品而 yum 源默认只能识别一个开放的货架它没法自己拆箱。所以标题里的挂载不是可选项而是必须做的一步。不挂载dnf 永远无法通过file:///mnt/repo/BaseOS这样的路径访问到安装包。2. 挂载前准备确认版本、准备镜像、规划目录2.1 先确认系统版本、架构和包管理器开始操作前先确认三件事系统版本、CPU 架构、包管理器是否正常。cat /etc/os-release cat /etc/redhat-release uname -m dnf --versionuname -m输出x86_64代表 x86 架构输出aarch64代表 ARM 架构。这个信息必须和 ISO 镜像的架构对应否则就算挂载成功、repo 文件写对安装时也会出现大量 Package architecture does not match 之类的错误。系统版本命令是为了确认你拿到的确实是 Stream 10而不是 Stream 9。两者虽然流程差别不大但仓库分区和 RPM 包集合有变化混着用容易出现依赖解析问题。2.2 获取 ISO 并校验完整性镜像从哪下内网环境通常可以到你所在网络访问速度最快的公共开源镜像站下载选 DVD 版本而不是最小化网络安装版。DVD ISO 的好处是里面自带了BaseOS和AppStream两个仓库的完整 rpm 包及 repodata 索引挂载之后直接就能用不需要依赖网络。下载完成后一定要做 SHA256 校验。ISO 文件动辄几个 GB传输过程中偶发损坏并不罕见而包损坏在 yum 源的场景里会以各种奇怪报错体现比如repomd.xml解析失败、某个 rpm 安装时校验和不匹配。校验命令很简单sha256sum /opt/iso/CentOS-Stream-10-x86_64.iso把输出和镜像站页面上给出的官方 SHA256 值比对完全一致再继续。这一步省不得后面所有排错都会因为镜像没问题而省掉大量猜疑。2.3 规划挂载点别把源放在 /tmp 之类的临时目录挂载点建议用/mnt/repo或者/repo/centos10这种固定路径别图省事放到/tmp下面。/tmp在系统重启、定时清理时都可能被清空而且语义上就是临时文件的地方。ISO 文件的存放位置同理建议固定放在/opt/iso不要放在用户家目录更不要放在系统盘里容易误删的目录。我给客户做环境时见过太多次这种场景机器用了两周某天跑dnf install突然报源不可用排查半天发现是当初把 ISO 放在了/tmp重启后文件没了。一个比较合适的规划是ISO 文件/opt/iso/CentOS-Stream-10-x86_64.iso挂载点/mnt/repo或/repo/centos10后续如果要升级包重新下载新版 ISO重新挂载覆盖即可3. 手动挂载到永久挂载mount 与 fstab 的正确姿势3.1 手动挂载 ISO 的命令与验证先手动挂载一次确保整个链路没问题再谈开机自启。需要 root 权限然后建目录、挂载、验证三步走mkdir -p /mnt/repo mount -o loop /opt/iso/CentOS-Stream-10-x86_64.iso /mnt/repo df -h | grep /mnt/repo ls /mnt/repo-o loop的含义是让内核把普通文件模拟成块设备来挂载这是 ISO 文件挂载的常规做法。如果挂载成功df -h里能看到/mnt/repo一行ls能看到 ISO 根目录下的文件列表。在这里我要特别提醒一个点mount命令执行之后如果没有任何输出通常是好事有输出反而要仔细看。最常见的报错是mount point does not exist解决方法是先mkdir还有一种是Permission denied要么不是 root要么文件所在磁盘本身就有问题。3.2 有光驱设备时直接挂 /dev/sr0 的替代方案如果你的机器是虚拟机或者物理机带光驱系统里通常有/dev/sr0之类的光驱设备。这种情况下不一定要用 loop 挂载 ISO 文件可以直接挂载光驱设备lsblk mount /dev/sr0 /mnt/repolsblk先看一眼设备列表。如果确认存在sr0且光驱里已经放入了系统安装光盘直接挂设备更省事加载速度通常也比 loop 方式快一点。但要注意光驱设备对应的是物理盘/虚拟盘里的那张盘而不是某个独立 ISO 文件。如果你手头只有 ISO 文件还是用 3.1 的方式。3.3 写入 fstab 实现开机自动挂载手动挂载只能维持到重启之前。要让系统每次开机都自动把 ISO 挂到指定目录需要写入/etc/fstab。在文件末尾追加一行/opt/iso/CentOS-Stream-10-x86_64.iso /mnt/repo iso9660 loop,ro,nofail 0 0逐字段解释第一列是 ISO 文件的绝对路径第二列是挂载点第三列是文件系统类型ISO 镜像对应iso9660第四列里loop表示用 loop 设备挂载文件ro表示只读对 iso9660 来说本来就是只读写不写其实影响不大但建议保留nofail表示如果启动时这个设备或文件找不到不要进入紧急模式直接跳过第五、六列0 0表示不参与 dump 备份和 fsck 检查。写完后先验证一下配置是否正确mount -a df -h | grep /mnt/repomount -a会按照 fstab 配置把尚未挂载的条目全部挂一遍。如果这条命令卡住或者报错说明 fstab 这一行有问题千万别直接重启否则可能起不来。3.4 挂完先检查目录结构别急着写 repo挂载完成后先看一眼目录结构再写仓库文件。这一步很多人会跳过结果后面排查半天发现是路径多了一层或者大小写写错。ls /mnt/repo ls /mnt/repo/BaseOS/repodata/repomd.xml ls /mnt/repo/AppStream/repodata/repomd.xml正常情况下你会看到BaseOS和AppStream两个目录它们下面各自有一个repodata/repomd.xml。如果 ISO 版本较特殊根目录可能还会有一层版本号目录比如/mnt/repo/CentOS-Stream-10-x86_64/BaseOS此时后面的 repo 文件路径要跟着调整。4. repodata 的真相为什么有时要 createrepo有时不用4.1 repodata 就是 yum 源的索引很多新手以为 yum 源只要有一堆 rpm 包就行这是最大的误解。dnf 真正依赖的其实是repodata目录里的索引其中最关键的文件是repomd.xml。它相当于整个仓库的货架清单有哪些软件包、每个软件包在什么路径、校验和是多少、依赖关系如何全部记录在这个 XML 以及配套的数据文件里。没有 repomd.xml就算目录里堆着几万个 rpm 包dnf 也会直接报Cannot download repodata/repomd.xml拒绝工作。反过来只要 repodata 存在且完整rpm 包哪怕在很深的子目录里dnf 也能通过索引找到。打个更直白的比方超市里商品摆得再满如果没有货物清单收银台就没法扫码结账。repodata 就是那张清单。4.2 官方 DVD 自带 repodata这是最省事的情况CentOS Stream 10 官方 DVD ISO 的特点是BaseOS和AppStream两个目录已经预生成了完整的 repodata。所以你只需要把挂载点目录指到仓库不需要任何额外操作。这也是为什么我推荐优先用 DVD ISO 而不是自己找个 rpm 包目录。两种情况的差别源的数据来源是否有现成 repodata你需要做的事官方 DVD ISO 的 BaseOS有写 .repo 指过去就行官方 DVD ISO 的 AppStream有写 .repo 指过去就行自己收集的 rpm 目录没有先安装 createrepo_c再生成索引判断方法很简单就是 3.4 里那两条ls命令看到repomd.xml就说明自带索引。4.3 自制 rpm 目录必须先用 createrepo_c 生成索引有些场景下你可能没有 DVD ISO只有一个从别处拷来的 rpm 目录里面有大量.rpm文件但没有repodata。这种就需要自己生成索引工具是createrepo_c。在 CentOS Stream 10 上安装它需要先有一个可用源。如果官方网络源已经失效比如内网机器可以从刚挂载的 ISO 里的 Packages 目录中找到createrepo_c的 rpm 包手动安装find /mnt/repo -name createrepo_c-*.rpm找到后用rpm -ivh安装如果提示依赖缺失就继续从同一个目录里找对应的依赖包。等createrepo_c可用之后对你自己的 rpm 目录生成索引createrepo_c /data/rpm/BaseOS这个命令会在/data/rpm/BaseOS下生成repodata目录。如果之后这个目录里的 rpm 包新增了重跑一次加--update参数即可createrepo_c --update /data/rpm/BaseOS我特别提醒一个坑不要在 ISO 挂载目录上直接执行createrepo_c。因为 iso9660 是只读文件系统命令会卡在写入repodata时报Read-only file system。如果你真的想给 ISO 里的某个目录做索引先把 rpm 文件复制到可写位置再操作。4.4 gpg 签名校验什么时候开什么时候关rpm 包出厂前会打上 GPG 签名dnf 在安装时可以通过公钥来验证软件包是否被篡改过。这就是gpgcheck1做的事情。默认情况下 CentOS 官方仓库都是开着的所以我们写本地源时也应该保持一致。但 GPG 校验会增加一点理解成本尤其是当密钥文件名和路径不对时会产生让人一头雾水的报错。我提供两条判断经验源里的 rpm 是你自己整理的非官方包且内网环境完全可信图省事可以gpgcheck0。源来自官方 ISO 或官方镜像站务必保持gpgcheck1并指定正确的gpgkey路径。我更推荐后者。gpg 校验开着的另一层意义是如果某个 rpm 文件在复制或传输过程中损坏dnf 会在安装前直接报校验失败而不是装到一半开不了服务。这能帮你提前暴露问题而不是掩盖问题。5. 写 .repo 文件并让 dnf 真正用起来5.1 第一步备份并清理默认仓库配置这是最容易忽略的一步也是内网环境翻车的头号原因。新装好的 CentOS Stream 10/etc/yum.repos.d/下面默认带着官方仓库配置文件比如centos.repo之类。这些文件指向的地址在外网环境没问题但在内网环境会导致 dnf 在扫描仓库时疯狂尝试连接外部 mirrorlist最终报超时或者干脆报Cannot find a valid baseurl for repo: baseos。处理办法很简单把默认配置全部挪到备份目录让 dnf 只认我们自己写的仓库文件。mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ ls /etc/yum.repos.d/做完之后确认一下目录里还剩什么。正常情况应该只剩.repo文件如果你之前已经建过或者暂时为空。别把backup目录里的内容再卷进去。5.2 本地源 repo 文件模板新建/etc/yum.repos.d/local.repo内容如下[local-baseos] nameLocal CentOS Stream 10 BaseOS baseurlfile:///mnt/repo/BaseOS enabled1 gpgcheck1 gpgkeyfile:///mnt/repo/RPM-GPG-KEY-CentOS-Official [local-appstream] nameLocal CentOS Stream 10 AppStream baseurlfile:///mnt/repo/AppStream enabled1 gpgcheck1 gpgkeyfile:///mnt/repo/RPM-GPG-KEY-CentOS-Official有几个字段我要单独解释baseurl指向的是仓库目录不是具体某个文件也不是repodata目录本身。file://表示本地文件系统访问。路径要写到包含 rpm 包的那一层比如/mnt/repo/BaseOS因为这一层下面才有repodata。gpgkey的文件名不一定是RPM-GPG-KEY-CentOS-Official不同版本的 ISO 可能略有差异。建议写之前先看一眼ls /mnt/repo/*GPG*如果看到实际文件名不一样就把它替换到 gpgkey 那一行。如果 ISO 根目录同时有AppStream等其他仓库并且确实需要引入可以继续追加类似的段落。模板文件里name只是显示名[local-baseos]这里的英文名才是 repo id全局唯一不要和默认仓库 id 重复。5.3 dnf clean、makecache、repolist 三步验证写完 repo 文件之后按顺序执行三条命令dnf clean all dnf makecache dnf repolistdnf clean all清掉之前所有仓库缓存避免旧缓存干扰。dnf makecache根据新的 repo 文件重新建立元数据缓存。dnf repolist会列出当前可用的仓库列表以及启用状态。如果一切正常你会看到类似这样的信息local-baseos和local-appstream出现在列表里状态为 enabled。如果列表里还残留baseos之类默认仓库 id说明备份步骤出了问题回去检查 5.1。如果makecache阶段报错Cannot download repomd.xml先看路径大小写和层级再回 3.4 对照检查目录结构。5.4 实测安装软件包验证全链路仓库配置好之后最好装一个包做全链路验证不要只看repolist就完事。我会装一个确定存在于 BaseOS 或 AppStream 里的基础工具dnf install -y wget vim-enhanced如果安装过程顺畅、没有尝试访问外网、速度很快说明本地源已经生效。这里有个小细节dnf在安装时会打印它正在访问的仓库名。如果你看到local-baseos这样的字眼就能确认包确实来自本地挂载目录而不是某个残留的默认源。如果此时报Public key for xxx is not installed说明 gpg 密钥还没导入到系统。有两种处理方式一是先导入 ISO 里的密钥文件再重试rpm --import /mnt/repo/RPM-GPG-KEY-CentOS-Official二是检查 gpgkey 路径是否拼写正确。不要轻易把gpgcheck改成 0我们前面说过开着校验能帮你提前发现包损坏问题。6. 踩坑记录本地源配置里最容易翻车的几个细节6.1 路径大小写与目录层级不对报错却总指向 repomd.xml我在给不同环境的机器配置源时遇到最高频的问题就是路径。BaseOS的首字母是大写 B很多人照抄教程时习惯性写成小写baseos还有的 ISO 目录结构多套了一层版本号目录。这两种情况最终都会报Cannot download repodata/repomd.xml但错误信息本身不会告诉你路径错了。遇到这种报错第一反应不要怀疑 repo 文件语法而是去现场看目录tree -L 2 /mnt/repo先看层级再看大小写逐个核对baseurl。Linux 路径是大小写敏感的这在 Windows 习惯过来的同事身上特别容易犯。记住file://的路径必须和实际目录完全一致一个字都不能差。6.2 开机挂载失败导致直接进 rescue 模式fstab 写得不严谨会在重启时把系统卡进 emergency mode。典型场景是这样的ISO 文件所在磁盘是加密盘或者网络盘启动早期阶段该磁盘还没就绪systemd 尝试挂载/mnt/repo时找不到文件于是判定 fstab 条目异常直接停下来等你手动处理。解决方法是加nofail如 3.3 节所写。nofail的意思是这个挂载条目如果失败就跳过不要阻塞启动流程。虽然大多数场景下 ISO 放在本地普通磁盘上不会遇到这个问题但加上nofail属于零成本保险建议一律加上。另外还有个细节fstab 里第一列必须写 ISO 文件的绝对路径不要写相对路径不要依赖环境变量。系统启动早期阶段环境极其有限任何我以为能解析的路径可能都无法解析。6.3 GPG key 报错的两个典型场景GPG 相关报错有两个高频场景。第一个是gpgkey文件路径写错dnf 在验证时发现找不到 key 文件于是直接拒绝处理仓库。第二个是系统里已经装了旧的公钥但和当前 rpm 包的签名对不上报Public key for xxx is not installed或GPG key retrieval failed。处理思路很明确先看 ISO 根目录实际有哪些 GPG 文件ls /mnt/repo/*GPG*然后用rpm --import导入正确的密钥再执行dnf clean all dnf makecache重来一遍。如果是在线环境也可以先删除旧的 key 再导入新的。这个问题的本质是密钥状态和仓库包不匹配不要试图绕过 gpg 校验直接关gpgcheck。6.4 从本地 file 源迁移到内网 http 源防火墙与 SELinux单机本地源搞定之后如果你要给内网里三五十台机器统一装包最自然的方案是把挂载目录通过 web 服务发布出来让客户端改用http://内网IP/...访问。这个演进本身不复杂但有两个新坑经常出现。第一个是 SELinux。默认情况下 web 服务进程的 SELinux 域是httpd_t它只能读取带有httpd_sys_content_t上下文标签的目录。直接把/mnt/repo发布出去而不改标签客户端访问会得到 403但报错到 dnf 那边却表现为 metadata 下载失败让人误以为是 repo 配置出错。处理方式chcon -R -t httpd_sys_content_t /mnt/repo firewall-cmd --add-servicehttp --permanent firewall-cmd --reloadchcon是临时修改重启后可能失效。更规范的做法是用semanage fcontext添加持久化规则配合restorecon恢复。如果只是临时用一下chcon就够了。第二个是防火墙。内网环境默认可能只开了 22 端口web 服务端口没放行客户端访问必然失败。firewall-cmd --add-servicehttp --permanent是红帽系的标准操作注意--permanent参数会让规则永久生效不加的话重载就丢了。反过来如果同一配置在一台机器上正常、另一台机器报权限错误优先检查后者的 SELinux 上下文和防火墙不要纠结 repo 文件。这个经验我在不少项目环境里反复验证过。6.5 我现在的常规做法与一点小技巧最后分享一个我自己的习惯。每拿到一台新装的 CentOS Stream 10 内网机器我做的第一件事不是马上去配网络源而是把手头的 DVD ISO 挂起来作为初始源。装完 vim、wget、tree、lrzsz 这些基础工具之后再根据网络条件决定要不要切换成内网 HTTP 源。ISO 固定放在/opt/isofstab 写死这样哪怕将来重装系统、或者某天机器彻底断网本地源依然可靠可用。一个小技巧是挂载点路径尽量起得像回事比如/repo/centos10而不是/mnt/repo。虽然区别不大但等你后面要给内网发布、写同步脚本、做 cron 计划时一个语义清晰的路径会让整个环境显得有序得多排查问题时也省心。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑