简介:面向需要在国产化或 ARM 服务器上私有化部署镜像仓库的运维与 DevOps 人员,这份资源提供 harbor-v2.9.0 的 arm64 架构离线安装包,解决内网环境无法拉取镜像、x86 包无法在 ARM 平台运行的问题。压缩包共 6 个文件,约 722.35MB,以 gz 离线镜像包为主体,配合 sh 安装脚本、prepare 预处理脚本、tmpl 配置模板及 license 授权文件,覆盖从环境准备到服务启动的完整链路,执行 install.sh 即可一键完成部署,前置条件为已安装 docker 与 docker-compose。目前已有 962 人学习下载,适合具备一定容器基础、希望快速搭建 ARM 版 Harbor 的读者参考。借助该离线包,可省去逐层拉取镜像与手动配置的繁琐过程,直接获得可运行的私有仓库环境,并对照配置模板调整端口、存储与访问参数,降低内网部署门槛。
1. harbor-v2.9.0离线安装(arm架构):内网环境下的镜像仓库落地
很多做信创项目的工程师都遇到过这种场景:客户机房完全断网,服务器是鲲鹏或飞腾的 arm64 机器,操作系统是银河麒麟或统信 UOS,但 CI/CD 流水线又必须有一个私有镜像仓库来存业务镜像。这时候 harbor-v2.9.0 离线安装(arm架构)就成了绕不开的一环。Harbor 是 VMware 开源的企业级容器镜像仓库,v2.9.0 这个版本在 arm64 上的组件兼容性已经比较成熟,但官方发布的离线包默认是 x86_64 架构,arm 机器上直接跑会报 exec format error。所以核心工作不是「装 Harbor」,而是「在 arm 架构上把 Harbor 的离线安装包重新组装出来」。这篇文章面向的是需要在离线 arm 服务器上部署私有仓库的运维和平台工程师,从离线包结构拆解讲到组件替换、配置调参和排错,每一步都能照着复现。
2. 拆解 harbor 离线安装包:arm 架构下哪些组件必须换
2.1 离线包目录结构与组件清单
Harbor 的离线安装包(offline installer)本质上是一个 tar.gz,解压后包含 harbor 目录和 harbor.v2.9.0.tar.gz 镜像包。harbor 目录里是 docker-compose.yml、prepare 脚本、common.sh 等编排文件,而 harbor.v2.9.0.tar.gz 里是十几个容器镜像的 tar 层。安装逻辑很简单:先 docker load 导入所有镜像,再用 docker compose 拉起容器。
问题在于,官方离线包里的镜像全是 linux/amd64 的。在 arm64 机器上 docker load 能成功,但 docker run 时会直接报exec /harbor/harbor_core: exec format error。所以 arm 架构离线安装的核心思路是:保留官方离线包的编排文件和配置模板,把里面的镜像全部替换成 arm64 版本。
需要替换的镜像清单如下:
| 组件 | 镜像名 | 作用 | arm64 来源 |
|---|---|---|---|
| 核心服务 | goharbor/harbor-core | API 与业务逻辑 | 自行构建或第三方 arm 镜像 |
| 门户 | goharbor/harbor-portal | Web UI | 同上 |
| 数据库 | goharbor/harbor-db | PostgreSQL | 官方 postgres arm64 可替代 |
| 缓存 | goharbor/redis-photon | Redis | 官方 redis arm64 可替代 |
| 注册表 | goharbor/registry-photon | 镜像存储 | 官方 registry arm64 可替代 |
| 任务服务 | goharbor/harbor-jobservice | 异步任务 | 自行构建 |
| 日志 | goharbor/harbor-log | 日志收集 | 自行构建 |
| 代理 | goharbor/nginx-photon | 反向代理 | 官方 nginx arm64 可替代 |
| 扫描器 | goharbor/trivy-adapter-photon | 漏洞扫描 | 自行构建 |
这张表是整篇文章的骨架。你会发现,Harbor 自研的组件(core、jobservice、portal、log、trivy-adapter)没有官方 arm64 镜像,必须自己编译或者找社区构建好的。而依赖的中间件(PostgreSQL、Redis、Registry、Nginx)都有官方 arm64 版本,可以直接替换。
2.2 为什么不能直接用 docker buildx 一把梭
有经验的工程师第一反应是:用 docker buildx 在 x86 机器上交叉编译 arm64 镜像不就行了?理论上可行,但 Harbor 的构建体系有几个坑。
第一,Harbor 的 Makefile 依赖 Photon OS 作为基础镜像,而 Photon OS 的 arm64 版本并不完整,部分包缺失。第二,Harbor 的编译过程需要下载大量 Go 模块和 npm 包,离线环境下根本拉不下来。第三,即使编译成功,镜像里的二进制还需要和 arm64 的 glibc 版本匹配,银河麒麟的 glibc 版本和 Photon OS 不一定一致。
所以更稳妥的做法是:在一台能联网的 arm64 机器上(比如鲲鹏开发板或者云上的 arm 实例),用 Harbor 源码编译出 arm64 镜像,然后 docker save 导出,再拷贝到离线环境。如果连这台机器都没有,那就只能找社区已经构建好的 arm64 镜像包,但要注意版本必须和 v2.9.0 对齐,否则数据库 migration 会出问题。
我一般会准备一台 arm64 的 Ubuntu 20.04 作为构建机,因为 Harbor 官方在 Ubuntu 上的编译依赖最容易满足。构建命令大致如下:
# 在 arm64 构建机上执行 git clone https://github.com/goharbor/harbor.git cd harbor git checkout v2.9.0 # 安装编译依赖 sudo apt-get install -y docker.io docker-compose make gcc # 编译并构建所有镜像 make build -e BUILD_ARCH=arm64 # 导出镜像为 tar 包 make save -e BUILD_ARCH=arm64这段命令的逻辑是:先切到 v2.9.0 标签,确保源码版本和离线包一致;然后通过 make build 触发 Dockerfile 构建,BUILD_ARCH=arm64 会让编译参数指向 arm64;最后 make save 把所有镜像导出成一个 tar 文件。参数 BUILD_ARCH 是关键,不指定的话默认是 amd64,编出来的镜像在 arm 上跑不了。
构建完成后,你会得到一个 harbor.v2.9.0.tar.gz,里面的镜像就是 arm64 的了。把这个文件和官方离线包里的 harbor 目录(编排文件)组合在一起,就得到了一个 arm64 离线安装包。
3. 在银河麒麟 arm 服务器上执行离线安装
3.1 系统前置检查与 docker 环境准备
银河麒麟 V10 SP2 是信创环境里最常见的 arm64 操作系统,内核版本一般是 4.19 或 5.10。在开始之前,先确认几件事:
# 确认 CPU 架构 uname -m # 期望输出:aarch64 # 确认内核版本 uname -r # 期望输出:4.19.x 或 5.10.x # 确认 docker 是否已安装 docker version # 如果没有,需要先离线安装 docker如果 docker 还没装,需要准备 docker 的 arm64 离线 rpm 包。银河麒麟基于 CentOS 8 的包管理体系,可以用yum install --downloadonly在联网机器上下载 docker-ce 及其依赖,然后拷贝到离线机器上rpm -ivh安装。注意 docker 版本不要低于 20.10,否则 docker compose v2 的语法可能不兼容。
安装完 docker 后,启动并设置开机自启:
sudo systemctl enable docker sudo systemctl start docker sudo systemctl status docker这一步看起来简单,但血泪经验是:银河麒麟默认的 SELinux 策略可能会阻止 docker 挂载卷。如果后面 Harbor 容器启动时报 permission denied,先检查getenforce的输出,如果是 Enforcing,临时设为 Permissive 试试。
3.2 导入 arm64 镜像并修改编排文件
把 arm64 的 harbor.v2.9.0.tar.gz 和 harbor 目录放到同一级,然后执行导入:
# 解压离线包 tar -xzf harbor-offline-installer-v2.9.0-arm64.tgz cd harbor # 导入所有镜像 docker load -i harbor.v2.9.0.tar.gz # 确认镜像架构 docker inspect goharbor/harbor-core:v2.9.0 --format '{{.Architecture}}' # 期望输出:arm64导入完成后,需要修改 harbor.yml 配置文件。从 harbor.yml.tmpl 复制一份:
cp harbor.yml.tmpl harbor.yml vim harbor.yml关键配置项如下:
# 修改为服务器的实际 IP 或域名 hostname: 192.168.1.100 # 如果不用 HTTPS,注释掉 https 段 # https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path # 数据存储路径,确保磁盘空间足够 data_volume: /data/harbor # 数据库密码,生产环境务必修改 database: password: root123 max_idle_conns: 100 max_open_conns: 900hostname 这一项必须填客户端能访问到的地址,填 127.0.0.1 的话其他机器 push 镜像会失败。data_volume 建议单独挂一块盘,因为镜像层很占空间,放在系统盘容易把根分区撑满。
3.3 执行安装脚本与验证服务状态
配置改好后,运行安装脚本:
sudo ./install.sh --with-trivy--with-trivy表示同时启用漏洞扫描组件。如果不需要扫描功能,可以不加这个参数,少启动一个容器,省点资源。
安装脚本会做几件事:检查 docker 和 docker compose 版本、加载镜像、生成 docker-compose.yml、启动容器。整个过程大概 2 到 5 分钟,取决于磁盘 IO 速度。
安装完成后,验证容器状态:
docker compose ps期望看到 9 个容器都是 Up 状态。如果有容器反复重启,用docker logs <容器名>看日志。最常见的问题是 harbor-db 启动失败,原因是数据目录权限不对,解决方法:
sudo chown -R 999:999 /data/harbor/database999 是 PostgreSQL 容器内 postgres 用户的 UID。这个坑在 x86 上不太常见,但 arm 环境下因为文件系统权限映射差异,出现的概率更高。
最后验证 Web 界面和 push 功能:
# 浏览器访问 http://192.168.1.100 # 默认账号 admin,密码 Harbor12345 # 命令行登录并 push 测试镜像 docker login 192.168.1.100 docker tag nginx:latest 192.168.1.100/library/nginx:test docker push 192.168.1.100/library/nginx:testpush 成功说明整个链路通了。如果 push 时报received unexpected HTTP status: 500,多半是 harbor-core 和 registry 之间的通信问题,检查这两个容器的日志。
4. arm 架构离线安装 harbor 的避坑与排查
4.1 镜像架构不匹配导致容器起不来
现象:docker compose up后容器状态一直是 Restarting,日志里报exec format error。
原因:离线包里混入了 amd64 镜像,或者 docker load 时没有覆盖旧镜像。
解决:用docker inspect <镜像名> --format '{{.Architecture}}'逐个检查,发现 amd64 的重新导入 arm64 版本。导入前先docker rmi删掉旧镜像,否则 docker load 会跳过已存在的标签。
4.2 数据库初始化失败导致 harbor-core 崩溃
现象:harbor-db 容器 Up,但 harbor-core 日志报dial tcp 127.0.0.1:5432: connect: connection refused。
原因:PostgreSQL 的数据目录权限不对,或者初始化脚本没有执行完就超时了。
解决:先确认/data/harbor/database目录属主是 999:999,然后删除该目录下的所有内容,重启 harbor-db 容器让它重新初始化。注意这个操作会清空所有数据,仅适用于首次安装。
4.3 银河麒麟 SELinux 阻止卷挂载
现象:容器启动时报Permission denied,但目录权限看起来没问题。
原因:SELinux 策略不允许 docker 访问宿主机目录。
解决:临时setenforce 0验证是否是 SELinux 问题。如果是,可以在 docker-compose.yml 里给卷挂载加上:z或:Z标签,或者永久调整 SELinux 策略。生产环境不建议直接关闭 SELinux,加标签更安全。
4.4 docker compose 版本不兼容
现象:./install.sh报docker compose command not found或unsupported option。
原因:银河麒麟自带的 docker-compose 可能是 v1 版本,而 Harbor v2.9.0 要求 v2。
解决:离线安装 docker compose v2 的二进制文件,放到/usr/local/bin/docker-compose,并确保可执行。验证命令是docker compose version,注意中间是空格不是横杠。
4.5 磁盘空间不足导致镜像 push 失败
现象:push 镜像时进度条卡住,然后报no space left on device。
原因:/data/harbor所在分区满了,或者 docker 的>docker exec harbor-db pg_dump -U postgres registry > /backup/registry_$(date +%Y%m%d).sql
这个备份文件在升级失败时就是后悔药,回滚时导入即可。
多节点分发的话,如果内网有多个 Harbor 实例,可以用 rsync 同步镜像存储目录,但要注意 registry 的存储驱动必须一致。更稳妥的方式是每个节点独立部署,然后用 Harbor 的复制策略做镜像同步。复制策略在 Web 界面的「仓库管理」里配置,支持推模式和拉模式,跨机房场景建议用拉模式,避免网络抖动导致同步中断。
最后说一个我踩过的坑:arm64 镜像的 manifest 格式和 amd64 略有差异,如果 Harbor 前面挂了 CDN 或者反向代理,有些代理会缓存 manifest 导致拉取失败。解决方法是给 manifest 的 URL 加上Cache-Control: no-cache头,或者在代理层禁用对/v2/路径的缓存。这个坑排查起来很费时间,因为现象是「有时候能拉有时候不能拉」,看起来像玄学,实际上是缓存命中率的问题。
希望帮到你。
本文还有配套的精品资源,点击获取