简介:面向需要在国产化或 ARM 服务器上私有化部署镜像仓库的运维与 DevOps 人员,这份资源提供 Harbor v2.9.0 的 arm64 架构离线安装包,解决内网环境无法拉取镜像、x86 包不兼容等部署难题。压缩包共 6 个文件,以 sh 安装脚本、gz 离线镜像包为主,另含 license 授权文件、prepare 预处理脚本与 tmpl 配置模板,整体约 722.35MB,覆盖从环境准备到服务启动的完整链路。使用前需预先装好 docker 与 docker-compose,执行 install.sh 即可一键完成安装,省去逐组件手工配置的繁琐。目前已有 969 人学习下载,适合希望快速搭建企业级镜像仓库、验证 ARM 平台兼容性的读者参考,也可作为内网离线交付场景的部署底包。
1. 离线环境里把 harbor-v2.9.0 装到 arm 机器上,到底难在哪
一台没有外网的 arm 服务器,一个拷贝进来的离线包,一条./install.sh命令,然后就是漫长的等待和一堆镜像拉取失败的报错——这是我第一次在 arm 架构上部署 harbor-v2.9.0 时最真实的体验。harbor 本身是一个企业级容器镜像仓库,v2.9.0 这个版本在 x86 上安装已经相当成熟,但一旦换到 arm 架构、又断掉外网,事情就完全不一样了。你需要提前把所有镜像、二进制、依赖全部准备好,任何一个环节漏了,安装脚本就会卡在某个docker pull上不动。
这篇文章面向的是手里有 arm 服务器(比如国产化平台、边缘计算节点、实验室自建集群)、需要在纯离线环境里把 harbor-v2.9.0 跑起来的运维和开发人员。我会把整个流程拆成可复现的步骤:从离线包的组成、镜像的架构匹配、配置文件的参数含义,到安装后怎么验证、出问题怎么排查。如果你之前只在 x86 上装过 harbor,那 arm 上多出来的那些坑,这篇会帮你提前踩一遍。
2. 离线包和 arm 镜像:先把原料备齐再动手
2.1 harbor 离线安装包到底包含什么
harbor 官方提供的离线安装包(offline installer)本质上是一个压缩包,解压后包含几个关键部分:harbor/目录下是 docker-compose 模板、配置文件模板和安装脚本;harbor/images/或类似的镜像归档目录里存放着所有需要的容器镜像 tar 包。安装脚本install.sh会做几件事:检查 docker 和 docker-compose 是否可用、加载镜像 tar 包、根据harbor.yml渲染最终的 docker-compose 文件、然后启动容器。
在 x86 环境下,官方离线包里的镜像就是 amd64 架构的,直接加载即可。但 arm 环境下,你需要的是 aarch64/arm64 架构的镜像。这里第一个关键认知是:harbor 官方发布的离线包默认是 amd64 的,arm 版本需要单独获取或自行构建。常见做法是去 harbor 的 release 页面找是否有 arm64 的离线包,如果没有,就需要用docker buildx在能联网的机器上交叉构建,或者找第三方已经构建好的 arm64 镜像归档。
我一般会先确认目标机器的架构:
uname -m # 输出 aarch64 或 arm64 表示是 arm 架构 # 输出 x86_64 表示是 amd64这一步看起来简单,但很多翻车案例就是拿错了包——把 amd64 的离线包拷到 arm 机器上,docker load的时候不报错,但启动容器时直接exec format error,因为镜像里的二进制架构不对。
2.2 在联网机器上准备 arm64 镜像的两种路径
如果你拿到的离线包里镜像不是 arm64 的,有两条路可以走。
第一条路是找现成的 arm64 离线包。harbor 社区在某些版本确实提供多架构支持,v2.9.0 需要确认 release 资产里是否有harbor-offline-installer-v2.9.0-arm64.tgz这类文件。如果有,直接下载即可。
第二条路是自己构建。这需要一台能联网的 arm64 机器(或者用 qemu 模拟),先把 harbor 的源码拉下来,用make build或docker buildx构建所有组件镜像,然后docker save导出成 tar 包。这个过程比较重,但可控性最强。下面是一个用 buildx 构建并导出镜像的示例:
# 在联网的 arm64 机器上操作 # 假设已经 clone 了 harbor 源码并切换到 v2.9.0 tag cd harbor # 使用 buildx 构建多架构镜像,这里指定 arm64 docker buildx build --platform linux/arm64 -t harbor-core:arm64 -f make/photon/core/Dockerfile . # 构建完成后导出为 tar 包 docker save harbor-core:arm64 -o harbor-core-arm64.tar # 对其他组件重复此过程:portal、registry、registryctl、jobservice、db、redis、proxy 等逻辑说明:docker buildx build的--platform linux/arm64参数确保构建出的镜像目标架构是 arm64。docker save把镜像导出成 tar 文件,方便拷贝到离线机器。参数上需要注意的是,harbor 的各个组件 Dockerfile 路径不同,需要根据源码目录结构逐个构建。如果构建过程中遇到基础镜像拉取失败,需要先确保基础镜像本身有 arm64 版本。
把所有组件镜像 tar 包准备好后,拷贝到离线机器上,用docker load -i xxx.tar逐个加载。加载完成后用docker images确认每个镜像的架构标签。
2.3 离线机器的前置依赖检查清单
在真正运行install.sh之前,离线机器上必须已经具备这些条件:
| 依赖项 | 检查命令 | 要求 |
|---|---|---|
| Docker | docker version | 20.10 以上,支持 arm64 |
| Docker Compose | docker compose version或docker-compose version | v2 或 v1.29 以上 |
| 磁盘空间 | df -h /data | 至少 40GB 可用 |
| 内存 | free -h | 至少 4GB,推荐 8GB |
| 端口 | ss -tlnp | grep -E '80|443|5432|6379' | 80/443 未被占用 |
这些检查看起来是常规操作,但在离线环境里,docker 本身可能就没有装好。arm 机器上的 docker 安装包也需要提前准备,不能指望apt install能联网下载。我一般会提前把 docker 的 arm64 deb 包或二进制包也放进离线介质里。
提示:docker-compose 在 arm 上有一个常见问题——某些版本的 docker-compose 二进制是 x86 编译的,在 arm 上运行会报
cannot execute binary file。务必确认docker-compose version能正常输出版本号。
3. 配置 harbor.yml 与启动安装:参数改对才能跑起来
3.1 harbor.yml 里必须改的五个参数
解压离线包后,进入harbor/目录,你会看到harbor.yml.tmpl。复制一份为harbor.yml,然后开始改。以下五个参数是必须根据你的环境调整的:
# harbor.yml 关键配置片段 hostname: harbor.internal.example.com # 改成你的实际域名或IP http: port: 80 https: port: 443 certificate: /your/cert/path.crt private_key: /your/cert/path.key harbor_admin_password: YourStrongPassword123 data_volume: /data/harbor database: password: your_db_password max_idle_conns: 100逐项说明:hostname是 harbor 对外暴露的地址,如果离线环境没有 DNS,直接写 IP 也可以,但要注意后续 docker login 时用的地址要一致。http.port和https.port是监听端口,如果 80/443 被占用可以改,但改了之后客户端登录时要带端口号。harbor_admin_password是 admin 用户的初始密码,v2.9.0 要求密码至少 8 位且包含大小写和数字。data_volume是数据存储路径,确保这个路径所在磁盘有足够空间。database.password是内部数据库密码,虽然不对外暴露,但也建议改掉默认值。
如果你不需要 https,可以把https整段注释掉,只保留 http。但生产环境建议配 https,证书可以是自签的,客户端需要把 CA 证书加到信任列表。
3.2 运行 install.sh 时发生了什么
配置改好后,执行安装:
# 在 harbor 目录下执行 sudo ./install.sh # 如果需要指定安装组件(比如只要核心功能,不要 trivy 扫描) sudo ./install.sh --with-trivy=false # 安装完成后查看容器状态 docker compose ps # 或者如果是 docker-compose v1 docker-compose psinstall.sh的执行逻辑是:先检查harbor.yml是否存在且格式正确,然后调用prepare脚本生成docker-compose.yml,接着加载harbor/images目录下的所有镜像 tar 包,最后用 docker-compose 启动所有服务。整个过程如果镜像加载失败,脚本会报错退出。
参数方面,--with-trivy=false表示不安装镜像扫描组件,这在离线环境里很实用,因为 trivy 的漏洞库需要联网更新,离线环境下它基本没法工作。类似的可选组件还有--with-notary(镜像签名)、--with-chartmuseum(Helm chart 仓库),按需开启。
安装完成后,用docker compose ps应该看到所有容器状态是Up或healthy。harbor 的核心组件包括:harbor-core(API 服务)、harbor-portal(Web UI)、harbor-registry(镜像存储)、harbor-db(PostgreSQL)、harbor-redis(缓存)、harbor-jobservice(任务调度)、nginx(反向代理)。
3.3 验证安装是否真正可用
容器都起来了不代表 harbor 就能用。我一般会做三层验证:
第一层,访问 Web UI。在浏览器打开http://<hostname>,应该能看到 harbor 的登录页面。用 admin 和你设置的密码登录,能进去就说明 portal 和 core 正常。
第二层,命令行登录和推拉镜像。在一台能访问 harbor 的机器上(可以是本机)执行:
# 登录 harbor docker login harbor.internal.example.com # 输入用户名 admin 和密码 # 从 harbor 拉一个测试镜像(如果 harbor 里还没有镜像,先从别处推一个上去) # 这里假设本地有一个 alpine 镜像 docker tag alpine:latest harbor.internal.example.com/library/alpine:latest docker push harbor.internal.example.com/library/alpine:latest # 然后删除本地镜像再拉取 docker rmi harbor.internal.example.com/library/alpine:latest docker pull harbor.internal.example.com/library/alpine:latest如果能成功 push 和 pull,说明 registry 存储、数据库、redis 这条链路都通了。
第三层,检查日志有没有隐藏错误。docker compose logs -f harbor-core看核心服务日志,docker compose logs -f harbor-registry看存储服务日志。有些问题不会导致容器退出,但会在日志里持续报错,比如数据库连接超时、redis 认证失败等。
注意:如果
docker login报x509: certificate signed by unknown authority,说明你用了自签证书但客户端没信任。解决办法是把 CA 证书拷贝到客户端的/etc/docker/certs.d/<hostname>/ca.crt,然后重启 docker。
4. arm 离线安装的避坑清单:五个血泪教训
4.1 镜像架构不匹配导致 exec format error
现象:docker compose up后,部分容器反复重启,docker logs看到exec /usr/bin/xxx: exec format error。
原因:加载的镜像 tar 包是 amd64 架构的,在 arm64 机器上无法执行。docker load不会检查架构,所以加载时不报错,运行时才暴露。
解决:用docker inspect <image> | grep Architecture确认每个镜像的架构是arm64。如果发现是amd64,需要重新获取或构建 arm64 版本。批量检查可以用:
# 列出所有 harbor 相关镜像的架构 docker images --format '{{.Repository}}:{{.Tag}}' | grep -E 'harbor|goharbor' | while read img; do arch=$(docker inspect "$img" --format '{{.Architecture}}') echo "$img -> $arch" done4.2 docker-compose 版本不兼容导致配置文件解析失败
现象:install.sh执行到一半报Unsupported config option for services或version is obsolete。
原因:harbor v2.9.0 生成的docker-compose.yml使用了较新的 compose 规范,如果离线机器上装的是老版本 docker-compose(比如 1.25 以下),解析会失败。
解决:确认docker compose version输出 v2.x,或者docker-compose version输出 1.29 以上。如果版本太低,需要提前准备新版本的 docker-compose 二进制文件(arm64 版本)拷贝到离线机器上替换。
4.3 数据目录权限问题导致 registry 无法写入
现象:harbor 容器都起来了,但 push 镜像时报500 Internal Server Error,harbor-registry日志显示permission denied。
原因:data_volume指定的目录(比如/data/harbor)权限不对,registry 容器内以非 root 用户运行,无法写入。
解决:确保数据目录存在且权限正确:
sudo mkdir -p /data/harbor sudo chown -R 10000:10000 /data/harbor sudo chmod -R 755 /data/harborharbor 的 registry 容器默认以 UID 10000 运行,所以数据目录的属主需要匹配。
4.4 离线环境下 trivy 扫描组件拖垮启动
现象:install.sh卡在启动 trivy 容器,或者 trivy 容器不断重启,日志显示无法下载漏洞库。
原因:trivy 需要联网更新漏洞数据库,离线环境下它无法完成初始化,导致容器一直不健康。
解决:安装时直接禁用 trivy:sudo ./install.sh --with-trivy=false。如果已经装了,可以修改docker-compose.yml把 trivy 相关服务注释掉,然后docker compose up -d重新启动。
4.5 hostname 改了但旧配置残留导致登录异常
现象:修改harbor.yml里的hostname后重新运行install.sh,Web UI 能打开,但docker login报unauthorized或connection refused。
原因:harbor 的数据库和 redis 里缓存了旧的 hostname 相关配置,重新安装时如果没有清理旧数据,会出现配置不一致。
解决:如果只是改 hostname,建议先docker compose down,然后删除data_volume下的数据库数据(注意这会丢失已有镜像和用户数据),再重新install.sh。如果不想丢数据,需要手动改数据库里的配置,这个操作比较复杂,一般建议在初始安装时就确定好 hostname。
5. 装完之后:把 harbor 真正用起来的几个进阶技巧
harbor 装好只是第一步,离线环境里怎么让它持续可用、怎么和现有 CI/CD 流程对接,才是真正花时间的地方。这里分享几个我实际用下来比较顺手的做法。
第一个技巧是用 harbor 的复制功能做离线同步。如果你有多个离线环境,或者有一个能联网的 harbor 实例,可以配置 harbor 的 replication 规则,把镜像从一个 harbor 同步到另一个。在离线环境里,这个功能可以用来从上游 harbor 拉取镜像,避免手动docker save/load的繁琐。配置路径在 Web UI 的Administration -> Registries里添加远端 registry,然后在Replications里创建规则。注意离线环境下网络是断的,这个功能更适合「半离线」场景——即 harbor 之间网络可达,但无法访问公网。
第二个技巧是定期备份 harbor 的数据库和存储。harbor 的核心数据在 PostgreSQL 和 registry 存储目录里。我一般会写一个简单的备份脚本:
#!/bin/bash # harbor 备份脚本 BACKUP_DIR=/backup/harbor/$(date +%Y%m%d) mkdir -p "$BACKUP_DIR" # 备份数据库 docker exec harbor-db pg_dump -U postgres registry > "$BACKUP_DIR/registry.sql" # 备份 registry 存储(如果数据量大,可以用 rsync 增量备份) rsync -avz /data/harbor/registry/ "$BACKUP_DIR/registry/" # 备份配置文件 cp /path/to/harbor/harbor.yml "$BACKUP_DIR/" echo "Backup completed at $BACKUP_DIR"这个脚本的逻辑是先 dump 数据库,再同步 registry 存储目录,最后备份配置文件。参数上,pg_dump -U postgres registry里的registry是 harbor 默认的数据库名,如果改过需要对应调整。备份频率看你的镜像更新频率,一般每天一次足够。
第三个技巧是用 harbor 的 webhook 对接内部通知系统。harbor 支持在镜像 push、pull、删除等事件时触发 webhook。在离线环境里,你可以把 webhook 指向内部的一个 HTTP 服务,用来做审计日志或者触发下游构建。配置在项目的Webhooks标签页里,填一个内网可达的 URL 即可。
最后一个我想强调的是版本升级的注意事项。harbor 的离线升级不能直接覆盖安装,需要先备份数据,然后下载新版本的离线包,修改harbor.yml里的配置(新版本可能有新增参数),再运行install.sh。升级过程中数据库会自动迁移,但如果跨的版本太多(比如从 v2.5 直接到 v2.9),建议逐个大版本升级,避免迁移脚本出错。我自己的习惯是每次升级前先在测试环境跑一遍,确认没问题再动生产。
希望帮到你。
本文还有配套的精品资源,点击获取