ARTICLE DETAIL

资讯详情

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

银河麒麟内网离线软件源搭建指南:APT与YUM本地仓库实战

银河麒麟内网离线软件源搭建指南:APT与YUM本地仓库实战 前阵子帮人处理一台银河麒麟V10系统装好了结果是个纯内网环境外网完全不通。现场要装数据库客户端apt update直接报“无法解析地址”朋友第一反应是没网是不是就装不了软件了当然不是。问题本质是软件安装的“货源”断了解决思路很简单自己在电脑里搭一个本地软件源把APT或YUM的仓库搬到内网来相当于给机器内置了一个“软件应用商店”。这篇我把自己实际操作过的离线软件源搭建流程完整写出来包括APT、YUM两种方式适合所有银河麒麟桌面版和服务器版用户以及Ubuntu、CentOS系Linux离线环境的管理员参考。1. 没有网络时装软件为什么这么费劲1.1 先分清楚你的银河麒麟是“哪个派系”很多人在这一步就栽了。银河麒麟V10不是一个“版本”走天下它分桌面版和服务器版包管理体系完全是两套银河麒麟桌面版Kylin Desktop V10基于Ubuntu使用apt命令软件包格式是.deb。银河麒麟服务器版Kylin Server V10早期版本基于CentOS/RHEL使用yum命令后续SP2、SP3版本开始转向dnf软件包格式是.rpm。判断方法很简单登录系统后执行cat /etc/os-release which apt which yum which dnf如果apt存在走APT方案如果yum或dnf存在走YUM方案。千万不要在桌面版上硬塞rpm包或者在服务器版上硬塞deb包架构都不同后面全是坑。这也是为什么网络上“银河麒麟安装软件命令”搜出来一堆互相矛盾的结果——大家说的根本不是同一个系统分支。1.2 软件依赖是离线安装最大的坎假设你手里已经有一个软件的deb包比如nginx.deb能不能直接双击或dpkg -i nginx.deb装上大概率不行。因为Linux软件不是孤立的它运行时要依赖一堆底层库libc6、libssl、zlib等系统里没有这些库或版本不对安装就会中断。举个例子装一个编译工具链gcc它的依赖可以拉出一长串binutils、cpp、libgcc-*-dev、libc6-dev、make、perl等等。手动在U盘里找这些包再一个个dpkg -i不是不能做而是指数级地痛苦。更别提有些依赖还有自己的依赖形成了“连环锁”。apt和yum这类包管理器的核心价值就是自动解析这个依赖链并按照正确的顺序把所有包一次装好。但前提是它必须知道“去哪里找这些包”。这个“去哪里找”就是软件源repository配置。1.3 本地软件源到底解决了什么问题把apt、yum比作“购物车”把软件源比作“超市仓库”。你平时执行apt install xxx实际上是去网络上配置好的源地址比如银河麒麟官方镜像站找到软件并下载安装。离线环境下这个“仓库”断了。本地软件源做的事情很简单把仓库目录原封不动搬到本机让apt或yum把本机目录当作“货源”。这样做有两个明显好处包管理器仍然能做依赖解析不需要手动挨个装包。所有包集中在本地安装速度快不依赖网络波动。所以哪怕你只是临时离线装一个软件也建议配一次本地源而不是手动dpkg -i。一劳永逸。2. 软件源的工作逻辑它凭什么能找到包2.1 APT源的结构一个标准的Debian/Ubuntu系软件源通常包含两个核心部分pool目录存放真正的.deb软件包文件。dists目录存放软件的索引和元数据比如Packages.gz、Release等。当你在/etc/apt/sources.list里看到一行deb http://mirrors.example.com/kylin V10 main universeapt update会去该地址下载对应的Packages.gz索引文件这个索引里记录了“这个仓库有哪些包、版本号多少、依赖什么、包文件相对路径是什么”。然后你执行apt install时apt根据索引找到包的具体路径下载并安装。所以APT源的灵魂是索引文件。如果目录里只有deb包、没有索引apt就完全不知道这些包存在。2.2 YUM源的结构YUM源的结构类似但它把索引统一放在repodata目录里repodata/repomd.xml仓库元数据入口。repodata/*-primary.xml.gz所有rpm包的名称、版本、依赖关系、文件列表。yum makecache做的就是下载并解析这些元数据。createrepo命令的作用就是为指定目录生成repodata。所以搭建YUM本地源关键动作只有一个把rpm包收集到一个目录然后在该目录执行createrepo生成索引。2.3 本地源只是换个“下载地址”理解这层逻辑后本地源就没什么神秘的了。所谓“本地源”就是在配置里把软件的获取地址从http://换成file://指向你本机的某个目录。对APT来说写法是deb [trustedyes] file:///opt/kylin-apt ./对YUM来说写法是baseurlfile:///opt/kylin-yum包管理器会把这个目录当作“服务器”读取索引、下载包、解析依赖流程和联网时完全一样。还有一点必须强调即使包就在本机目录也必须先生成索引。没生成Packages.gz或repodata之前哪怕目录里躺着几百个deb/rpm包apt install或yum install的结果依然是“找不到软件包”。3. 联网机器上准备把包和依赖一次带全3.1 确认系统版本和架构别带错“货”下载软件包前首先要搞清楚两台机器的“门派”和“架构”查看系统版本cat /etc/os-release查看CPU架构uname -m。x86_64对应amd64aarch64对应arm64。x86架构的机器不能安装arm64的包aarch64的机器也不能安装amd64的包。下载时一定要注意。另外最好在另一台与离线机同版本、同架构的联网机器上下载软件包。比如离线机是银河麒麟V10 SP1aarch64就在同版本SP1aarch64的联网机上准备包。不然依赖库如glibc版本不一致拷贝过来也装不上。3.2 APT系机器下载方法如果你的软件源是APT系银河麒麟桌面版用apt-get的--download-only参数最省心sudo apt-get clean sudo apt-get update sudo apt-get install --download-only 软件包名命令执行后它会把软件包以及所有依赖的deb包下载到本机缓存目录/var/cache/apt/archives/但不会安装。注意apt-get clean先清空缓存是为了确保下载的是本次的完整依赖集不含历史遗留。把缓存里的包都拷出来mkdir -p ~/offline-debs sudo cp /var/cache/apt/archives/*.deb ~/offline-debs/ tar czvf offline-debs.tar.gz ~/offline-debs/如果只想下载某一个包、不要依赖可以用apt download 软件包名但这种情况容易漏依赖建议还是用--download-only一次性把依赖树拉全。3.3 YUM系机器下载方法YUM系银河麒麟服务器版有两个常用方法。方法一是yumdownloader需要先安装yum-utilssudo yum install -y yum-utils mkdir -p ~/offline-rpms sudo yumdownloader --resolve --destdir~/offline-rpms 软件包名--resolve参数很关键表示同时下载所有依赖包。方法二是--downloadonlysudo yum install --downloadonly --downloaddir~/offline-rpms 软件包名在CentOS 7和部分老版本麒麟系统上yum install默认不支持--downloadonly需要额外安装插件sudo yum install -y yum-plugin-downloadonly如果用的是dnfRHEL8/9系或新版本麒麟服务器版命令写成sudo dnf install --downloadonly --downloaddir~/offline-rpms 软件包名下载完同样打包带走。不要用yum install直接装到联网机器上除非你本来就要在那台机器装这个软件。3.4 其他两种思路整仓镜像和缓存代理如果离线环境的规模很大要装几十上百个软件可以放弃“按软件下载”的思路直接在联网机器上拉取整个软件源镜像。APT系可以用apt-mirror工具YUM系可以用reposync工具。这类方案生成的目录结构完整可以直接作为本地源使用。还有一种半离线方案apt-cacher-ng或squid缓存代理。局域网里放一台能联网的机器做代理其他离线机器把软件源地址指向代理机第一次下载时缓存之后局域网内其他机器安装同样的软件就直接读缓存。这种方式适合“机器多、前期能联网、后期断网”的场景。不过说实话实际项目里最常用的还是“按软件下载”的方案。因为离线环境的软件需求通常明确几十个包已经足够覆盖绝大多数场景。把几百GB的完整仓库镜像拷进内网一是拷贝成本高二是很多内网机器根本不缺整个仓库只要常用软件齐就行。4. APT本地源搭建实操从deb包到可用的“商店”4.1 建立目录并导入deb包把前面从联网机器上拷贝出来的deb包放到离线机器上我习惯统一放到/opt/kylin-apt目录sudo mkdir -p /opt/kylin-apt cd /opt/kylin-apt sudo cp /path/to/offline-debs/*.deb ./这里建议把所有deb包平铺在这个目录下不要建子目录。dpkg-scanpackages默认不会递归扫描子目录如果包分散在各个子目录里会导致索引不全。如果在拷贝过程中遇到文件名乱码或后缀不是.deb的情况先检查一下文件是否传全尤其是用了FAT32格式U盘时可能会丢文件。4.2 生成Packages索引APT本地源最重要的一步就是生成Packages.gz索引文件。需要用dpkg-scanpackages命令它属于dpkg-dev包sudo apt install dpkg-dev如果离线机上没有这个命令只能回到联网机器上下载dpkg-dev及其依赖包拷贝过来安装。实际操作中我建议在联网准备阶段就把dpkg-dev也一起下载好避免到了离线环境抓瞎。执行生成命令cd /opt/kylin-apt sudo dpkg-scanpackages . /dev/null | gzip Packages.gz解释一下这两个参数.扫描当前目录下所有deb包。/dev/null表示不使用override文件。override文件通常用于仓库维护本地源完全不需要。执行完会在/opt/kylin-apt下生成一个Packages.gz文件。这个文件就是APT的“商品目录”。以后每次往目录里新增或删除deb包都要重新执行一次这条命令否则apt读到的还是旧索引。4.3 配置本地apt源银河麒麟桌面版默认的软件源配置在/etc/apt/sources.list和/etc/apt/sources.list.d/目录下。建议新建一个独立的配置文件sudo vi /etc/apt/sources.list.d/local-apt.list写入以下内容deb [trustedyes] file:///opt/kylin-apt ./这行配置的含义我再拆一下deb表示这是一个二进制软件源。[trustedyes]跳过GPG签名验证。因为本地目录里的包没有经过官方签名不加这个参数apt会提示NO_PUBKEY或At least one invalid signature was encountered拒绝读取。file:///opt/kylin-apt指向本机目录。./告诉apt这是一个“扁平仓库”索引文件Packages.gz直接放在这个目录下。建议把原来的网络源配置文件暂时重命名比如.bak后缀不然离线环境下apt update可能会卡在联网源上浪费大量时间sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak也可以只保留本地源文件把其他文件都移走。4.4 更新源并安装验证配置完成后执行sudo apt update正常情况下输出中会看到类似Get:1 file:/opt/kylin-apt ./ Packages随后执行安装测试sudo apt install 软件包名apt会从本地源读取索引、找到包、解析依赖并安装。整个流程和联网时没有任何区别只是数据通道从http变成了file。如果apt update报错或找不到包先检查三步目录里有没有Packages.gzsources.list里的路径是否和目录一一对应[trustedyes]有没有漏写。5. YUM本地源搭建实操从rpm包到可用的“商店”5.1 建立目录并导入rpm包YUM方案的目录同样建议用独立位置sudo mkdir -p /opt/kylin-yum cd /opt/kylin-yum sudo cp /path/to/offline-rpms/*.rpm ./rpm包同样建议平铺。有些管理员习惯把rpm包按子目录分类存放但传统createrepo不会递归扫描所有子目录平铺最稳妥。如果rpm包数量特别大也可以保持原有镜像目录结构但对应的createrepo命令和baseurl都要跟着调整新手不建议尝试。5.2 用createrepo生成仓库元数据YUM本地源的核心动作是执行createreposudo yum install -y createrepo sudo createrepo /opt/kylin-yum执行后会在/opt/kylin-yum目录下生成repodata子目录里面就是repomd.xml和各种元数据文件。这一步等同于APT的dpkg-scanpackages没有它yum同样“不认账”。后续如果往目录里新增了rpm包不需要重新全量扫描用增量模式更快sudo createrepo --update /opt/kylin-yum--update会只扫描新增或变更的rpm包在大仓库场景下能省不少时间。5.3 配置本地yum源在/etc/yum.repos.d/目录下新建一个repo文件sudo vi /etc/yum.repos.d/local.repo写入[local] nameKylin Local Repo baseurlfile:///opt/kylin-yum enabled1 gpgcheck0参数说明[local]仓库ID唯一即可。baseurlfile:///opt/kylin-yum本地仓库路径注意是file://后面接绝对路径。enabled1启用这个仓库。gpgcheck0跳过GPG签名校验。本地rpm包通常没有经过官方签名如果不关闭校验yum拒绝安装。这里有一个经常踩的坑机器上可能默认存在多个网络源配置文件比如CentOS-Base.repo或麒麟官方的repo。离线环境下这些网络源无法访问yum makecache会卡在连接超时上。建议把不需要的repo文件移走cd /etc/yum.repos.d/ sudo mkdir backup sudo mv *.repo backup/ sudo cp local.repo ./只保留本地源yum的缓存刷新就会很快。5.4 更新缓存并安装验证执行sudo yum clean all sudo yum makecache sudo yum install 软件包名yum clean all清掉旧缓存yum makecache重新构建基于本地源的缓存。安装时yum会读取repodata自动解析依赖并安装。如果是dnf命令等价替换为sudo dnf clean all sudo dnf makecache sudo dnf install 软件包名6. 排错与经验我在搭源过程中踩过的坑6.1 明明有deb包apt install却找不到这是APT本地源最常遇到的问题。现象是/opt/kylin-apt下全是deb包但apt install提示“E: 无法定位软件包”。排查顺序确认Packages.gz是否存在如果不存在说明dpkg-scanpackages没执行成功。确认sources.list里的路径是否和Packages.gz实际所在目录一致。确认是不是多个源并存本地源被网络源的报错干扰。把其他源暂时禁用。确认[trustedyes]是否写上签名问题会导致源被完全忽略。6.2 yum makecache卡住或报错最典型的是提示Could not retrieve mirrorlist原因是/etc/yum.repos.d/下还残留着网络源。解决办法就是前面提到的把网络repo文件移走只保留本地repo文件。还有一种情况yum makecache成功但yum install提示找不到包。先确认createrepo是否在/opt/kylin-yum目录下生成了repodata以及baseurl是否指向了包含repodata的那一层。如果repodata在/opt/kylin-yum/repodatabaseurlfile:///opt/kylin-yum就是对的如果你把rpm包放在/opt/kylin-yum/rpms/下并在/opt/kylin-yum执行了createrepo那repodata会在/opt/kylin-yum/repodata下而rpm包在rpms/下yum会无法关联。这就是为什么我强调rpm包平铺在仓库根目录。6.3 包下载不全导致的依赖缺失明明已经把软件包和依赖都下载了安装时还是提示缺少某个.so文件或依赖包。常见原因是对应的底层依赖库没被--resolve或--download-only拉全。比如某些包在安装后需要额外钩子触发下载或者在suggests、recommends里带了可选依赖。yumdownloader默认不下载recommends包apt-get --download-only也有类似情况。解决方法是先把软件包列表列出来对照依赖逐个检查。APT系可以用apt-cache depends 软件包名YUM系可以用yum deplist 软件包名看到缺哪个包再到联网机器上单独下载补上重新生成索引即可。6.4 架构不匹配和文件系统坑给x86的机器下载了arm64架构的包或者反过来安装时报“Wrong architecture”。这个无解只能在下载阶段严格把关。甚至同一个软件在CentOS 7和CentOS 8上的rpm包也不能通用。银河麒麟V10的SP版本不同底层库版本也有差异最稳妥的做法是“在和你离线机同样系统版本、同样架构的机器上准备包”。拷贝过程中还有一个隐藏坑如果用FAT32格式的U盘拷贝单文件超过4GB会失败而且Unix权限位、符号链接可能丢失。rpm/deb包本身不大但如果拷贝多的时候权限出错可能导致createrepo或dpkg-scanpackages读取异常。建议把deb/rpm先打包成tar文件再拷贝到目标机器后再解压能最大限度保留文件属性。6.5 补充不要在本地源上开gpgcheck我见过有人严格遵循安全习惯在本地源的repo配置里写gpgcheck1然后去网上找gpgkey折腾半天还是不通过。本地源的包不一定有可信签名设置gpgcheck0即可。离线环境的核心目标是装软件不是做完整供应链安全验证如果对完整性有要求可以在打包时算好校验值如SHA256到目标机器后核对。7. 进阶玩法让整个内网都用上你的本地源7.1 用HTTP把源共享出去如果内网不止一台机器没必要每台机器都拷贝一份软件包。把装有软件包的机器作为“源服务器”用HTTP把目录共享出去其他机器的源地址指向它这样整个内网就共用一个“软件应用商店”。最轻量的方式是用Pythoncd /opt/kylin-apt python3 -m http.server 8080其他APT机器在sources.list里写deb [trustedyes] http://192.168.1.100:8080 ./YUM方式同理用nginx、apache或python3 -m http.server把/opt/kylin-yum发布为HTTP目录然后客户端的baseurl写baseurlhttp://192.168.1.100/yum需要注意的是APT的flat repository通过HTTP共享时./这种写法兼容性不错但如果在目录里生成Release文件会更标准。不过本地使用场景下[trustedyes]跳过签名验证问题不大。7.2 配合系统安装镜像直接做源很多时候银河麒麟系统的安装ISO镜像本身就携带了大量基础软件包。把ISO文件挂载到系统上可以直接把镜像目录当作软件源省去大量拷贝工作。sudo mount -o loop /path/to/kylin.iso /mntYUM系直接配置baseurlfile:///mnt前提是镜像里对应版本的仓库结构完整且有repodata目录。一些安装ISO为了精简体积只保留最小系统所需包所以更丰富的软件还是得靠自定义仓库补全。在部署任务紧急时先用ISO源装上基础工具再补自定义源装业务软件是效率最高的组合。7.3 日常维护和应急U盘建议离线环境的管理员最怕的是“不知道未来要装什么软件”。我的建议是提前做一个“应急软件包U盘”里面至少包含以下内容常用基础工具vim、tree、net-tools、lrzsz、wget、curl。常用编译链gcc、make、gdb。运维常用服务openssh-server、ntp/chrony、rsync、telnet等。数据库客户端根据业务需要准备。ROS、显卡驱动等特殊场景专包按项目需要单独维护。每次在联网机器上装了某些新软件顺手把缓存的deb/rpm包同步到U盘对应目录再用脚本重新生成索引。这样下次遇到离线环境直接插上U盘挂载目录一条apt update或yum makecache就能进入“有网状态”。最后再分享一个小技巧把索引生成命令写成脚本比如/usr/local/bin/update-local-repo.sh里面分别处理APT和YUM的场景以后更新完包目录一条命令刷新索引不用每次回忆dpkg-scanpackages或createrepo的语法。我第一次搭这个环境的时候就是在U盘根目录放了这样一个脚本到了新项目现场改一下路径就能用省了不少事。
返回列表