ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CentOS 7内网离线环境本地YUM源搭建实战指南

CentOS 7内网离线环境本地YUM源搭建实战指南 搞运维的最怕什么不是服务器宕机而是一台刚交付的机器要装软件包却发现自己正处在一个完全内网的离线环境里。你敲下yum install vim系统开始尝试解析外网镜像域名然后超时、报错最后留下一句Could not resolve host。原因其实很简单YUM 默认仓库文件里的baseurl指向的全是公网地址内网离线环境下根本拿不到仓库的repodata元数据自然也就不知道去哪里下载 RPM 包。本地YUM源就是专门为解决这个场景而生的把软件包源放到内网可达的位置再通过一个本地repo文件告诉 YUM“仓库就在这台机器上”。下面我会以 CentOS 7 为例覆盖从挂载 ISO、配置 repo、HTTP 共享到createrepo构建自定义源的全过程也会把实验目的、选型逻辑和踩坑记录一起讲清楚。这个场景在真实工作里太常见了。党政机关、金融机构、电厂机房、军工企业很多网络环境安防要求高服务器不能随便接入公网还有一些交付现场客户只给你一台裸机网络连外网都没有。你拿着 CentOS 7 安装光盘装完最小化系统想装个net-tools都要折腾半天。只靠 U 盘来回拷 RPM 包不是不行但一旦遇到依赖链很长的情况手动安装会让你崩溃。所以“linux 配置本地 yum 源实验目的”这件事被反复搜索不是没有原因的它几乎是 Linux 系统管理员的必备基础技能。搞明白这个实验就能让yum install在无公网环境下照常工作让多台机器共用同一套软件包也能把散落各处的 RPM 包收拢成一个统一仓库。1. 内网离线环境下的YUM困境与实验目的1.1 没外网时yum install 为什么总是失败YUM 的工作机制本质上是一个“客户端-仓库”模型。客户端读取/etc/yum.repos.d/下的.repo文件找到仓库地址然后下载仓库中的repodata/repomd.xml元数据再根据元数据里的文件列表去解析依赖。这套机制设计得很好但它有一个前提客户端必须能访问到baseurl指定的地址。一旦进入内网离线环境系统默认的CentOS-Base.repo、CentOS-Epel.repo等文件全都指向公网域名YUM 客户端第一步去获取元数据时就卡死了。在离线环境里最常见的报错有两类。一类是域名解析失败Could not resolve host: mirror.centos.org这是因为内网 DNS 根本没有公网解析能力另一类是连上了但超时Cannot find a valid baseurl for repo: base/7/x86_64因为防火墙出不去或者镜像站根本不可达。很多新手到这里就以为是网络配置问题去改 DNS、改路由搞了半天也没用。实际上问题的根源不是能不能上网而是“YUM 没有本地仓库可用”。我们要做的就是给它造一个本地仓库让 YUM 把本地路径或者内网 HTTP 地址当成合法的baseurl。1.2 本地YUM源能解决什么问题实验目的拆解结合我自己的维护经验本地 YUM 源主要解决四个问题。第一避免重复搬运 RPM 包。如果没有源每台机器都要手动下载安装包传一次忍一次几十台机器就是灾难。第二解决依赖自动解析。手动rpm -ivh遇到依赖就得手动找而 YUM 源有元数据能自动把依赖关系算清楚。第三保证版本一致性。一个部门二十台机器今天装这个版本明天装那个版本时间久了环境就乱套了用统一源能锁定版本。第四加快内网安装速度。内网走 HTTP 或者本机文件系统比从公网拉取快得多尤其是批量部署时体感非常明显。把这个实验的目的拆开其实就三句话一是通过挂载 ISO 或使用createrepo构建可用的仓库二是写好.repo文件让 YUM 正确识别仓库三是用yum makecache、yum repolist、yum install三步验证仓库是否真正生效。如果你还想让局域网内其他机器共用这个源那就得再加一步把仓库通过 HTTP 或 NFS 共享出来。下面我按方案选型、实操步骤、进阶玩法、问题排查的顺序来写照着做基本不会翻车。2. 本地YUM源方案选型光盘ISO、镜像同步、自定义RPM库应该选哪种2.1 光盘ISO源最省事但要清楚它的边界如果你手里有 CentOS 7 的系统安装镜像那恭喜你这是最快的一种本地源。把 ISO 挂载到某个目录写一个baseurlfile:///mnt/cdrom的 repo 文件就完成了一大半。光盘源的好处非常明显不需要额外下载任何东西安装镜像里的Packages目录自带了几千个常用 RPM 包像vim、net-tools、gcc、make、httpd这些都能直接装。但它也有边界而且很多人容易忽略。CentOS 7 的 DVD 镜像大约 4GB里面主要是基础安装包和常用工具但并不是全量仓库。比如nginx不在默认 DVD 源里python3在 DVD 里有但可能版本比较旧一些冷门包更是找不到。如果你的内网环境只是需要装系统后补几个常用软件ISO 源完全够用但如果你要装一堆新软件或者需要 EPEL 仓库那就要考虑下面两种方案了。另外DVD 里的软件包不是实时更新的存在安全漏洞时你得定期从合规渠道获取新版镜像或补丁包。2.2 镜像同步源适合批量机器和长期维护当内网有几十台甚至上百台机器且软件需求比较多时我建议你维护一个“真正的镜像源”。思路是在允许访问公网的前置机器上通过rsync把某个开源镜像站的 CentOS 仓库同步下来再通过合规的数据导入方式放到内网服务器上最后用 HTTP/FTP/NFS 共享给所有内网机器。这种方案能最大程度保留 YUM 原生的仓库结构baseurl指向公网镜像的路径名称都不需要大改只需把域名换成内网服务器地址。同步命令大概长这样rsync -avz --delete rsync://mirrors.example.com/centos/7/os/x86_64/ /data/mirrors/centos/7/os/x86_64/实际使用时要根据你选择的具体镜像站调整地址并且注意--delete参数不要乱加它会把远端不存在的文件删掉如果你还要手动补充自己的包就不要对同一个目录用--delete否则会被误清。同步完成后目录结构里会有Packages/和repodata/直接把/data/mirrors作为网站根目录用 HTTP 发布客户端通过 URL 访问即可。这种方式前期准备费点劲但维护成本低适合长期稳定的内网环境。2.3 自定义RPM目录源离线安装包管理的终极形态第三种情况更贴近很多人实际遇到的场景你手里没有完整镜像只有一堆从各种渠道收集来的 RPM 包或者你们团队自己开发了一些内部工具需要统一分发。这时候就需要用到createrepo这个神器。它能扫描一个目录下的所有 RPM 包生成repodata元数据让 YUM 客户端把这个目录当成一个标准仓库。自定义源特别适合放补丁包、自研软件、第三方商业软件安装包。你可以把/data/yum/rpms这个目录变成公司内部软件仓库新包直接丢进去重建一次元数据全网机器就能yum install了。这种方案的可控性最强但需要你自己处理依赖createrepo只负责建立索引不会帮你去公网下载缺失的依赖所以在放入 RPM 包时要确保依赖是完整的。我把三个方案的特点做成了一张表方便你选型方案优点缺点适用场景光盘 ISO 源搭建最快无需下载包不新缺少部分软件单机或少量机器临时使用镜像同步源仓库结构完整可持续更新前期准备耗时占用磁盘大大规模内网、长期维护自定义 RPM 目录源完全可控适合私有包需要自己管理依赖补丁包、自研软件、离线安装包3. CentOS 7 本地YUM源搭建实操ISO挂载、repo配置、验证与局域网共享3.1 快速挂载CentOS 7 ISO镜像并确认挂载结果先准备一个挂载目录然后把 ISO 挂上去。假设我把CentOS-7-x86_64-DVD-2009.iso放在了/opt目录下实际操作命令如下mkdir -p /mnt/cdrom mount -o loop /opt/CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom ls /mnt/cdrom/Packages | head -n 5 df -h /mnt/cdrom第一行创建挂载点第二行用 loop 方式挂载 ISO 文件。如果你用的是物理光驱而不是 ISO 文件可以把第二行换成mount /dev/cdrom /mnt/cdrom效果是一样的。执行完后ls /mnt/cdrom应该能看到Packages、repodata、images等目录。这里要特别确认一下repodata/repomd.xml是否存在因为 YUM 依赖这个文件识别仓库如果挂载后看不到它说明你挂的可能不是 DVD 镜像而是类似 boot 镜像的轻量 ISO。这里有两个细节值得注意。第一ISO 文件所在分区的文件系统不建议是 FAT32因为 CentOS 7 的 DVD 镜像体积接近甚至超过 4GBFAT32 单文件上限就是 4GB容易出现文件不完整或者无法拷贝的问题。第二重启之后挂载会失效如果你想长期使用最好写进/etc/fstab。我一般会加这样一行/opt/CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom iso9660 loop,defaults,nofail 0 0其中nofail参数的意思是即使开机的瞬间 ISO 文件路径不可用系统也不会卡在救援模式而是会继续正常启动。这个参数在实际运维中很关键尤其当源文件存放在数据盘上、开机时数据盘还没挂载好的情况下能避免很多麻烦。3.2 配置本地YUM源的核心参数repo文件逐行拆解ISO 挂载好之后YUM 并不会自动知道这个目录能用你必须告诉它。这就涉及centos7配置本地yum源的关键部分编写.repo文件。为了保证环境干净建议先把系统默认的 repo 文件全部备份到一个目录避免它们继续指向公网导致超时。mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/然后创建本地源文件cat /etc/yum.repos.d/local.repo EOF [local] nameLocal YUM Repository baseurlfile:///mnt/cdrom enabled1 gpgcheck0 EOF这里每一行都有讲究。[local]是仓库 ID必须全局唯一不能用中文不能有空格name只是描述性文字可以随意baseurl是仓库地址file://表示本地文件系统协议后面跟绝对路径也支持http://和ftp://enabled1表示启用这个仓库gpgcheck0表示不校验 RPM 包的 GPG 签名。对于本地 ISO 源我通常建议gpgcheck0因为挂载的目录里没有现成的公钥文件如果设置为 1执行安装时会报 “Public key for xxx.rpm is not installed” 的错误。如果你觉得不安全也可以从/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7导入官方公钥然后设置gpgcheck1并在 repo 文件里指定gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7。不过对于纯内网环境公钥保护和实际风险都要评估本地源用gpgcheck0是很普遍的做法。最关键的还是baseurl别写错file:///mnt/cdrom是三个斜杠少了就成了file:/mnt/cdromYUM 识别不了。3.3 清缓存、验证源是否生效的完整流程repo 文件写好后下一步就是让 YUM 重新加载元数据。顺序很重要yum clean all yum makecache yum repolistyum clean all先清空本地缓存的元数据防止旧数据残留。第 2 步yum makecache会连接baseurl并生成新的缓存如果仓库配置正确这一步能看到下载repomd.xml的进度。第 3 步yum repolist会列出当前所有启用的仓库以及仓库里可用的包数量。如果你看到的repo id是local、包数量是几千说明本地源已经生效。接下来用一个小工具做最终验证yum -y install vim装不上的话多半是baseurl路径、挂载状态或者repodata目录有问题。常见报错Cannot find a valid baseurl for repo: local/7/x86_64基本就是路径不对报错[Errno 14] curl#37 - Couldnt open file /mnt/cdrom/repodata/repomd.xml则说明挂载目录里没有repodata得回头检查挂载对不对。这个“清缓存、重建缓存、列仓库、装包”四步验证法我每次搭源都会走一遍不赶时间的话建议你也照做。3.4 让局域网其他机器也能用HTTP共享源配置方法单机可用只是第一步内网环境里通常需要让其他机器也用同一个源。最简单的方式是用 HTTP 共享。先在本机安装并启动httpdyum -y install httpd mkdir -p /var/www/html/centos mount --bind /mnt/cdrom /var/www/html/centos systemctl enable --now httpd firewall-cmd --permanent --add-servicehttp firewall-cmd --reload这里我建议用mount --bind而不是软链接。软链接虽然配置简单但在 SELinux 开启的环境里httpd访问软链接指向的只读挂载点很容易出现 403 Forbidden排查起来非常头痛。mount --bind相当于把挂载点再绑定到 web 目录下配合防火墙放行 80 端口客户端就能直接访问了。客户端机器上的 repo 文件也很简单把baseurl改成内网服务器地址即可cat /etc/yum.repos.d/remote-local.repo EOF [remote-local] nameRemote Local YUM Repository baseurlhttp://192.168.1.10/centos enabled1 gpgcheck0 EOF写完同样执行yum clean all yum makecache就能用。如果客户端访问报 403除了检查目录权限还可以在服务端临时执行setsebool -P httpd_use_fusefs 1这个参数能放行 httpd 读取 FUSE 或 loop 设备上的文件系统场景。如果你不想碰 SELinux也可以用 NFS 共享在服务端/etc/exports里增加一行共享目录客户端 mount 到本地后repo 文件继续用file:///mnt/nfsrepo效果也很好但前提是内网允许 NFS 协议。4. 进阶操作用createrepo构建自定义RPM目录源4.1 安装createrepo并准备RPM目录ISO 源能解决的问题很有限当你有自己收集的 RPM 包或者想让内网用户安装公司自研软件时就得用createrepo搭一个自定义源。这个工具的安装非常简单在光盘源或者联网正常的环境下执行yum -y install createrepo mkdir -p /data/yum/rpms然后把你手里的 RPM 包全部拷贝到/data/yum/rpms目录。这里我特别提醒一下不要把 RPM 包按业务分门别类放到一堆子目录里因为baseurl指向的仓库只会索引该目录第一层的 RPM 包子目录里的包不会被扫描到。如果你实在想分类就为每个子目录单独建一个仓库但那样客户端要配置多个baseurl维护成本高。我的习惯是保持一个平铺目录包名清晰、版本可控这样才能用最简单的方式维护。放好 RPM 包后执行createrepo /data/yum/rpms命令执行完目录里会多出一个repodata文件夹里面就是 YUM 需要的元数据。整个过程不需要联网生成时间取决于 RPM 包数量包多的时候可能要等几十秒。4.2 编写custom.repo并处理多仓库冲突自定义源创建好后跟 ISO 源一样还需要一个 repo 文件指向它cat /etc/yum.repos.d/custom.repo EOF [custom] nameCustom RPM Repository baseurlfile:///data/yum/rpms enabled1 gpgcheck0 EOF然后执行yum clean all yum makecache再用yum repolist查看。如果之前已经配置了 ISO 源现在系统里就会有两个仓库同时启用。大多数情况下多个仓库共存是好事YUM 会自动根据包的版本、架构和仓库顺序选择最合适的包。但如果不同仓库里有同名但不同版本的包而且你希望稳定安装某一个源里的版本可以用--disablerepo强制指定yum --disablerepo* --enablerepocustom install my-app这条命令只启用custom仓库其他仓库全部禁用非常干净。有的团队会装yum-plugin-priorities来配置仓库优先级这在多仓库混合环境下确实有用但我个人觉得如果不是特别复杂的环境没必要引入额外插件手动指定仓库已经足够。4.3 包更新后什么时候用--update什么时候全量重建createrepo建好仓库后不是一劳永逸的。每当你往/data/yum/rpms里追加新的 RPM 包或者删除了某些包客户端再执行yum makecache时依然看不到最新变化因为repodata还是旧的。这时候必须重新生成元数据。命令有两种用法createrepo --update /data/yum/rpms追加新包、更新同版本包时用--update就够它只增量更新元数据速度更快适合平时频繁加包的场景。但是如果你删除了目录里的某些旧 RPM或者大批量替换了包版本我建议直接跑一次全量createrepo /data/yum/rpms让它重新扫描并生成干净的元数据。我踩过坑删除旧包后只用了--update客户端yum list里偶尔还会看到旧包信息全量重建后问题就消失了。所以大变动之后别省那几十秒。这里再分享一个配合createrepo使用的好工具repotrack。它属于yum-utils可以在联网机器上把某个包和它的全部依赖一次性下载到指定目录。你可以在有外网的前置机上下载然后把整个目录拷入内网再用createrepo生成元数据。这样准备离线 rpm 集合的效率比手动一个个找依赖高出很多yum -y install yum-utils repotrack -p /data/yum/rpms nginx createrepo --update /data/yum/rpmsrepotrack -p指定输出目录后面跟你要下载的包名它会把 nginx 以及所有依赖包都拉下来。内网机器随后直接yum install nginx就能装上。不过要注意前置机的 CentOS 版本、架构一定要和 target 机器一致否则从 x86_64 机器上下载的包拿到 aarch64 机器上是装不上的。5. 常见问题与排查技巧实录内网YUM源不生效怎么办5.1 YUM源故障速查表我在内网搭源时遇到过不少问题有些问题看起来奇怪实际上原因就那么几个。整理成一张速查表方便你遇到报错时直接对号入座报错或现象可能原因解决方法Could not resolve host没有禁用默认公网 repo备份并移走 /etc/yum.repos.d/ 下的原 .repo 文件Cannot find a valid baseurl for repobaseurl 写错或仓库目录不存在检查 baseurl 路径确认 ISO 已正确挂载Couldnt open file /mnt/cdrom/repodata/repomd.xml挂载点目录里没有 repodata重新挂载 ISO确认是 CD/DVD 镜像而不是 boot 镜像HTTP 访问报 403httpd 没有权限读取挂载目录改用 mount --bind 绑定到 web 根目录或调整 SELinux客户端 makecache 后包数量为 0repo 文件未启用或 baseurl 不可达执行yum repolist确认仓库是否被识别看 URL 是否通新加的 RPM 客户端看不到没有重新生成元数据执行createrepo --update /data/yum/rpmsPublic key for xxx.rpm is not installedgpgcheck1 但没导入公钥临时改为 gpgcheck0或导入对应 GPG key两个仓库提供同版本包装错源仓库优先级不明确用yum --disablerepo* --enablerepoxxx install指定这张表只是常规问题实际内网环境还可能遇到磁盘空间不足、防火墙没放行、客户端架构不一致等问题。排查顺序我建议先看 repo 文件、再看挂载/HTTP 是否可访问、最后看元数据是否最新一步一步来别慌。5.2 几个容易被忽略的坑除了上面那些报错还有几个“不是报错但很坑”的细节。第一个就是原 repo 文件的残留。有的人只是在 /etc/yum.repos.d 下新增了一个 local.repo没有禁用原来的 CentOS-Base.repo结果每次 yum 操作都会先去连接公网内网环境里光等超时就能等几分钟。最彻底的办法就是像我前面说的把所有默认 repo 移到 backup 目录只保留自己的源。第二个坑是挂载点权限和目录权限。如果你用 HTTP 共享网站根目录下的文件对httpd用户必须可读。单纯chmod -R 755有时候解决不了 SELinux 的拦截尤其当你的仓库目录是通过mount --bind从只读 ISO 挂载点绑过去的时候。遇到 403优先看/var/log/httpd/error_log确认是权限问题还是 SELinux 问题再用对应的setsebool或者chcon处理。很多教程直接让你setenforce 0那是对安全很不负责的行为生产环境千万别这么干。第三个坑是客户端缓存。有时候你要给客户端安装一个新的包但客户端之前已经makecache过了YUM 默认会有metadata_expire缓存时间导致它一直看不到仓库里的新包。这时候让客户端执行yum clean all yum makecache就能解决。还有如果内网环境时间不准某些使用 HTTPS 协议的仓库会报证书错误你用纯 HTTP 源一般没有这个问题但依然建议把内网机器的 NTP 时间同步好省很多麻烦。最后再分享一个小技巧如果只是临时给一两台机器装软件挂载 ISO 源就够了但如果这个内网环境要长期被很多人使用建议把“HTTP 共享 createrepo 自定义源”这套流程固化下来。我维护的内网源就是先用 ISO 做基础源再单独加一个 custom 源放补丁包和自研包日常运维基本没再为装软件发过愁。搭过一次之后你也会发现所谓内网离线环境只是在等一个真正可用的本地 YUM 源而已。
返回列表