恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
离线环境搭建本地yum源完整指南:从rpm包收集到客户端验证
首页
资讯中心
/
离线环境搭建本地yum源完整指南:从rpm包收集到客户端验证
离线环境搭建本地yum源完整指南:从rpm包收集到客户端验证
发布时间:2026/10/17 20:35:44
在企业内网、隔离环境或者一些不允许直接访问外部软件源的场景里自己动手搭一个本地 yum 源几乎是每个运维和系统管理员都会遇到的需求。尤其是当你手里只有一堆从网络上下载下来的 rpm 软件包而目标机器又完全无法连接外网时怎么把这些零散的包变成一个可用的、能被 yum 正常识别的仓库就成了一个必须解决的问题。我最近刚在一个纯离线环境里完整走了一遍这个流程从收集 rpm 包到生成元数据、配置客户端、最终成功安装中间踩了几个不大不小的坑这里把整个过程和踩坑经验完整记录下来给有同样需求的朋友一个可以直接抄作业的参考。这篇文章适合有一定 Linux 基础、需要在内网或离线环境搭建 yum 源的运维人员也适合刚接触 rpm 包管理、想搞清楚 yum 仓库底层原理的开发者。我会从最基础的概念讲起把每一步为什么这么做、参数怎么来的都说明白最后给出完整的操作命令和验证方法。1. 先搞清楚 yum 源到底是个什么东西很多人一上来就急着敲命令结果遇到报错完全不知道从哪查起。我觉得在动手之前花十分钟把 yum 仓库的组成结构搞清楚后面会省掉大量排查时间。1.1 yum 仓库的本质就是目录加元数据yum 本身并不神秘它做的事情可以简单理解为去一个指定的目录或者网络地址里读取一份描述这个目录里有哪些包、每个包依赖什么、包与包之间什么关系的清单文件然后根据这份清单帮你解决依赖、下载安装。所以一个能用的 yum 仓库必须包含两样东西一堆 rpm 软件包文件本身一份描述这些包的元数据metadata元数据不是随便写的它由专门的工具扫描 rpm 包后自动生成放在一个叫repodata的目录里。yum 客户端访问仓库时第一步就是去读repodata/repomd.xml这个文件相当于仓库的入口索引里面记录了其他元数据文件的位置和校验值。理解了这一点你就能明白为什么把 rpm 包丢到一个目录里然后配置 yum 指向这个目录是不行的——因为缺少repodatayum 根本不知道目录里有什么。1.2 为什么不能直接一个个 rpm -ivh 安装有人会问既然包都在本地我直接rpm -ivh *.rpm一个个装不就行了为什么还要费劲搭 yum 源这个问题我在实际工作中被问过很多次。直接 rpm 安装最大的问题是依赖关系需要手动解决。比如你装 A 包它依赖 B 和 CB 又依赖 D你得自己一个个去找、去按顺序装一旦依赖链很长手动处理会非常痛苦而且容易出错。yum 的核心价值就在于自动依赖解析。它会读取元数据里的依赖信息自动计算出需要安装哪些包、按什么顺序装你只需要一条yum install命令。所以在离线环境里把 rpm 包做成 yum 源本质上是为了重新获得这种自动依赖解析能力。1.3 本地源和网络源的区别在哪从 yum 客户端的角度看本地源file://和网络源http://、ftp://在使用方式上几乎没区别区别只在于仓库地址的协议不同。file://方式仓库就在本机文件系统上配置最简单适合单机使用http://方式仓库放在一台服务器上通过 HTTP 服务共享给多台机器适合内网批量部署我这次的需求是给一批内网机器提供统一的软件源所以最终采用的是 HTTP 方式。但制作仓库元数据的过程两者完全一样区别只在最后配置客户端时的 baseurl 写法。下面我会把两种方式都讲到。2. 收集和整理 rpm 包时最容易忽略的细节仓库能不能用很大程度上取决于你收集的 rpm 包是否完整、是否匹配目标系统。这一步看起来简单实际上坑最多。2.1 包的来源和版本必须和目标系统匹配我这次拿到的 rpm 包是从一台和目的一样的系统上通过yumdownloader下载下来的。这里有个关键点下载包的机器和目标机器的系统版本、架构必须一致。举个例子如果目标机器是 CentOS 7 x86_64那你下载的包也必须是针对 el7 x86_64 的。如果你不小心混入了 el8 或者 i686 的包生成仓库时可能不报错但客户端安装时会出现依赖找不到或者包不兼容的问题。怎么确认一个 rpm 包的目标平台可以用这条命令看rpm -qp --queryformat %{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n xxx.rpm输出里如果看到el7、x86_64这样的字样就说明平台信息。批量检查的话可以写个循环for pkg in *.rpm; do echo -n $pkg: rpm -qp --queryformat %{ARCH}\n $pkg done把架构不一致的包挑出来剔除掉能避免后面很多莫名其妙的报错。2.2 依赖包要下全否则仓库等于白搭这是离线搭源最核心的痛点。你从网络上下载的包往往只是你直接想装的那个包但它依赖的一大堆包你并没有一起下下来。结果就是仓库搭好了yum install的时候还是提示缺依赖。正确的做法是在一台能联网、且系统和目标一致的机器上用yumdownloader把目标包及其所有依赖一起下载下来。命令大概是这样yumdownloader --resolve --destdir/tmp/rpms httpd--resolve这个参数是关键它会自动把依赖树上的所有包都下载下来。--destdir指定下载目录。这样下载下来的包集合才是完整的。提示如果目标机器和下载机器的系统版本有细微差异比如小版本号不同依赖包可能会有出入。最稳妥的办法是尽量让两台机器的系统版本完全一致。2.3 目录结构建议按需规划rpm 包放哪个目录其实没有硬性规定但建议规划得清晰一点方便后续维护。我一般会这样组织/data/yum-repo/ ├── base/ # 基础系统包 ├── extras/ # 额外软件包 └── custom/ # 自己收集的定制包每个子目录都是一个独立的仓库各自生成自己的 repodata。这样以后要更新某一类包不会影响到其他仓库。如果包不多全部放一个目录也完全可以不用过度设计。3. 用 createrepo 生成仓库元数据包整理好了接下来就是最关键的一步生成元数据。这一步用到的工具是createrepo。3.1 安装 createrepo 工具createrepo这个工具本身可能不在最小化安装的系统里需要先装上。如果目标机器能连外网直接yum install -y createrepo如果是完全离线的环境那就得先想办法把 createrepo 的 rpm 包搞进来手动安装。它本身依赖 python 相关的一些库通常系统里已经有了直接rpm -ivh createrepo-*.rpm一般能装上。装完后用createrepo --version验证一下。3.2 执行 createrepo 生成元数据假设你的 rpm 包都放在/data/yum-repo/custom/目录下生成元数据的命令非常简单createrepo /data/yum-repo/custom/执行完之后你会看到该目录下多了一个repodata目录里面就是生成的各种元数据文件。这时候一个最基本的仓库就已经成型了。这里解释一下 createrepo 背后做了什么它会遍历目录下所有 rpm 包读取每个包的头部信息名称、版本、依赖、提供的能力等然后把这些信息汇总、压缩生成primary.xml.gz、filelists.xml.gz、other.xml.gz等文件最后生成入口文件repomd.xml。yum 客户端就是通过读这些文件来了解仓库内容的。3.3 包有更新时怎么重新生成如果你往目录里新增了 rpm 包需要重新生成元数据否则 yum 看不到新包。有两种做法直接重新跑一遍createrepo /data/yum-repo/custom/它会重新扫描全部包用--update参数增量更新createrepo --update /data/yum-repo/custom/包数量少的时候两者差别不大包多的时候--update会快很多因为它只处理新增和变化的包。不过实测下来--update偶尔会有缓存导致新包识别不到的情况如果发现更新后 yum 还是看不到新包直接全量重新生成一次最保险。注意每次重新生成元数据后客户端的 yum 缓存需要清理才能看到变化命令是yum clean all这个后面会详细说。4. 把仓库共享出去HTTP 方式的配置单机使用的话仓库放在本地用file://引用就够了。但如果要给多台机器用就需要通过 HTTP 服务把仓库目录共享出去。4.1 用 HTTP 服务暴露仓库目录最常用的做法是装一个 HTTP 服务把仓库目录作为网站根目录或者子目录暴露出来。假设仓库在/data/yum-repo/可以这样配置# 安装 http 服务以常见的为例 yum install -y httpd # 创建一个软链接把仓库目录挂到网站目录下 ln -s /data/yum-repo /var/www/html/repo # 启动服务 systemctl start httpd systemctl enable httpd这样其他机器就可以通过http://服务器IP/repo/custom/来访问这个仓库了。4.2 权限和防火墙的常见问题这一步最容易卡住的地方有两个权限问题HTTP 服务默认以特定用户身份运行如果仓库目录的权限设置得太严服务进程读不到文件客户端访问就会返回 403。解决办法是确保仓库目录及其父目录对服务进程可读通常给个755权限就够了chmod -R 755 /data/yum-repo防火墙问题如果服务器开了防火墙需要放行 HTTP 端口否则客户端根本连不上。这个根据实际环境配置即可测试阶段可以先临时关闭防火墙验证确认没问题后再按需放行。验证服务是否正常可以在服务器本机执行curl -I http://localhost/repo/custom/repodata/repomd.xml如果返回 200说明 HTTP 这一层通了。如果返回 403 或 404就回头查权限和路径。5. 客户端配置与完整验证流程仓库服务端搭好了最后一步是在客户端配置并验证。这一步我会把配置文件的写法、缓存清理、以及完整的验证命令都列出来。5.1 编写 repo 配置文件在客户端的/etc/yum.repos.d/目录下新建一个.repo文件比如custom.repo内容如下[custom] nameCustom Local Repository baseurlhttp://服务器IP/repo/custom/ enabled1 gpgcheck0如果是单机本地使用把 baseurl 改成file:///data/yum-repo/custom/即可。这里几个字段解释一下[custom]仓库的 ID必须唯一客户端用它来标识这个仓库name仓库的描述随便写只是给人看的baseurl仓库地址指向包含 repodata 的那个目录enabled1启用这个仓库gpgcheck0关闭 GPG 签名校验。自己做的仓库一般没有签名所以关掉否则会报签名验证失败提示如果出于安全考虑想开启 gpgcheck需要自己生成 GPG 密钥对包进行签名流程会复杂不少。内网自用场景下关闭 gpgcheck 是常见做法。5.2 清理缓存并验证仓库可用配置文件写好后先清理旧缓存再让 yum 重新读取仓库yum clean all yum repolistyum repolist会列出当前所有可用的仓库。如果你看到custom这个仓库出现在列表里并且包数量不为 0说明仓库配置成功了。如果custom没出现或者包数量是 0常见原因有现象可能原因排查方向仓库不出现repo 文件语法错误检查文件名后缀是否为 .repo字段拼写包数量为 0repodata 未生成或路径不对确认 baseurl 指向的目录下有 repodata报 403/404HTTP 权限或路径问题用 curl 直接访问 repomd.xml 验证报签名错误gpgcheck 开着但无签名设置 gpgcheck05.3 实际安装测试仓库通了之后做一次真实安装测试才算真正验证完成。挑一个你下载的包比如 httpd执行yum install -y httpd如果 yum 能自动解析依赖并从你的仓库里把包都装上那就说明整个流程完全跑通了。这一步我建议一定要做因为yum repolist只能证明仓库被识别不能证明依赖关系是完整的。只有真正装一次才能确认你收集的依赖包是全的。安装过程中如果提示某个依赖找不到那就说明你下载包的时候漏了依赖需要回到第 2 步把缺的包补进来重新生成元数据再清理客户端缓存重试。6. 几个我实际踩过的坑和应对经验前面流程讲完了这里单独把几个实际踩过的坑拎出来说这些是文档里一般不会写、但实际很容易遇到的问题。6.1 元数据生成后客户端看不到新包这个坑我遇到过一次。当时往仓库里加了几个新包跑了createrepo --update结果客户端yum repolist显示的包数量没变新包死活看不到。排查过程是这样的先在服务端确认 repodata 目录的修改时间是不是最新的发现确实是刚更新的。然后直接在客户端用 curl 拉取 repomd.xml对比里面的校验值和服务器上的文件发现客户端拿到的还是旧的缓存。原因就是客户端 yum 有本地缓存yum clean all之后重新yum makecache就好了。所以记住一个原则服务端元数据一变客户端必须清缓存。这个顺序不能乱。6.2 依赖包版本冲突导致安装失败还有一次仓库里同时存在同一个包的两个版本结果 yum 解析依赖时选错了版本导致安装失败。这种情况通常是因为多次下载包时没注意把新旧版本都放进去了。处理办法是保持仓库里同一个包只保留一个版本把多余的删掉再重新生成元数据。如果确实需要保留多版本那就要在配置依赖时格外小心或者用yum install 包名-版本号的方式明确指定版本。6.3 大仓库生成元数据很慢怎么办如果仓库里的包非常多比如上千个createrepo全量生成会非常慢可能要好几分钟甚至更久。这时候有几个优化方向用--update做增量更新避免每次全量扫描用--workers参数开启多线程加快生成速度比如createrepo --workers 4 /data/yum-repo/custom/把仓库按类别拆分成多个小仓库各自独立生成减少单次生成的数据量我实测下来--workers参数对多核机器提升比较明显包多的话建议加上。6.4 关于仓库的日常维护建议仓库搭好只是开始后续维护才是长期工作。我的经验是每次增删包之后养成重新生成元数据 客户端清缓存的固定动作定期检查仓库里有没有重复版本、架构不匹配的包如果仓库要长期给多台机器用建议写个简单的脚本把生成元数据这一步自动化避免手动操作遗漏这套流程我从第一次摸索到现在已经在内网环境里稳定用了很久中间除了上面提到的几个坑整体还是很顺的。核心其实就是理解rpm 包 repodata 元数据 yum 仓库这个本质剩下的都是围绕这个本质做配置和验证。把依赖包收集全、把元数据生成对、把客户端缓存清干净这三件事做到位离线 yum 源基本就不会出问题。