简介本资源为 Harbor v2.9.0 的离线安装包专为 arm64 架构环境打造面向需要在国产化服务器或 ARM 平台上快速部署私有镜像仓库的运维与开发人员。包内共 6 个文件以 sh 安装脚本、gz 离线镜像包、prepare 预处理文件、tmpl 配置模板及 license 授权文件为主整体约 722.35MB覆盖从环境准备到服务启动的完整流程。使用前需预先安装 docker 与 docker-compose执行 install.sh 即可一键完成 Harbor 部署省去在线拉取镜像的繁琐步骤。目前已有 969 人学习下载适合希望在内网或离线场景下搭建企业级镜像仓库、并需要稳定可复现安装方案的读者参考使用。1. 从一台没有外网的 ARM 服务器说起harbor-v2.9.0 离线包到底解决了什么机房里有台 ARM 架构的服务器操作系统是麒麟或者统信网口插着内网线浏览器打不开任何外部地址。这时候领导说要把容器镜像仓库搭起来你打开官方文档准备docker pull发现连 Docker 本身都装不上——这就是 harbor-v2.9.0 离线安装包存在的意义。它把 Harbor 核心组件、依赖镜像、安装脚本全部打包成一个压缩文件你只需要把包传到服务器上解压、改配置、执行安装脚本一套私有镜像仓库就能在内网跑起来。arm64 架构和 x86 最大的区别在于镜像的 CPU 指令集不同官方发布的离线包里如果只包含 amd64 镜像你在 ARM 服务器上docker load之后启动容器会直接报exec format error所以必须确认下载的是 arm64 版本的离线包。这篇文章面向的是需要在 ARM 服务器上部署私有镜像仓库的运维和开发人员尤其是那些内网环境无法访问 Docker Hub、无法在线拉取镜像的场景。我会把整个流程拆成可复现的步骤包括环境准备、离线包结构解析、配置修改、安装验证以及我在实际部署中踩过的几个坑。2. 动手之前ARM 服务器环境检查与离线包结构拆解2.1 确认 CPU 架构和操作系统兼容性在把离线包传上去之前先在目标服务器上执行几条命令确认环境。ARM 架构不是只有一种aarch64 和 armv7l 的指令集不同Harbor 官方离线包通常只支持 aarch64。另外操作系统的内核版本和 Docker 版本也有最低要求CentOS 7 的内核 3.10 在跑 Harbor v2.9.0 时可能会遇到 overlay2 存储驱动的问题。# 确认 CPU 架构输出 aarch64 才符合 arm64 离线包的要求 uname -m # 查看操作系统发行版和版本号 cat /etc/os-release # 检查内核版本建议 4.x 以上 uname -r # 确认 Docker 是否已安装及版本 docker version --format {{.Server.Version}} # 检查 docker-compose 是否可用 docker-compose version这几条命令的输出决定了你接下来要不要先升级内核或者重装 Docker。我遇到过一台服务器uname -m输出armv7l结果离线包里的镜像全部无法加载只能重新找 armv7 的构建版本。Docker 版本建议在 20.10 以上docker-compose 用 v2 版本v1 的 Python 实现在 ARM 上偶尔会有依赖问题。2.2 离线包目录结构说明把 harbor-offline-installer-v2.9.0-arm64.tar.gz 解压之后你会看到这样的目录结构harbor/ ├── harbor.v2.9.0.tar.gz # 所有组件镜像的打包文件 ├── harbor.yml.tmpl # 配置文件模板 ├── install.sh # 安装脚本 ├── prepare # 环境准备脚本 └── common.sh # 公共函数库harbor.v2.9.0.tar.gz是核心里面包含了 registry、portal、core、jobservice、db、redis、nginx 等组件的 arm64 镜像。install.sh会调用prepare脚本生成最终配置然后通过 docker-compose 启动所有容器。harbor.yml.tmpl是模板你需要复制一份改名为harbor.yml再修改。注意不要直接修改harbor.yml.tmpl安装脚本会覆盖它。正确做法是cp harbor.yml.tmpl harbor.yml然后编辑harbor.yml。2.3 导入镜像与目录规划离线安装的核心操作之一是把harbor.v2.9.0.tar.gz里的镜像导入到本地 Docker 中。这个文件通常有 2GB 左右导入过程需要几分钟。# 解压离线安装包 tar -xzf harbor-offline-installer-v2.9.0-arm64.tar.gz # 进入解压后的目录 cd harbor # 导入所有组件镜像到本地 Docker docker load -i harbor.v2.9.0.tar.gz # 确认镜像已导入应该能看到 goharbor/ 开头的多个镜像 docker images | grep goharbordocker load的输出会显示每个镜像的加载进度如果中途报错no space left on device说明/var/lib/docker所在分区空间不够至少预留 10GB。导入完成后用docker images确认正常应该看到goharbor/harbor-core、goharbor/harbor-portal、goharbor/registry-photon等十几个镜像标签都是v2.9.0。3. 配置 harbor.yml从模板到可运行实例的关键参数3.1 必须修改的五个配置项harbor.yml里有几百行配置但离线安装场景下真正需要改的只有几个。下面是一个最小可用的配置示例# 主机名可以是 IP 也可以是域名客户端通过这个地址访问仓库 hostname: 192.168.1.100 # HTTP 配置内网环境通常不配证书直接用 HTTP http: port: 80 # HTTPS 配置如果不需要 HTTPS 就整段注释掉 # https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path # 管理员初始密码第一次登录用 admin 加这个密码 harbor_admin_password: Harbor12345 # 数据存储目录确保所在分区有足够空间 data_volume: /data # 数据库密码离线安装用默认的就行 database: password: root123 max_idle_conns: 100 max_open_conns: 900hostname这一项最容易翻车。如果你填了localhost或者127.0.0.1其他机器访问不了如果填了域名但内网 DNS 没解析docker login 会报no such host。我一般直接填服务器的内网 IP简单直接。data_volume默认是/data如果这个分区空间小改成大分区的路径比如/opt/harbor/data。3.2 关闭 HTTPS 的正确姿势内网环境没有证书直接用 HTTP 最省事。但要注意Harbor 的配置文件里 HTTPS 段如果保留但证书路径无效安装脚本会报错退出。正确做法是把整个https段用#注释掉而不是留空。# 错误做法保留 https 段但不填证书 https: port: 443 # 正确做法整段注释 # https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path注释掉 HTTPS 之后客户端 docker login 时需要配置 insecure-registries这个后面会讲。3.3 存储驱动与数据持久化Harbor 默认使用本地文件系统存储镜像data_volume指向的目录会挂载到 registry 容器里。如果你希望用外部存储比如 NFS 或者 S3需要额外配置storage_service段。离线安装场景下大多数情况用本地存储就够了。# 本地存储配置默认就是 filesystem storage_service: filesystem: rootdirectory: /storage # 如果 data_volume 是 /data实际存储路径是 /data/registry安装完成后/data目录下会出现database、redis、registry、jobservice等子目录分别对应不同容器的持久化数据。备份的时候直接打包整个/data目录就行。4. 执行安装与验证从 install.sh 到推送第一个镜像4.1 运行安装脚本配置改好之后执行安装脚本。这个脚本会做几件事检查 Docker 和 docker-compose、生成最终配置、启动所有容器。# 在 harbor 目录下执行安装 ./install.sh # 如果之前装过 Harbor需要先清理旧容器和网络 # docker-compose down # rm -rf /data/database /data/registry安装脚本的输出会显示每个组件的启动状态。正常情况最后会打印----Harbor has been installed and started successfully.----。如果中途报错最常见的原因是端口被占用。Harbor 默认用 80 和 443如果服务器上已经有 nginx 或者 apache 在跑需要改harbor.yml里的端口。# 检查 80 端口是否被占用 ss -tlnp | grep :80 # 如果被占用修改 harbor.yml 里的 http.port 为其他端口比如 80804.2 验证容器状态和 Web 界面安装完成后用 docker-compose 查看容器状态# 查看所有 Harbor 容器状态 docker-compose ps # 正常应该看到 9 个容器状态都是 Up 或 healthy # harbor-core、harbor-portal、harbor-jobservice、harbor-registry # harbor-db、redis、nginx、registryctl、harbor-log然后打开浏览器访问http://192.168.1.100应该能看到 Harbor 的登录页面。默认用户名admin密码是你在harbor.yml里设置的harbor_admin_password。登录之后创建一个测试项目比如library然后尝试推送一个镜像。4.3 客户端配置与镜像推送在另一台机器上推送镜像之前需要先配置 Docker 信任这个 HTTP 仓库。编辑/etc/docker/daemon.json{ insecure-registries: [192.168.1.100] }然后重启 Dockersystemctl restart docker接下来登录并推送镜像# 登录 Harbor docker login 192.168.1.100 # 输入用户名 admin 和密码 # 给本地镜像打标签 docker tag nginx:latest 192.168.1.100/library/nginx:latest # 推送镜像 docker push 192.168.1.100/library/nginx:latest # 拉取镜像验证 docker pull 192.168.1.100/library/nginx:latest推送成功后在 Harbor 的 Web 界面里能看到library/nginx这个仓库和对应的标签。如果推送时报http: server gave HTTP response to HTTPS client说明客户端的insecure-registries没配好检查 daemon.json 的格式和 Docker 是否重启。5. 避坑指南ARM 离线安装 Harbor 的五个血泪教训5.1 镜像架构不匹配导致容器启动失败现象docker-compose up之后容器状态一直是Restarting查看日志报exec format error。原因下载的离线包是 amd64 版本里面的镜像在 arm64 服务器上无法执行。解决确认离线包文件名包含arm64或aarch64用docker inspect查看镜像的 Architecture 字段。# 查看镜像架构 docker inspect goharbor/harbor-core:v2.9.0 --format {{.Architecture}} # 输出应该是 arm645.2 磁盘空间不足导致镜像导入中断现象docker load执行到一半报no space left on device部分镜像导入失败。原因/var/lib/docker所在分区空间不够Harbor 所有镜像加起来大约 2.5GB加上解压后的临时文件至少需要 10GB 可用空间。解决清理无用镜像和容器或者把 Docker 的># 查看 Docker 根目录位置 docker info | grep Docker Root Dir # 清理未使用的镜像和容器 docker system prune -a5.3 端口冲突导致 nginx 容器无法启动现象install.sh执行到最后报错提示port is already allocated。原因服务器上已经有服务占用了 80 或 443 端口。解决修改harbor.yml里的http.port为其他端口比如 8080然后重新执行./install.sh。http: port: 80805.4 客户端 insecure-registries 配置不生效现象docker login报http: server gave HTTP response to HTTPS client。原因/etc/docker/daemon.json格式错误或者修改后没有重启 Docker。解决检查 JSON 格式确保insecure-registries数组里填的是 Harbor 的 hostname 和端口如果改了端口要带上。{ insecure-registries: [192.168.1.100:8080] }5.5 数据目录权限问题导致容器反复重启现象harbor-db或harbor-registry容器不断重启日志报Permission denied。原因data_volume指定的目录权限不对容器内的进程无法写入。解决确保/data目录存在且权限为 755或者手动创建子目录并赋予正确权限。mkdir -p /data chmod 755 /data # 重新安装 docker-compose down ./install.sh6. 进阶技巧离线环境下的镜像同步与仓库备份6.1 用 Harbor 的复制功能做多节点同步如果你有两台 ARM 服务器一台做主仓库一台做备仓库可以用 Harbor 的复制功能做镜像同步。在 Web 界面里进入「仓库管理」添加目标仓库的地址和凭证然后创建复制规则。这个功能在离线环境里特别有用因为主仓库挂了之后备仓库可以直接顶上。配置复制规则时需要注意目标仓库的hostname必须和harbor.yml里配置的一致否则会报证书或者连接错误。如果两边都是 HTTP确保客户端的 insecure-registries 里两个地址都加了。6.2 定期备份 /data 目录和数据库Harbor 的所有数据都在data_volume指定的目录里备份就是打包这个目录。但直接打包有个问题数据库文件在容器运行时会处于不一致状态。正确做法是先停掉 Harbor再打包。# 停止 Harbor cd /path/to/harbor docker-compose down # 打包数据目录 tar -czf harbor-backup-$(date %Y%m%d).tar.gz /data # 重新启动 docker-compose up -d如果不想停机可以单独备份数据库# 进入数据库容器执行 pg_dump docker exec harbor-db pg_dump -U postgres -d registry registry-backup.sql6.3 验证备份可用性的方法备份文件躺在那里不代表能用。我一般会定期做一次恢复演练找一台测试机装好 Docker 和 docker-compose把备份的/data目录解压到相同路径然后执行docker-compose up -d看 Harbor 能不能正常启动、之前的镜像和项目还在不在。这个演练有个细节要注意如果备份时的harbor.yml里hostname和测试机的 IP 不同恢复后需要改harbor.yml再重启。另外数据库的密码如果改过恢复后也要保持一致。从那以后我每次部署完 Harbor都会在/data目录下放一个README文件写清楚当前版本、配置要点和备份命令。这个习惯帮我省了好几次重新翻文档的时间。希望帮到你。本文还有配套的精品资源点击获取