ARTICLE DETAIL

资讯详情

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

openEuler离线环境本地yum仓库搭建与内网共享实践

openEuler离线环境本地yum仓库搭建与内网共享实践 1. 为什么离线环境还得自己搭yum仓库openEuler 22.03 LTS SP1默认的yum源指向官方公网镜像网络通畅的时候yum install确实是直连官方源就完事。可实际项目里大量生产机器的部署环境是物理隔离机房或者专网服务器根本没有公网出口甚至内网DNS都不一定好使。这时候你要在几十台甚至上百台openEuler上装个gcc、装个nginx每台机器都手动下载rpm包再rpm -ivh硬装依赖关系会把你折腾到怀疑人生。yum的价值不在于它是个软件下载器而在于它能把依赖解析这件事自动化。你只要告诉它我要装nginx它会自己去仓库里把主包、依赖包、子包全部拉下来顺序装好。所以把yum源从公网搬到本地或者内部网络是所有离线环境用openEuler逃不开的基础工程。这篇文章就围绕本地和内部两个场景展开本地单机怎么快速建源内网多台机器怎么共用一套仓库。附带讲一下自建rpm仓库和日常维护的坑。1.1 没有外网时服务器怎么装软件假设你手头有五台openEuler服务器都在一个物理隔离的网络里。没有公网出口没有镜像站连yum默认源都连不通。最原始的办法是在一台有外网的机器上把所有需要的rpm包下载好打成压缩包拷进内网然后逐台rpm -ivh。听起来可行但一旦涉及复杂软件依赖关系就是一棵树。你要装一个text browser类的软件可能还简单装nginx、装数据库、装编译工具链时依赖包可能牵扯到几十个甚至上百个底层包。手动搜集依赖包的版本、来源、父子关系几乎等于重新发明一遍yum。而本地yum仓库做的事情就一句话把所有rpm包放进一个目录用createrepo生成元数据让每台机器把它当成一个yum源。之后在这些离线机器上使用yum install体验和在线几乎没有区别依赖自动解析、自动下载、自动安装。这个过程就是对公网yum源的一次本地化迁移。1.2 ISO自带repo与自建仓库的差别openEuler 22.03 LTS SP1的安装ISO里自带了一个软件仓库里面收录了不少常用软件包。把ISO挂载起来指向对应的挂载路径就能当一个本地源用。这种方案最大的好处是零成本、零准备时间系统装完手里有ISO就能立刻用。但ISO源有天然限制收录范围有限很多东西不进DVD镜像。你要装一个比较冷门的开发库或者需要较新的软件版本ISO里大概率没有。另一个问题是ISO源是静态的不会跟着官方仓库更新存在安全漏洞的软件版本你不得不自己想办法解决。所以我的建议是一两台机器临时应急挂ISO完全足够生产集群或者长期维护的环境老老实实搭一个内部HTTP仓库把openEuler官方源中需要的内容同步下来定期更新。而且两类仓库完全可以共存ISO源用于系统安装后的基础环境搭建HTTP源用于日常软件安装和补丁获取。2. 动手前需要知道的基础信息2.1 openEuler 22.03 LTS SP1的仓库路径结构openEuler的版本命名有自己的规矩22.03 LTS表示2022年3月发布的长期支持版本SP1是它的第一个维护补丁版本。和CentOS/RHEL系列类似openEuler的仓库也按架构和子仓库划分但细节上有明显差异。官方仓库地址大致长这样https://repo.openeuler.org/openEuler-22.03-LTS-SP1/OS/x86_64/ https://repo.openeuler.org/openEuler-22.03-LTS-SP1/everything/x86_64/ https://repo.openeuler.org/openEuler-22.03-LTS-SP1/EPOL/x86_64/ https://repo.openeuler.org/openEuler-22.03-LTS-SP1/debuginfo/x86_64/ https://repo.openeuler.org/openEuler-22.03-LTS-SP1/source/日常使用中OS和everything是最常用的两个子仓库OS体积小但包数量不多everything覆盖范围大得多。EPOL是各种SIG特别兴趣小组维护的扩展包里面有不少官方主干之外的工具链和软件比如一些高版本编译器、运行时环境。debuginfo和source按需同步即可不需要的时候别去碰特别占空间。还有一点要留心openEuler的Arm架构aarch64和x86_64架构仓库路径只是体系架构名称不同。如果你在鲲鹏服务器上部署所有路径中的x86_64全部替换成aarch64。别拿x86_64的包在aarch64上用yum虽然不会明着拒绝但装完大概率跑不起来。2.2 需要使用的工具和检查命令开始之前先确认机器上有没有必要的工具。openEuler默认自带了yum和dnf两者底层一脉相承repo文件格式完全通用。createrepo用于生成仓库元数据nginx或httpd用于把仓库目录暴露成HTTP服务。如果系统里还没装在ISO仓库可用的情况下直接安装cat /etc/openEuler-release uname -m yum --version yum install -y createrepo nginx我个人习惯先看一遍基础信息再动手避免后续命令因为架构不匹配或者版本差异翻车。下面这组检查命令可以照抄# 查看系统版本 cat /etc/openEuler-release # 查看CPU架构 uname -m # 查看yum版本 yum --version # 查看createrepo和nginx是否已安装 rpm -qa | grep createrepo rpm -qa | grep nginx确认工具就绪后就可以按方案搭建了。3. 最应急的方案挂载ISO做单机本地源有时候你手上只有一台刚装好的openEuler服务器既没外网也没内网源唯一的软件资源就是那张家底ISO。先别急着到处找包把ISO挂载成yum源是最快解决手痒装包问题的办法。3.1 挂载ISO镜像并设置开机自动挂载先把ISO文件上传到服务器某个目录比如/data/iso/。然后建立挂载点用mount命令挂载mkdir -p /mnt/openeuler-iso mount -o loop /data/iso/openEuler-22.03-LTS-SP1-x86_64-dvd.iso /mnt/openeuler-iso挂载完成后第一时间确认一下ISO里有没有repodata目录ls /mnt/openeuler-iso/repodata有repodata目录就说明ISO自带仓库元数据yum可以直接把挂载路径当成源用不需要额外执行createrepo。这里有个细节如果机器重启手动挂载会失效。要保证重启后还能用得写进/etc/fstab/data/iso/openEuler-22.03-LTS-SP1-x86_64-dvd.iso /mnt/openeuler-iso iso9660 loop,ro 0 0写完fstab后建议执行mount -a测试一下确保路径和设备都正确。有人喜欢用/dev/sr0这种光驱设备名但服务器上可能会插多块光驱或者虚拟光驱设备名不一定固定用ISO文件路径加loop挂载最稳定。3.2 编写repo配置文件并替换默认源openEuler的yum仓库配置文件都放在/etc/yum.repos.d/目录下。系统装完默认会生成openEuler.repo里面配置的是官方公网地址。为了保证本地源优先同时不污染原配置我建议把官方源文件重命名备份再新建一个local.repocd /etc/yum.repos.d/ mv openEuler.repo openEuler.repo.bak vim local.repolocal.repo内容如下[local-iso] nameopenEuler 22.03 LTS SP1 Local ISO baseurlfile:///mnt/openeuler-iso enabled1 gpgcheck0这里直接把gpgcheck设为0原因是ISO源面向单机可信环境省掉公钥配置环节最不容易出问题。如果你对安全有强迫症也可以开gpgcheck并在repo文件里指定gpgkey路径[local-iso] nameopenEuler 22.03 LTS SP1 Local ISO baseurlfile:///mnt/openeuler-iso enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler但注意用gpgcheck1时系统里必须已经有对应的RPM公钥文件。先rpm --import导入公钥再执行yum操作否则会报GPG key检索失败。3.3 清缓存、建缓存、验证仓库可用写完之后固定三连操作yum clean all yum makecache yum repolistrepolist输出中能看到local-iso仓库并且包数量不是0说明ISO本地源已经正常工作。接着装个包验证一下yum install -y tree如果tree正常装上说明本地源完全可用。到这里你已经有了一台可以离网安装基础软件的openEuler机器。但这个方案只有一台机器受益下一步就是把仓库对外服务化做成内部网络共用的yum源。4. 多机共用的核心方案Nginx搭建内部HTTP仓库单机挂ISO只是应急手段。管理和维护几十台服务器时更合适的做法是把仓库集中在一台仓库服务器上用Nginx提供HTTP服务所有客户端通过网络访问。好处很明显版本统一、更新集中、权限可控客户端不用再为从哪拿包操心了。4.1 设计仓库目录结构并同步官方源仓库服务器上我习惯建这样的目录结构/data/yum/ └── openEuler-22.03-LTS-SP1 ├── OS │ └── x86_64 ├── everything │ └── x86_64 └── EPOL └── x86_64目录准备好后内容怎么填进去是关键。如果仓库服务器能访问外网最省事的是用rsync把官方源整个同步下来。以下三个目录是日常必须的rsync -avz --delete rsync://repo.openeuler.org/openEuler-22.03-LTS-SP1/OS/x86_64/ /data/yum/openEuler-22.03-LTS-SP1/OS/x86_64/ rsync -avz --delete rsync://repo.openeuler.org/openEuler-22.03-LTS-SP1/everything/x86_64/ /data/yum/openEuler-22.03-LTS-SP1/everything/x86_64/ rsync -avz --delete rsync://repo.openeuler.org/openEuler-22.03-LTS-SP1/EPOL/x86_64/ /data/yum/openEuler-22.03-LTS-SP1/EPOL/x86_64/--delete参数要谨慎使用它的作用是让本地和远端完全一致本地多出来的文件会被删除。如果你在本地目录放了自己的额外rpm包加了--delete之后这些文件会被清理掉。第一次同步建议不加--delete后面做周期性更新时再加。如果外网带宽有限有个折中方案只同步repodata和最近更新的rpm但这里有个非常隐蔽的坑——你只拷贝部分rpm而repodata里的元数据是全量的yum安装时会把元数据里记录的所有包当成可选包一旦你选的包没有实际文件yum直接报错。所以要么老老实实全量同步要么干脆不要用远程的repodata同步后用createrepo重新生成一份只含本地rpm的元数据方法见第5节。4.2 配置Nginx对外开放仓库仓库内容就位后用Nginx把/data/yum目录暴露成HTTP服务。openEuler装Nginx非常顺利直接yum install -y nginx即可。配置文件通常位于/etc/nginx/nginx.conf我习惯在http块里新增一个server块单独服务仓库server { listen 80; server_name repo.internal; root /data/yum; autoindex on; autoindex_exact_size off; autoindex_localtime on; location / { index index.html; } }autoindex on这行很关键没有它浏览器访问仓库目录时看不到文件列表虽然yum客户端不受影响但你在排查问题时少了一个直观的辅助手段。启动Nginx并设置开机自启systemctl enable nginx --now systemctl status nginx同时在防火墙上确认80端口被放行firewall-cmd --permanent --add-servicehttp firewall-cmd --reload如果服务器有SELinux开启Nginx默认只能读取/usr/share/nginx/html目录下的文件访问/data/yum可能报403 Permission denied。最简单的处理是把SELinux设为宽松模式或者给/data/yum目录设置正确的httpd_sys_content_t上下文。生产环境不建议直接关闭SELinux我一般用semanage和chcon把仓库目录的SELinux类型改过来yum install -y policycoreutils-python-utils semanage fcontext -a -t httpd_sys_content_t /data/yum(/.*)? restorecon -Rv /data/yumSELinux的问题常见但容易被忽略如果Nginx日志里频繁出现Permission denied大概率就是它拦的。4.3 客户端repo配置与缓存验证仓库服务器部署完成后所有客户端写一个统一的repo文件。假设仓库服务器内网IP是192.168.10.10那客户端的/etc/yum.repos.d/internal.repo内容这样写[internal-os] nameopenEuler 22.03 LTS SP1 OS baseurlhttp://192.168.10.10/openEuler-22.03-LTS-SP1/OS/x86_64/ enabled1 gpgcheck0 [internal-everything] nameopenEuler 22.03 LTS SP1 everything baseurlhttp://192.168.10.10/openEuler-22.03-LTS-SP1/everything/x86_64/ enabled1 gpgcheck0 [internal-epol] nameopenEuler 22.03 LTS SP1 EPOL baseurlhttp://192.168.10.10/openEuler-22.03-LTS-SP1/EPOL/x86_64/ enabled1 gpgcheck0然后清缓存、建索引、验仓库yum clean all yum makecache yum repolistmakecache正常后yum会显示从internal-os、internal-everything、internal-epol三个仓库成功创建缓存。如果报错参考第6节的排查思路。5. 两个高频扩展需求离线下载rpm包和自建rpm仓库正式的仓库搭完后运维工作会催生出两个衍生需求一是临时需要某个软件如何快速把包带进内网二是内部开发的rpm包怎么变成一个标准yum仓库。这两个需求都绕不开yum-utils和createrepo。5.1 用yumdownloader批量下载rpm包及其依赖有一台能访问公网的跳板机时批量下载rpm包最常用的工具是yumdownloader它属于yum-utils包yum install -y yum-utils比如要把nginx及其所有依赖包下载到/data/rpms目录yumdownloader --resolve --destdir/data/rpms nginx--resolve是关键参数它会自动分析依赖并连同依赖包一起下载不输这个参数的话只下载主包本体拷进内网后照样缺依赖。下载完成后把整个目录拷进内网。如果只是临时给一两台机器用可以直接在客户端把/data/rpms配置为一个file源如果希望长期使用把它合并进正式仓库是最佳选择。这里还要提一下repoquery它和yumdownloader是黄金搭档。搭仓库或者梳理依赖时先用repoquery查看某个包的依赖清单心里有数了再下载。示例repoquery --requires nginx repoquery --list nginx5.2 用createrepo把rpm目录变成真正的仓库不管是从公网下载的一批rpm还是你要发布的内网开发包只要这些rpm在同一个目录下createrepo就能把它们变成标准yum仓库。操作步骤如下mkdir -p /data/custom-rpms # 把rpm文件放入该目录 cd /data/custom-rpms createrepo .createrepo执行后目录下会出现repodata子目录里面是repomd.xml和各类元数据文件。这就标志着一个标准yum仓库被创建出来了。之后只要向目录中添加了新的rpm包重新执行一次增量更新createrepo --update /data/custom-rpms--update参数只会重新扫描有变动的部分不会从头构建整个元数据速度会快很多。这个操作几乎是我每次往内网仓库丢新包时必执行的命令。有个坑必须强调单独把一个rpm文件丢进目录不执行createrepo只执行yum clean all和yum makecacheyum依然找不到这个包。原因很简单——yum客户端读的是repodata里的索引信息不是直接扫目录里的文件。没有重新生成元数据之前一切刷新缓存都是徒劳。6. 搭建和运行中的典型故障与处理流程内部yum仓库本身不难搭可运行过程中总是能碰到一些让人头疼的问题。我把实际踩过的坑按故障链路整理出来按照这个顺序排查多数问题都能定位。6.1 yum makecache报错Metadata下载失败的完整排查链路这是一类高频报错提示大概长这样Errors during downloading metadata for repository internal-os: - Status code: 404 for http://192.168.10.10/openEuler-22.03-LTS-SP1/OS/x86_64/repodata/repomd.xml第一反应先别动yum直接在客户端用curl模拟访问元数据文件curl -I http://192.168.10.10/openEuler-22.03-LTS-SP1/OS/x86_64/repodata/repomd.xml如果返回404问题在路径或Nginx配置。分几步查第一步确认Nginx的root配置是否正确。root /data/yum时访问http://IP/openEuler-22.03-LTS-SP1/OS/x86_64/repodata/repomd.xml对应的实际路径是/data/yum/openEuler-22.03-LTS-SP1/OS/x86_64/repodata/repomd.xml。任何一级目录名的大小写和真实目录不一致都会404。第二步确认仓库服务器本地是否真的存在repodata目录。用ls命令逐级检查某些时候你同步了rpm包但忘了同步repodata或者同步时漏了repomd.xml元数据自然不完整。第三步检查Nginx的server配置有没有set root/alias混淆。有人会在location里写alias导致路径拼接多了一层这种问题看curl返回的URL是拼出的404还是403就能追踪。如果curl返回200那就是yum缓存问题按下面的方式处理比较稳妥yum clean all yum makecache6.2 gpg校验错误公钥导入和gpgcheck冲突如果repo文件里写的是gpgcheck1但客户端没有导入对应公钥yum install时常见的报错是Public key for xxx.rpm is not installed解决方案有两个选一个都行。一是直接关闭gpgcheck内网仓库通常可信这个代价最低二是把openEuler官方公钥导入客户端rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-openEuler注意openEuler 22.03 SP1的公钥文件名可能不是这个先看一下目录里实际存在什么ls /etc/pki/rpm-gpg/到了这步你可能会问我repo文件里明明没开gpgcheck为什么还校验因为rpm包自己的包头里嵌了签名信息yum默认行为可能会校验。如果实在想彻底绕开可以在repo文件里加一行gpgcheck0同时确认没有其他repo文件里开启了全局gpgcheck比如/etc/yum.conf里如果设了gpgcheck1会影响到所有repo。排查时要多个配置文件一起看。6.3 修改repo配置后不生效缓存残留与配置残留这是最高频的隐形坑。只改了repo文件里的baseurl没执行yum clean allyum还是会用旧cache里的元数据表现就是明明改了源装的还是老版本包。我给自己定了一个固定流程改任何repo文件后必须执行yum clean all yum makecache yum repolist一次不落。这个三连操作基本能消除绝大多数改动不生效问题。另外如果多个repo文件里存在相同的仓库ID写在后面的会覆盖前面的。比如旧的openEuler.repo里定义了[OS]这个ID新的internal.repo里也定义了[OS]那ID重复了yum只会用其中一个。所以新建repo文件前最好grep一下原文件列表里的repo IDgrep -h ^\[ /etc/yum.repos.d/*.repo看到重复ID就顺手改掉。这种排查思路比较实用遇到仓库明明配了却显示不出来时第一反应就应该是查ID冲突。6.4 客户端访问慢和网络层面优化内网100台机器同时yum makecache时仓库服务器会瞬间被打满。这种情况下我通常做几件优化第一客户端repo文件里加metadata_expire参数[internal-os] nameopenEuler 22.03 LTS SP1 OS baseurlhttp://192.168.10.10/openEuler-22.03-LTS-SP1/OS/x86_64/ enabled1 gpgcheck0 metadata_expire1d这样客户端在一天内不会反复拉取元数据对批量执行任务有很大改善。如果希望更快响应也可以设成6h或者更短看你的更新频率。第二Nginx开启gzip压缩。多数环境中rpm包本身是压缩格式再开gzip意义不大但repodata里的xml数据没有压缩开启gzip可以明显减小传输量。在nginx.conf的http块里加上gzip on; gzip_types application/xml text/plain text/css application/javascript;第三如果集群规模很大可以考虑让仓库服务器挂SSDmetadata文件是小文件磁盘随机读取性能对并发访问的影响很直接。这是很多运维容易忽略的地方系统盘不够快几十台机器同时makecache能把IO拖垮。7. 实际维护的几点体会仓库搭好只是开始真正考验运维耐心的是后续的持续跟进。我个人的维护习惯是这样的基础系统安装阶段第一台机器用ISO源保证基础工具链就绪后续所有机器统一走HTTP内部源。每周末同步一次everything和EPOL确保安全补丁不会滞后太多。同步用的rsync命令写成计划任务自动执行并在执行后自动createrepo --update。这样大多数时间仓库都在自动更新我只需要定期瞄一眼日志和磁盘占用。磁盘规划上everything仓库加EPOL镜像完整的x86_64内容大约需要几十GB到上百GB不等具体取决于官方仓库的增长速度。如果磁盘紧张可以把debuginfo和source目录排除掉日常装软件用不到同步它们纯粹浪费空间。还有一件小事很容易被忽视给仓库服务器配置一个稳定的内网DNS记录。客户端repo文件里统一用主机名仓库地址而不是裸IP。否则哪天仓库服务器要换IP你得一台台改所有客户端的repo文件100台机器改下来会非常痛苦。用主机名的话只需要在DNS或者各台机器的/etc/hosts里改一行。再有就是养成看Nginx访问日志的习惯。偶尔翻一下/var/log/nginx/access.log能看到哪些客户端在持续拉取失败哪些地址访问了不存在的路径。这些信号往往能在问题变严重之前提醒你。内部yum仓库本质上是一个软件供应链节点维护它的核心不是搭建那一刻的操作而是后续系统化、自动化地保持内容新鲜和可用。把这些基本功做扎实了后面所有基于openEuler的应用交付才会省心。
返回列表