ARM离线环境部署Harbor v2.9.0:避坑指南与实战
简介面向需要在国产化或 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之前离线机器上必须已经具备这些条件依赖项检查命令要求Dockerdocker version20.10 以上支持 arm64Docker Composedocker compose version或docker-compose versionv2 或 v1.29 以上磁盘空间df -h /data至少 40GB 可用内存free -h至少 4GB推荐 8GB端口ss -tlnp | grep -E 80|443|5432|637980/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-trivyfalse # 安装完成后查看容器状态 docker compose ps # 或者如果是 docker-compose v1 docker-compose psinstall.sh的执行逻辑是先检查harbor.yml是否存在且格式正确然后调用prepare脚本生成docker-compose.yml接着加载harbor/images目录下的所有镜像 tar 包最后用 docker-compose 启动所有服务。整个过程如果镜像加载失败脚本会报错退出。参数方面--with-trivyfalse表示不安装镜像扫描组件这在离线环境里很实用因为 trivy 的漏洞库需要联网更新离线环境下它基本没法工作。类似的可选组件还有--with-notary镜像签名、--with-chartmuseumHelm chart 仓库按需开启。安装完成后用docker compose ps应该看到所有容器状态是Up或healthy。harbor 的核心组件包括harbor-coreAPI 服务、harbor-portalWeb UI、harbor-registry镜像存储、harbor-dbPostgreSQL、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 Errorharbor-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 需要联网更新漏洞数据库离线环境下它无法完成初始化导致容器一直不健康。解决安装时直接禁用 trivysudo ./install.sh --with-trivyfalse。如果已经装了可以修改docker-compose.yml把 trivy 相关服务注释掉然后docker compose up -d重新启动。4.5 hostname 改了但旧配置残留导致登录异常现象修改harbor.yml里的hostname后重新运行install.shWeb 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建议逐个大版本升级避免迁移脚本出错。我自己的习惯是每次升级前先在测试环境跑一遍确认没问题再动生产。希望帮到你。本文还有配套的精品资源点击获取