ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

龙芯+银河麒麟部署Harbor私有镜像仓库全攻略

2026/9/30 17:43:43 拓冰建站 浏览量
龙芯+银河麒麟部署Harbor私有镜像仓库全攻略 把一台龙芯服务器变成能用的私有镜像仓库表面看是装个 Harbor 而已真正动起手来才知道这种“国产 CPU 国产系统 开源容器仓库”的组合坑全都藏在细节里。我先说清楚这次的环境龙芯 3A5000LoongArch 指令集银河麒麟 V10 SP1目标是在内网里跑起 Docker 版的 Harbor给团队提供一个支持权限隔离、镜像回收的私有仓库。选 Harbor 而不是直接用轻量 registry是因为团队要按项目分权限、要定期清理无效镜像、后面还要对接 CI 流水线这些功能只有 Harbor 这类平台型仓库能扛住。难点在于Harbor 官方发布的多是 amd64/arm64 架构镜像放到 LoongArch 环境里直接跑轻则 manifest 列表里找不到对应架构重则镜像能加载却根本跑不起来。这篇文章把完整流程和踩坑过程梳理一遍给同样要在龙芯环境里折腾 Harbor 的朋友一个参考。1. 部署前必须想清楚的三件事1.1 龙芯与银河麒麟的组合第一步不是装软件而是认清架构很多朋友习惯拿到服务器就yum install docker在龙芯环境里这样莽很容易翻车。龙芯比较特殊市场上能看到的机器分两个流派老一点的 3A3000/3A4000 走的是 MIPS 指令集系统里uname -m出来是mips64el新一点的 3A5000/3A6000 走的是自研 LoongArch 指令集uname -m出来是loongarch64。两者是完全不同的体系二进制、镜像、工具链都不通用连很多底层.so 都要重编。银河麒麟 V10 面向不同硬件也有对应的版本比如针对 ARM、X86、MIPS、LoongArch 都有独立发布。同一台机器上你既要在系统层面确认版本也要在 CPU 层面确认架构不能想当然。我这次就是先被“龙芯”两个字误导了一把以为统一走 MIPS 方向结果用 MIPS 的包装了半天才发现机器其实是 LoongArch白白浪费了小半天。实操上部署前必须跑这几个命令uname -m # 看 CPU 架构loongarch64 还是 mips64el cat /proc/cpuinfo # 看具体型号3A5000 还是 3A6000 cat /etc/os-release # 看系统版本银河麒麟 V10 SP1 / SP2 等 uname -r # 看内核版本确认内核是否较新某些老内核对 Docker 支持不友好这一步不是走过场它会直接决定后面所有包和镜像怎么选。比如同样是银河麒麟ARM 版本可以直接用很多 arm64 现成包LoongArch 版本则经常要自己多走一步适配。先把“我是谁”搞清楚了后面每一步都会顺很多。1.2 Harbor 不是单个容器而是一整套服务组合Harbor 这个项目我一开始以为就是个带 Web 界面的 Docker registry装了才发现它内部最少有七八个组件协同工作。按官方离线包的结构核心组件大致是这样harbor-core核心服务管认证、权限、项目、审计、复制策略这些业务逻辑。harbor-jobservice负责执行异步任务比如镜像复制、垃圾回收、漏洞扫描。harbor-registry基于 Docker Distribution 的镜像存储服务真正存放镜像层的地方。harbor-portal用户看到的 Web 前端。harbor-dbPostgreSQL 数据库存放项目、用户、策略等元数据。harbor-redis缓存和任务队列给 core 和 jobservice 用。harbor-nginx统一入口负责 HTTPS 终结、路由分发对外只暴露一个端口。把这些组件跑起来靠的是 Docker Compose 编排。所以真正部署 Harbor 时你的服务器上不光要有 Docker还得有可用的 Compose 环境。而且这些组件都有各自的基础镜像依赖比如 PostgreSQL、Redis、Nginx任何一个镜像在目标架构上缺失整个 Harbor 都起不来。这也是为什么很多人拿官方离线包在龙芯上docker load之后发现能加载但docker-compose up起来后某些容器直接报错退出。因为离线包里装的是 x86_64 架构的镜像加载到 Docker 里只是把二进制文件放到本地磁盘真正运行做 exec 时CPU 发现指令集对不上直接抛exec format error。所以部署 Harbor 前的第二个思路转变就是别把它当成“一个软件”而是一整套需要架构全匹配的服务集群任何一个镜像节点掉链子整个链路都跑不通。1.3 官方镜像支持有边界别把“离线包能加载”当成“能运行”Harbor 官方目前发布的多架构镜像主要覆盖 amd64、arm64、ppc64le、s390x 这些主流平台LoongArch 不在官方支持列表里。这带来一个很直接的问题你在龙芯机器上执行docker pull或docker load前者会报no matching manifest for linux/loongarch64 in the manifest list entries后者虽然能加载但运行时会报exec format error第一次遇到这种报错容易慌其实原理不复杂。Docker 镜像的 manifest 列表里会声明支持的架构如果平台不匹配拉取阶段就会被拒绝离线 tar 包不检查架构但运行起来还是会被内核拒绝。所以别看到“离线包”就以为万事大吉。理解了这层后面就好办了。要么找到已经适配 LoongArch 的 Harbor 镜像要么自己拿源码构建要么先用功能少一点的轻量方案过渡。我这次选择的路线是在社区适配好的 Harbor LoongArch 离线包基础上部署同时准备了轻量 registry 作为备选方案。下面章节会把这几种方案的选择过程讲细。2. 环境准备与 Harbor 镜像适配2.1 用命令先给服务器做个体检在动手安装之前我习惯性先确认几个硬性条件。第一是磁盘空间Harbor 的镜像存储、数据库、日志都会往数据目录里堆建议单独分一个数据盘或者把/opt/harbor所在的目录留足至少 50GB生产环境 100GB 以上更稳妥。第二是内存Harbor 整套服务默认配置下PostgreSQL 加 Redis 加 core 加 nginx 跑起来实际要 2GB 左右如果服务器内存只有 4GB 甚至更少建议提前把数据库和 Redis 的资源限制调低。体检命令大概是这么一组free -h # 确认内存 df -h /opt # 确认数据盘空间 nproc # 确认 CPU 核数 systemctl status firewalld # 确认防火墙状态 getenforce # 确认 SELinux 状态银河麒麟系统里 SELinux 默认可能是 enforcing也可能已经 disabled需要根据实际状态处理。SELinux 不关的话Docker 容器挂载目录后访问数据卷时经常碰到 permission denied排查起来很隐蔽。我建议要么临时setenforce 0验证要么在正式部署前把系统的 SELinux 策略调整好避免后面容器启动成功但写数据失败的诡异问题。2.2 Docker 的安装别贪新稳定优先在龙芯 银河麒麟环境装 Docker我走过两条路。第一条是直接用银河麒麟软件源里的 docker 包优点是安装方便、依赖项少缺点是版本可能偏旧而且不同小版本的命令参数和网络模式行为有差异。第二条是从 Docker 官方或镜像站点找对应 loongarch64 的 docker-ce 包来装。如果机器能联网并且系统基于 yum 体系银河麒麟 V10 通常带 yum/dnf可以这样操作sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce docker-ce-cli containerd.io但注意这个命令在龙芯机器上不一定能直接拉到 loongarch64 的包因为官方仓库的目录结构对 LoongArch 的覆盖可能不全实际取决于你下载的系统版本和仓库同步情况。稳妥做法是先去 download.docker.com 的 loongarch64 目录下看一下有没有对应 RPM 包有的话直接下载到本地安装sudo yum install -y ./docker-ce-*.rpm ./containerd.io-*.rpm如果压根找不到官方 loongarch64 的 RPM 包那就回到银河麒麟自带的源里装sudo yum list docker* sudo yum install -y docker docker-compose装完先别急着配 Harbor先确认 Docker 本身能正常起sudo systemctl enable docker sudo systemctl start docker docker version docker run hello-world # 小体积验证跑通说明 daemon 正常这里我吃过的教训是不要为了追求最新版去装那种只有 x86 架构的包然后在龙芯上强行rpm -ivh --force或者硬解压二进制强行装上的 Docker 大概率在启动 daemon 阶段就各种报错还得回头清理残留纯属给自己加戏。2.3 docker compose 选型同样要考虑架构Harbor 这种多容器应用起服务靠 compose 编排所以 docker compose 本身也要能在龙芯上跑。银河麒麟源里的 docker-compose 一般是一个 Python 脚本版本优点是不挑 CPU 架构只要 Python 是 loongarch64 版本就能装缺点是执行速度慢一点、依赖 PyYAML 等模块离线环境里装依赖比较麻烦。如果你用的是 docker-ce 新版建议直接配 compose 插件sudo yum install -y docker-compose-plugin docker compose version这种插件方式虽然下载的二进制同样要匹配 loongarch64但整体功能完整、执行效率高配合 Harbor 的docker-compose.yml用起来更顺手。判断标准就一条装完后docker compose version能正常输出版本号而不是直接报错“exec format error”。顺带提一句Harbor 离线包自带的install.sh脚本内部会调用 docker compose 或 docker-compose如果你两个都没有脚本会在最开始就中断并提示缺失工具。所以这个环节别跳。2.4 Harbor 镜像适配三条路线怎么选离线包拿到手却不适配架构这个坎绕不开。结合我在龙芯上折腾的体验镜像适配大致有三条路线各有取舍。路线一使用社区或内部适配的 LoongArch Harbor 离线包。这种方式最省事。Harbor 的主要核心代码是 Go 写的而 Go 对 LoongArch 的支持已经相当完善所以社区持续有人在产出 loongarch64 对应的 Harbor 镜像包。你只需要找一个信任的来源拿到harbor-offline-installer-v2.x.x-linux-loongarch64.tgz这样的包后续流程就和官方安装包几乎一样。这条路的前提是你能确认包的来源可信、镜像没有被做过手脚拿到后先在测试机跑一遍。路线二自建镜像。如果找不到合适的适配包就得自己动手。Harbor 里有几个组件是编译型二进制core、jobservice、registry它们可以在 LoongArch 上用 Go 交叉编译然后搭配 loongarch64 版本的 PostgreSQL、Redis、Nginx 基础镜像再把前端静态资源打进 portal 镜像。流程大约是准备 LoongArch 的 Go 工具链和 Docker 构建环境 → 克隆 Harbor 源码并 checkout 对应 tag → 修改 Makefile 里目标平台 → 逐个构建子镜像 → 自己组装离线包。这条路工作量不小但胜在能完全掌控每一层镜像内容适合有安全审查要求的场景。路线三先用轻量 registry 过渡。如果你当前只是急着要一个能推拉镜像的仓库Harbor 的全部功能一时用不上可以先跑一个精简版私有仓库顶着。比如直接部署 Docker Distribution把镜像存储起来同时用 Nginx 做一层简单的访问控制后面等 Harbor 的 LoongArch 适配稳定了再迁移。好处是部署时间短、运维简单、资源占用小坏处是权限管理、镜像清理、复制这些功能都得自己造轮子。我最后走了路线一同时在线下备好了一套轻量 registry 作为回退方案。具体部署细节见下一章节。3. 完整部署流程从零到能推送镜像3.1 解压离线包并配置 harbor.yml拿到适配好的 Harbor LoongArch 离线包后整个流程就跟在 x86 上差不了太多了。先把包传到服务器解压tar zxf harbor-offline-installer-v2.8.4-linux-loongarch64.tgz cd harbor ls -l目录里会有harbor.yml.tmpl、install.sh、docker-compose.yml、common.sh这些文件还有一个.tgz格式的镜像压缩包。先把配置模板复制一份cp harbor.yml.tmpl harbor.yml vim harbor.ymlharbor.yml 是 Harbor 的全局配置我之前在 x86 环境配置过一版这次在龙芯上基本沿用核心参数就这几项# 对外访问地址可以是域名也可以是 IP hostname: registry.internal.lan # HTTP 配置如果只想用内网明文访问就只开 http http: port: 80 harbor_admin_password: ChangeMeAdmin123 # 数据库密码Harbor 会自动帮你建库和初始化 database: password: ChangeMeDb123 max_idle_conns: 50 max_open_conns: 200 # 数据卷挂载目录所有重要数据都在这 data_volume: /opt/harbor/data # 日志轮转避免日志把磁盘写满 log: level: info local: rotate_count: 10 rotate_size: 200M如果你要用 HTTPS在配置文件里把证书路径指好比如https: port: 443 certificate: /opt/harbor/certs/registry.crt private_key: /opt/harbor/certs/registry.key关于密码Harbor 默认要求至少 8 位包含大小写字母、数字、特殊字符太简单的会在启动校验时报错。数据卷目录最好单独准备别放在系统盘根目录里否则后面镜像堆起来根分区一满不止 Harbor 挂整个系统都可能陷入只读状态。3.2 启动 Harbor 并验证基础服务配置文件就绪后执行sudo ./install.shinstall.sh 会自动加载离线包里的镜像、校验配置文件、执行 prepare 阶段生成最终编排配置然后用 docker compose 把服务拉起来。整个过程在龙芯上会比 x86 上慢一点尤其是第一次加载多个镜像时耐心等。如果之前已经部署过想带漏洞扫描功能可以用sudo ./install.sh --with-trivy但 Trivy 的漏洞数据库镜像在 LoongArch 下不一定有现成的建议先不加。启动完成后验证一下容器状态docker ps正常情况下能看到harbor-core、harbor-jobservice、harbor-registry、harbor-portal、harbor-db、harbor-redis、harbor-nginx这些容器都在运行。再访问一下系统 APIcurl -s http://127.0.0.1/api/v2.0/systeminfo能返回 JSON 数据就说明核心服务起来了。浏览器访问http://服务器IP/用admin和你配置的密码登录 Web 界面。如果页面能打开恭喜Harbor 在龙芯上的部署已经完成了一大半。这里提个容易忽略的点Harbor 启动后harbor-core和harbor-jobservice如果反复重启多半不是架构问题而是数据库初始化没完成或端口冲突。可以先docker logs harbor-db看数据库日志再docker logs harbor-core看连接数据库的报错按日志一步步来。3.3 客户端接入私有仓库Harbor 服务端起来了还要让各台需要拉推镜像的机器能连上来。这里最常见的坑就是 Docker 客户端默认只走 HTTPS而我这套内网环境没配 HTTPS所以直接推镜像会报http: server gave HTTP response to HTTPS client解决办法是在需要访问 Harbor 的每台客户端机器上修改 Docker daemon 配置把 Harbor 地址加进insecure-registries。比如 Harbor 地址是registry.internal.lan:80在/etc/docker/daemon.json里写入{ insecure-registries: [registry.internal.lan] }然后重启 Dockersudo systemctl restart docker如果访问方式配了 HTTPS而且你用的是自签证书更规范的做法是把 CA 证书放到每台客户端的/etc/docker/certs.d/registry.internal.lan/ca.crt目录下这样 Docker 客户端在验证服务端证书时就能通过。登录和推送就按常规流程来docker login registry.internal.lan -u admin -p 你的密码 docker tag nginx:1.27 registry.internal.lan/library/nginx:1.27 docker push registry.internal.lan/library/nginx:1.27注意镜像名里的library是项目名Harbor 不会像 Docker Hub 那样默认送你一个公开的library项目你必须在 Web 界面里先创建一个叫library的项目或者创建自己的项目名否则 push 时会报项目不存在。这一步我踩过一次当时死活想不通账号密码都对了为什么推不上去最后才意识到项目还没建。3.4 用 Web 界面完成权限配置Harbor 的 Web 界面比命令行直观得多登录后建议先做这几件事。创建项目。进入“项目”菜单新建一个项目比如devops根据需要设置成私有或公开。私有项目意味着只有被授权的用户或机器人账号才能访问公开项目内网里所有人都能拉取。对内网小团队来说我习惯把基础镜像项目设置为公开把涉及业务代码镜像的项目设为私有兼顾效率和安全。创建用户。在“系统管理 → 用户”里添加项目成员给不同角色分配权限。Harbor 的角色模型大概是项目管理员、开发人员、访客。开发人员能推送镜像访客只能拉取这个粒度对团队协作很实用。创建机器人账号。如果后面要对接 Jenkins、GitLab CI 这类流水线建议创建机器人账号而不是直接用个人账号。机器人账号可以限定在某个项目、只给推送或拉取权限密码是令牌形式泄露了可以单独吊销不影响个人账号。配置垃圾回收。Harbor 删除镜像后实际上只是删掉了镜像的引用底层存储的 blob 还在需要定期执行垃圾回收。在“系统管理 → 垃圾回收”里可以手动执行也可以设置定时策略。建议至少每天跑一次否则存储增长会超出预期。我在内网环境就遇到过一次镜像删了不少但数据卷越来越大就是 GC 没开。配置复制规则。如果有多机部署、灾备需求Harbor 的复制功能可以把镜像推到另一个 Harbor 实例或阿里云、腾讯云之类的云端仓库。在“系统管理 → 复制管理”里创建规则选择源项目和目标仓库即可。复制任务由 jobservice 组件异步执行可以在界面上看到任务状态。4. 运行过程中常见问题与排查4.1 容器反复重启日志里出现 permission denied这是我在银河麒麟环境里碰到的第一类典型问题。现象是docker ps里某些容器刚启动几秒就退出看docker logs有一堆permission denied或mkdir ... no such file or directory。排查思路分三路。第一路看 SELinux执行getenforce如果是 enforcing先把数据卷目录的 SELinux 上下文配好或者临时禁用验证。第二路看目录权限Harbor 数据卷里 database、registry、redis 这些子目录需要被容器内 999 或 5432 等用户写入检查目录 owner 和权限是否匹配。第三路看挂载目录的父级目录如果/opt本身带了 noexec 或者权限受限也会引发奇怪问题。多数情况下把数据卷整个目录 chown 给一个合适的 uid并解决 SELinux 上下文后容器就能稳定起来了。4.2 login 成功但 push 镜像报 unauthorized这个问题很隐蔽。现象是docker login已经成功docker push却提示unauthorized: authentication required甚至denied: requested access to the resource is denied原因基本集中在三处。一是镜像里的项目名在 Harbor 里不存在也就是我前面提过的library项目没建。二是用户名对应的权限不够比如访客角色尝试 push。三是用了机器人账号但在 Web 界面里创建的机器人账号只选了“拉取”权限。解决方法是去项目成员里确认该账号是不是“开发人员”角色以及机器人账号是否勾选了“推送”。还有一个被忽略的点时钟同步。Harbor 生成 token 时会校验时间如果服务器和客户端的时间偏差太大登录虽然显示成功但后续请求 token 可能校验不过去。建议部署前就配置好 NTP 时间同步看起来是小事情实际上能避免很多诡异的认证问题。4.3 客户端一直连不上 Harbor报 connection refused如果客户端机器能 ping 通服务器但docker login报 connection refused优先检查三样东西。第一Harbor 的 nginx 容器是不是真的在监听 80/443 端口用docker ps看端口映射。第二银河麒麟的防火墙默认可能拦截端口确认放行sudo firewall-cmd --zonepublic --add-port80/tcp --permanent sudo firewall-cmd --reload第三Harbor 配置里的 hostname 写的是什么。如果 hostname 配置了域名客户端必须能解析该域名不能图省事用 IP 访问却又配置域名。我当时配置的registry.internal.lan就在每台客户端 hosts 文件里加了一行解析问题才彻底消失。4.4 内存不足导致的隐性故障银河麒麟跑在龙芯服务器上内存配置如果比较紧Harbor 的整套服务跑起来很容易出现隐性故障。常见现象是Harbor 页面偶尔能打开但很慢或者harbor-core偶尔被 OOM killdocker 里的 restart 策略又会自动重启看起来像周期性崩溃。排查手段首先是docker inspect harbor-core --format {{.State.OOMKilled}}如果输出 true说明确实被系统 OOM 机制杀了。解决办法是给数据库和 Redis 容器设置合适的资源上限避免它们各自吃太多内存。比如修改 docker-compose.yml 里 harbor-db 的 mem_limit同时调整 PostgreSQL 的shared_buffers和 Redis 的maxmemory。也要意识到LoongArch 上部分基础镜像的默认配置和 x86 版有差异某些容器优化参数反而会带来额外开销。部署完成后建议用docker stats观察一段时间的资源占用曲线做到心里有数。5. 运行一段时间后的经验与扩展5.1 数据备份怎么做Harbor 的数据主要在两块数据库里的元数据registry 目录里的镜像 blob。备份时不能直接复制运行中的目录否则可能拿到不一致的数据。我采用的方式是先写个脚本在备份前用 docker compose stop 把不需要的服务停掉或者至少停掉 harbor-db然后用 tar 将/opt/harbor/data/database和/opt/harbor/data/registry打备份。如果业务要求不能停服可以用 PostgreSQL 自身的逻辑备份docker exec harbor-db pg_dump -U postgres -d registry harbor_db_backup.sql镜像存储则靠定期对 registry 目录做快照或者 rsync。说实话最简单可靠的方式还是每天凌晨低峰期短暂停掉 harbor-db快速 tar 一遍数据卷再启动整个窗口控制在几分钟内。对于内网研发团队来说这个策略完全够用。5.2 后续可以扩展的方向Harbor 部署稳定后值得往这几个方向继续延伸。对接 CI/CD。在 Jenkins 或 GitLab CI 里配置 docker login 和 docker push 命令提交代码后自动构建镜像推送到 Harbor。使用机器人账号能避免把个人密码写进流水线配置更安全。多架构镜像管理。如果你们未来有 ARM 和 x86 混用的情况可以用 buildx 构建多架构镜像manifest 列表推送到 Harbor。Harbor 本身能显示不同架构的镜像变体拉取时 Docker 会自动选择匹配架构这个能力在混合架构机房非常有用。镜像代理缓存。如果研发团队经常需要拉取公共镜像可以在 Harbor 里创建代理项目指向 Docker Hub 等外部仓库这样内网拉取公共镜像时会走 Harbor 的缓存既快又不重复占用外网带宽。不过这个功能依赖 Harbor 能访问外网离线内网环境就别考虑了。磁盘监控。镜像仓库是最容易在无声无息中把磁盘塞满的服务之一。给数据卷目录挂上磁盘监控告警阈值建议 70% 就开始预警留出足够操作空间。我现在的习惯是每次给龙芯 银河麒麟环境部署这类服务都会先花 30 分钟把架构核对清楚、把镜像适配路线选好再动手装系统包。很多看起来是“运气象问题”的故障归根结底都是前期适配判断错了方向。Harbor 这套在龙芯上虽然有额外的工作量但真跑起来稳定性并不差关键就是不要在架构和镜像这两步省时间。