资讯动态

arm64下Harbor离线安装完整指南:依赖体检与排错

发布时间:2026/10/8 8:33:49 来源:尧图企业网站定制
简介面向在 arm64 架构服务器上部署 Harbor 容器镜像仓库的运维与开发人员这份离线安装资源解决了内网环境中无法在线拉取 Harbor 及其依赖组件的问题。资源包采用 gz 压缩格式共 6 个文件集成一键安装入口 install.sh、公共函数脚本 common.sh、环境预检与配置模板 prepare 和 harbor.yml.tmpl同时包含离线镜像压缩包与授权文件整体大小约 722MB覆盖从环境检查、配置调整到服务启动的主要过程。已有 969 人学习下载适用于在 ARM 服务器上快速搭建私有镜像仓库的 Kubernetes 或 Docker 场景借助这套材料可以避免手动拼装多个组件与镜像显著减少离线部署时的遗漏。确认 Docker 与 Docker Compose 已就绪后解压资源包并按脚本顺序执行即可完成 Harbor v2.9.0 安装适合内网生产环境、离线交付或统一镜像管理需求也为后续版本升级与问题排查提供了清晰的参照。1. 离线装 Harbor 的难点不在 Harbor在 arm 机器的环境债生产网段不连外网、服务器上是 arm64 芯片、还要让内网各台机器都能推送和拉取镜像——这是 harbor v2.9.0 离线安装在 arm 架构下最典型的诉求。标题里三个限定词凑在一起意味着要面对的已经不是「去官网下个安装包」这么简单离线安装包本身几个 GB目标机器上的 docker 版本可能停在 1.13docker-compose 可能根本不存在arm 变体会把 x86 环境里顺利的事情重新变成一场 DIY。Harbor 本质是一套用 docker compose 编排的多容器应用离线安装的核心只有两件事把官方离线包完整搬进内网再让这台 arm 服务器满足它运行所需的 docker、compose、python、openssl 等依赖。这两件事做完install.sh 基本不会卡后面都是配置细节和排错。这篇文章按「资源准备 → 依赖体检 → 配置安装 → 避坑 → 验证」的顺序展开适合在内网搭私有镜像仓库、或给 arm 服务器做容器基础设施的运维和开发参考。文中给出的路径是我在实际部署里反复验证过的常见做法参数和踩坑点都可以直接抄。2. 先把 arm 离线资源备齐下载路径、校验口令与内网传输在 arm 环境下装 Harbor第一道门槛不是安装而是「拿到正确的离线包并完整传进内网」。很多人在这一步就翻车拿了一个来源不明的包传到 arm 机器或者用 scp 传到一半中断解压时出现 CRC 错误。下面先说明为什么不需要刻意去找「arm 版离线包」再给出一套可抄的下载、校验、传输流程。2.1 为什么离线包不分「arm 版」镜像归档与 Docker manifestHarbor v2.9.0 的离线安装包 harbor-offline-installer-v2.9.0.tgz解压后会有 install.sh、harbor.yml.tmpl、common.sh以及一个体积最大的 harbor.v2.9.0.tar.gz。这个 tar.gz 里不是源码也不是传统安装包而是用 docker 导出命令归档的一组镜像包含 harbor-core、harbor-registry、harbor-portal、harbor-db、harbor-redis、nginx 等核心组件。执行 install.sh 时脚本会调用 docker load 把这个归档整体装载到当前节点的 docker 里。因为 Docker 镜像在 registry 上以 multi-arch manifest多架构清单发布同一个 tag 下会同时挂 amd64、arm64 等不同架构的镜像层。docker load 时daemon 会读当前机器的 CPU 架构从 manifest 里选取匹配的层来加载所以离线包里不需要区分「x86 版」和「arm 版」只要镜像发布方把 arm64 变体打了进去arm64 机器就能直接用。Harbor 2.x 中后期已经补齐官方镜像的 arm64 支持2.9 的离线包在 arm64 服务器上可以正常 load。反过来如果你的芯片是 armv7 或更老的 32 位 ARM官方镜像可能没有对应变体那就必须从源码自行构建已经不属于「离线安装」的讨论范畴。2.2 下载、校验、解压把安装包变成可信任的安装目录先在可联网的机器上把离线包拉下来再做两层校验最后解压到固定路径。# 在可联网的机器上下载 Harbor v2.9.0 离线安装包-c 支持断点续传 wget -c https://github.com/goharbor/harbor/releases/download/v2.9.0/harbor-offline-installer-v2.9.0.tgz # 同时拉取同目录下的 .asc 签名文件用于 GPG 校验 wget -c https://github.com/goharbor/harbor/releases/download/v2.9.0/harbor-offline-installer-v2.9.0.tgz.asc # 1) 先做 SHA256 校验输出应该与官方 Release 页公布的那串值完全一致 sha256sum harbor-offline-installer-v2.9.0.tgz # 2) 如果有发布公钥再做 GPG 签名校验防止包被替换 gpg --verify harbor-offline-installer-v2.9.0.tgz.asc harbor-offline-installer-v2.9.0.tgz # 3) 解压到 /opt得到 harbor 目录 tar -zxf harbor-offline-installer-v2.9.0.tgz -C /opt cd /opt/harbor ls -l逻辑说明第一步是防下载损坏离线包是 GB 级文件任何一次中断重连都可能让归档内部数据错位导致 docker load 时报 invalid tar header。第二步是防供应链替换尤其当你从别人的 U 盘或内网中转目录拿到安装包时GPG 校验能确认这个离线包确实来自 goharbor 官方签名。第三步解压后先看一眼 install.sh 和 common.sh 的权限与内容如果脚本里有不明的外部下载动作要立刻停下来排查。参数说明-c是 wget 的断点续传对不稳定的内网中转机很关键-C /opt指定解压目录一般我会固定保留 /opt/harbor 这个路径避免后续脚本里的相对路径出问题。ls 之后应该能看到 harbor.v2.9.0.tar.gz、harbor.yml.tmpl、install.sh、common.sh、LICENSE 这几个文件。2.3 内网传输与磁盘预留rsync 比 scp 稳空间按三个位置算离线包准备好之后传输到内网 arm 服务器这一步常见做法是用 rsync 而不是 scp。rsync 对中断的容忍度更高并且能在传输后做完整性校验。# 使用 rsync 从联网中转机推到内网 arm 服务器-P 保留进度和断点续传 rsync -avP --progress harbor-offline-installer-v2.9.0.tgz user10.0.0.11:/opt/ # 传输完成后在 arm 上再算一次哈希与源机比对 ssh user10.0.0.11 cd /opt sha256sum harbor-offline-installer-v2.9.0.tgz参数说明-a归档模式保留权限与时间戳-v显示明细-P等价于--partial --progress传大文件中断后再次执行能接着传。不建议用服务器自带面板的网页上传大文件那些工具通常没有可靠性校验传完也不告诉你文件是否完整。哈希比对这一步不能省尤其当传输链路中还有跳板机或移动介质时任何一次拷贝都可能引入坏块。空间预留按三个位置算放置离线包的目录/opt、docker 的数据目录/var/lib/docker、Harbor 数据卷/data 或你之后在 harbor.yml 里指定的 data_volume。arm 单板或小规格服务器往往只有一块盘这三个位置大概率在同一分区所以只df -h /不够。安装前分别确认三个路径至少保证整机有 20GB 以上空余生产使用建议给 /data 单独挂盘避免后续镜像存储和系统日志互相挤占。提示离线包、解压后的镜像归档、docker 镜像层三者在安装过程中会同时占空间。计算容量时按「安装包 2 倍 数据卷预估」来留别只盯着 tar 包体积。3. 前置依赖体检arm 上的 docker、compose 与 openssl 一个都不能少离线安装领域最容易出现一种错觉「反正离线包自带镜像目标机上只要有个 docker 就能跑」。实际部署时翻车的往往是另一种情况二进制是有的但版本不对依赖不全报错还看不懂。Harbor v2.9.0 对运行时的要求并不花哨但每一条都卡在硬条件上arm 环境尤其明显。3.1 版本太旧等于没装docker 20.10、compose V2 与 python3 的底线Harbor v2.9.0 对 docker 引擎的要求是 20.10.0 以上。这个要求不是文档里的一句摆设而是因为离线包里的镜像大量使用 multi-arch manifestdocker 18 及更早版本对 manifest list 的支持不完整在 arm 上可能出现「明明 load 成功docker images 里却看不到镜像」的诡异状态。与此同时install.sh 在寻找 compose 时会优先使用docker compose子命令V2 插件其次才找独立的docker-compose程序如果两者都没有脚本直接退出不会给你任何机会往下走。另一个容易被忽略的点是 prepare 阶段。install.sh 里的 prepare 是 python 脚本会自动检测 python3 是否存在。老旧发行版如果只有 python2prepare 会走向 Python 2 分支但 2.9 的脚本对 Python 2 的支持已经很弱常见报错是语法错误。openssl 同理prepare 需要它生成自签证书和内部通信密钥openssl 版本太低时可能直接生成出「不合法」的密钥后面容器全起、登录就报证书错误。所以在 arm 机器上docker 20.10、compose V2、python3.6、openssl 1.1 这四样都要先确认缺哪样补哪样再进入安装。3.2 三条命令完成前置体检# 1) docker 必须以服务端身份正常响应且版本不低于 20.10 docker version --format server{{.Server.Version}} client{{.Client.Version}} # 2) compose 二选一能输出版本号才算数 docker compose version || docker-compose version # 3) prepare 阶段依赖的 python 与 openssl python3 --version openssl version逻辑说明第一条命令如果 server 段为空或直接报 cannot connect to the Docker daemon先解决 docker 服务再谈 Harbor。如果只有 client 段说明 docker 服务没起来或当前用户不在 docker 组里。第二条命令里的||表示前面失败才执行后面的适合排查「到底有没有 compose」这类二选一场景。第三条里 python3 版本可以低些但必须存在openssl 输出 1.1 以上基本放心。参数说明--format里的 Server.Version 与 Client.Version 是 docker 的 Go 模板字段docker 17.05 之后都支持如果老版本不认这个模板就直接跑docker version看完整输出。如果第 2 步发现 docker-compose 输出的是 1.18 之类的版本不要在该机器上硬装 Harbor继续看 3.3 的处理方式。3.3 离线补 docker-compose把 V2 二进制放进 cli-pluginsarm64 上补 compose常见做法是把 Compose V2 的二进制直接放到 docker 的 cli-plugins 目录同时保留独立的 docker-compose 命令。# 在能联网的 arm64 机器上下载 Compose V2 的 aarch64 二进制 curl -L https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-linux-aarch64 -o /usr/local/bin/docker-compose chmod x /usr/local/bin/docker-compose # 把它放进 cli-plugins 目录供 docker compose 子命令调用 mkdir -p /usr/local/lib/docker/cli-plugins ln -sf /usr/local/bin/docker-compose /usr/local/lib/docker/cli-plugins/docker-compose # 验证两种调用方式都能输出版本号 docker compose version docker-compose version逻辑说明Compose V2 是单独编译的 Go 二进制不依赖 python放进 /usr/local/bin 只是提供 docker-compose 命令放进 cli-plugins 则是让docker compose子命令能找到它。两个位置都配置兼容性最好因为 install.sh 对 compose 的探测顺序在不同小版本里并不完全一致。用ln -sf建立软链后后续升级 compose 只需要替换 /usr/local/bin/docker-compose 这一个文件cli-plugins 里的链接不用动。参数说明v2.24.5是 Compose V2 的一个较新发布版本可以换成实际存在的更新 tag文件名里的 linux-aarch64 对应 64 位 arm如果你的环境是 armv7需要换 linux-armv7 文件。如果执行时报Exec format error就是拿错了架构重新下载对应平台文件即可不要试图用 x86_64 的二进制硬跑。如果目标机完全无法联网就在联网机器上把 docker-compose-linux-aarch64 下载后用第二章的 rsync 方式拷进去再加执行权限。需要强调的是compose 二进制是整条链路里唯一分架构的可执行文件离线包里的镜像归档不分架构但这个二进制必须和 arm 处理器匹配。4. 改配置、跑安装harbor.yml 里 5 个参数和 install.sh 的三个阶段前置依赖确认完毕接下来的动作可以总结成一句话把 harbor.yml.tmpl 复制成 harbor.yml按内网需求修改再执行 install.sh。但「改配置」是整个离线安装里最容易被低估的一步很多「harbor 推送失败 get https://192.168.x.x/v2/」类问题根源其实在 harbor.yml 的 hostname 和端口配错了跟 Harbor 本身没半点关系。4.1 harbor.yml.tmpl 转 harbor.ymlhostname 与 http/https 的取舍先做最基础的复制cd /opt/harbor cp harbor.yml.tmpl harbor.yml # 用编辑工具打开下文的改动都集中在这个文件里 vi harbor.yml打开模板后第一件事是明确这台 arm 服务器对外提供 http 还是 https。内网离线环境里大多数团队没有企业 CA默认先跑 http。这样省去在每台客户机的 docker daemon 里配置证书信任代价是需要把 registry 地址写进所有客户端的 insecure-registries。如果对安全要求高就走 https 并把 Harbor 生成的 CA 证书分发给各台机器。两种模式在 harbor.yml 里的写法完全不同http 模式保留http.port并把整个https:段注释掉https 模式则相反把 http 段注释、https 段打开并配置 certificate 和 private_key 路径。hostname 这一项是理解 Harbor 的关键Harbor 会把 hostname 写进自己生成的 registry 配置里客户端登录后拿到的 v2 接口地址也由它决定。如果填的是本机 hostname 或 127.0.0.1其他机器用docker login 10.0.0.11即使能登录后续 push 时也会被带到客户端解析不了的域名或回环地址上表现就是连接被拒或超时。所以这里要填客户端实际访问的地址通常就是内网 IP或已在 DNS 完成解析的内网域名。4.2 必调的 5 个参数表格与修改示例配置项默认值建议hostname本机名内网 IP 或已有 DNS 域名http.port80被占用时改成 8080 等高位端口https.port443用 http 模式时注释整个 https 段harbor_admin_passwordHarbor12345安装前一次性设定装完再改麻烦database.passwordroot123安装前设定事后改容易造成账号不一致用一段实际修改示意# hostname 改成内网 IP hostname: 10.0.0.11 # http 端口80 在 arm 机器上很可能被其他服务占掉改成 8080 http: port: 8080 # https 段整体注释暂不使用 https 时 # https: # port: 443 # certificate: /your/cert.pem # private_key: /your/key.pem # admin 初始密码安装后立刻能登录别留着默认值 harbor_admin_password: Harbor!2024 # 数据库密码会影响 postgres 容器内的环境变量 database: password: HarborDb!2024 max_idle_conns: 50 max_open_conns: 100逻辑说明hostname 改成 IP 后所有客户端 push 都会拿这个 IP 去请求 registry 的 /v2/ 接口端口从 80 改到 8080 后客户端 docker daemon 的 insecure-registries 也要写10.0.0.11:8080两边必须一致否则会出现「登录成功但 push 超时」的灵异现场。harbor_admin_password 和 database.password 在容器首次启动前写入配置才有意义容器启动后再改 Web 层密码数据库层密码如果没同步反而新增故障点。参数说明database 段里的 max_idle_conns、max_open_conns 是连接池参数内网小规模使用保持默认即可。arm 机器内存如果只有 8GB 左右建议把 max_open_conns 从默认 100 下调到 50能明显减少 postgres 容器的内存压力其余参数不要乱动。4.3 install.sh 的三个阶段load、prepare、up配置改完就可以跑安装。install.sh 不是一条命令刮完所有事它会顺序完成三个阶段先检查运行时并 docker load 镜像归档再运行 prepare 生成 docker-compose.yml最后调用 compose 把全部容器拉起来。cd /opt/harbor # 首次安装直接前台跑方便看到 load 和 prepare 的输出 ./install.sh # 不需要内置漏洞扫描组件时就保持默认不加 --with-trivy # 如果还想开 chartmuseum 存 helm chart追加 --with-chartmuseum执行时如果 docker load 阶段日志很长那是正常现象十几个镜像逐个导入需要几分钟。load 完成后会看到 prepare 输出它负责生成 docker-compose.yml、nginx 配置和自签证书最后是 compose 的一串 Creating/Created 输出。第一次跑不建议加-d前台输出一旦报错能立刻看到卡在哪个容器比事后翻日志省时间。容器拉起来后验证状态# 在 /opt/harbor 目录下执行确保能读到 compose 编排文件 cd /opt/harbor # 等 1-2 分钟让数据库和 redis 完成初始化再查状态 docker compose ps # 如果状态含糊看每个容器最近一行的日志 docker compose logs --tail20这里docker compose在较新版本里等价于docker-compose。如果 compose ps 里 harbor-db 显示 healthy、harbor-core 显示 running、nginx 端口监听正常再往下就只剩客户端推送验证了。注意容器初始化阶段 harbor-portal 有可能短暂显示 starting耐心等 healthy 再打开 Web 页面。提示install.sh 没加 --with-trivy 时harbor-trivy 相关容器不会出现在 compose ps 里这属于正常现象不用担心少装。5. 避坑arm 离线环境最常翻车的 5 个「现象 → 原因 → 解决」这一章把 arm 离线环境部署时见过、踩过的高频问题按现象、原因、解决三段式写出来。前三个跟网络和证书有关后两个更贴近 arm 机器特有的磁盘与权限问题顺序按出现频率排。5.1 harbor 推送失败 get https://192.168.x.x/v2/握手阶段就断了现象在某台客户机上执行 docker push报错形如get https://10.0.0.11:443/v2/: dial tcp 10.0.0.11:443: connect: connection refused或者另一种更常见的error during connect: Post https://10.0.0.11:443/v2/: http: server gave HTTP response to HTTPS client原因docker 客户端做 push 前会先 GET registry 的 /v2/ 接口完成握手。第一类报错说明 Harbor 的 nginx 并没有在 443 端口监听多半是 harbor.yml 里只开了 http 端口第二类报错说明 Harbor 监听在 80 端口但客户端默认用 https 访问。实际项目里更多是第二类也就是服务起来了客户端协议对不上。解决确认 Harbor 实际监听端口然后在所有需要推送的机器上把 registry 地址写进 docker daemon 的 insecure-registries# 修改 /etc/docker/daemon.json加入实际访问的 IP 和端口 { insecure-registries: [10.0.0.11:8080] } # 重启 docker 让配置生效如果由 systemd 托管reload 即可 sudo systemctl reload docker逻辑说明insecure-registries 是 docker daemon 层面的信任名单名单里的地址会跳过 https 握手与证书校验。这里填的端口必须和 harbor.yml 里 http.port 一致两个数字任何一边不同都会表现为「登录成功但 push 一堆报错」。检查顺序建议是先curl -I http://10.0.0.11:8080/v2/看 Harbor 是否应答再检查 daemon 配置最后才怀疑防火墙。很多 arm 小服务器上 firewalld 默认开着8080 入站被挡也会造成同样的 refused 报错。5.2 install.sh 报找不到 docker-compose或版本过低直接退出现象执行 install.sh 时脚本输出 docker-compose is not found 或 no compose command available随后直接退出或者机器上存在 docker-compose 1.18但脚本认为版本不受支持。原因Harbor v2.9.0 的 install.sh 探测 compose 时优先找docker compose子命令再找docker-compose独立命令。目标是老发行版系统里只有旧 pip 装的 docker-compose 1.18它在 Compose V2 的语法和判断逻辑下会被直接判为不可用。解决按 3.3 的方式准备 Compose V2 的 aarch64 二进制。需要额外提醒如果机器上已经存在 /usr/bin/docker-compose先把旧文件改名为 docker-compose.bak否则 install.sh 探测到它存在就直接拿去用旧版本依旧会报版本错误。离线环境没有 yum 源卸载后就用拷进去的 /usr/local/bin/docker-composePATH 顺序里 /usr/local/bin 通常排在前面不会走回旧命令。5.3 x509: certificate has expired or is not yet valid内网时间不同步现象docker login 或 docker push 时报x509: certificate has expired or is not yet valid原因Harbor prepare 阶段用 openssl 生成自签 CA 和服务器证书证书有效期判断依据本机当前时间。内网 arm 机器如果长期断电或没接 NTP系统时间可能停在几个月甚至几年前openssl 生成证书时系统认为当前时间不在有效范围内客户端校验自然失败。解决装之前在三台关键节点上执行date确保时间差异在两分钟以内。离线环境通常没有 NTP 服务器常见做法是在可联网时先对一次时间进入内网后自行维护临时验证的话直接date -s 2024-08-01 12:00:00修正到真实时间后再执行 install.sh。时间不同步还会连累 Harbor 登录 token 的过期判定表现就是登录后很快失效这类问题看日志很难定位最先怀疑时间。5.4 磁盘打满docker load 中途报 no space left现象install.sh 执行到 docker load 阶段时报write /var/lib/docker/overlay2/... no space left on device有的机器以 tar 解压失败的形式出现。原因arm 单板或小规格服务器的根分区往往不大/var/lib/docker 和 /opt 在同一块盘上。离线包、解压后的镜像归档、docker 镜像层三者在安装过程中同时占用空间容量很容易瞬间被吃满。解决安装前执行df -h / /var/lib/docker /data把三个路径单独看清楚。如果 /data 不在独立挂载点后续 Harbor 存储镜像会继续挤占同一块盘。生产环境最低限度给 Harbor 数据卷划一块独立盘安装时映射到 /data。空间确实紧张的话可以先把离线包解压到 /opt装完立即删除 tar.gz 和 harbor.v2.9.0.tar.gz能省出约一倍空间但 /var/lib/docker 里的镜像层占用省不掉只能扩容。5.5 harbor-db 容器反复重启Harbor 页面 503现象compose ps 里 harbor-db 一直处于 Restarting 状态Web 页面访问直接 503docker compose logs db 里能看到权限相关或数据库崩溃日志。原因Harbor 数据卷 /data 的属主不对postgres 容器以特定 UID 启动写不进 /data/database另一种常见原因是 data_volume 里残留了旧版本 Harbor 的数据新版本脚本直接挂载时数据库起不来。解决先执行docker compose logs db --tail50判断是哪一类。权限问题就修正数据目录属主Harbor 的 postgres 容器常见 UID 是 999执行chown -R 999:999 /data/database后重启容器确定是旧数据残留时不要试图覆盖修复按官方升级流程处理测试环境可以直接换一个 data_volume 路径。arm 环境里的崩溃日志有时长得像 postgres 自身的原生报错容易误判成架构不兼容先查权限和时间通常更快。6. 把 Harbor 当成生产系统全链路验证与升级时的三个长期动作装完不是终点。真正要验证的是「另一台机器能不能正常推、正常拉」。我的验证习惯是三步走第一浏览器访问 http://10.0.0.11:8080用 admin 登录看 Web 界面是否正常第二在客户机上 docker login登录成功只是第一步真正能信的是 push 一次再 pull 一次第三看 /data 目录里有没有实际写入镜像层数据。三步都过Harbor 才算真正落地。# 在另一台客户机执行完整验证链路 docker login 10.0.0.11:8080 -u admin docker tag busybox:latest 10.0.0.11:8080/library/busybox:test docker push 10.0.0.11:8080/library/busybox:test docker rmi 10.0.0.11:8080/library/busybox:test docker pull 10.0.0.11:8080/library/busybox:test这一串命令全部通过Harbor 的核心链路就算彻底通了。如果 push 成功、pull 失败优先怀疑磁盘与 /data 写权限如果 login 成功、push 报 401重点检查 hostname 与客户端访问地址是否一致。接下来是三个长期动作。第一个安装完成立刻改 admin 密码并把这台机器的 harbor.yml、证书文件、数据库密码单独备份到离线环境之外的地方。Harbor 不像普通服务配置和数据卷是绑定的配置文件丢失后数据卷还在也基本等于黑匣子。第二个升级前把 /data/database 整目录备份harbor.yml 留底跨大版本升级时不要直接拿新版本 install.sh 覆盖旧目录官方离线包里带升级脚本要按版本顺序逐级升跳版本升级最常见的翻车点就是数据库 schema 不兼容。第三个日常巡检只看两个指标磁盘剩余空间和 harbor-db 容器健康状态配 compose ps 就能覆盖大部分故障。我当年在内网部署时遇到过推送失败 get https://192.168.x.x/v2/排查了将近半天最后发现只是把 hostname 填成了主机名而不是内网 IP那次血泪经验之后我养成了装完就从另一台机器打一次 push 的习惯。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑