☰
ARM服务器离线安装Harbor v2.9.0:从架构确认到避坑实践
2026/10/8 14:38:47 网站建设 项目流程

简介:面向ARM64架构的Harbor v2.9.0离线安装资源包,专为在信创或内网环境中部署容器镜像仓库的运维工程师与开发人员设计。包内共包含6个文件,涵盖自动安装脚本、离线镜像归档、配置文件模板、许可证及预处理工具,整体约722MB;其中安装脚本与prepare工具可显著降低手工配置门槛,配合Docker Compose即可在离线状态下快速启用Harbor服务。已有969人学习下载,配套文档对安装流程作了详细说明。资源将Harbor核心镜像与配置完整打包,执行内置安装脚本即可自动完成镜像加载、环境检测与服务启动,尤其适用于ARM服务器上的规模化部署。使用前需自行准备Docker及Docker Compose,整体操作简洁,解决了离线场景下依赖获取难、配置步骤多等常见痛点,是一份高效实用的企业级镜像仓库部署方案。

1. ARM 服务器上离线装 Harbor 到底难在哪

一台鲲鹏或飞腾服务器,系统装好了、内网与外网隔离,现在要把 Harbor v2.9.0 部署上去当私有镜像仓库——这是国产化替代和等保内网环境里最常见的诉求。离线安装这个题目本身就够烦,叠加 ARM 架构以后,很多人在 x86 上练熟的流程会突然翻车:镜像架构不匹配、install.sh 报错、docker compose 命令找不到、登录以后推送镜像 dial tcp 超时。这篇文章直接说清楚在 ARM 架构下跑通 Harbor v2.9.0 离线安装的完整路径,从物料准备到参数配置再到排查思路,适合手里已经拿到一台 ARM 服务器、正在被离线部署折磨的运维和研发。

2. 安装前把三件事想清楚:架构确认、物料清单与端口预检

2.1 用 uname -m 和 lscpu 确认架构:区分 aarch64 与 armv7

ARM 是一个大筐,什么都能往里装。但 Harbor 的官方离线包只针对 64 位 ARM 构建,也就是 aarch64,对应 ARMv8 及以上的服务器芯片。如果你拿到的是 armv7l 这种 32 位 ARM(多见于老式嵌入式板子),官方离线包根本跑不起来。先确认架构,别的都是后话。

第一件事,登录服务器执行:

uname -m # 输出 aarch64 说明是 64 位 ARM,可以继续 # 输出 armv7l 或 armv6l 说明是 32 位 ARM,官方 Harbor 离线包不可用

第二件事,配合 lscpu 看芯片型号和字节序:

lscpu | grep -E "Architecture|Byte Order|Model name"

这两条命令输出的作用:uname -m决定你该下载哪个 Harbor 离线包;Model name让你知道是鲲鹏 920、飞腾 FT-2000 还是其他芯片,方便后续在遇到问题时去查芯片相关的已知问题。我用过的鲲鹏 920 和飞腾 S2500 都是标准的 aarch64,跑 Harbor v2.9.0 的官方 ARM 镜像没有架构兼容性问题。

注意,同是 aarch64,操作系统可以是麒麟 V10、统信 UOS、openEuler 或者 Debian,这些系统的包管理器不同,但 Harbor 的离线包依赖的是 docker 和 docker compose,跟具体发行版关系不大,只要 docker 能跑就行。

2.2 离线物料清单:Harbor 包、docker 程序与依赖组件

离线环境最怕的是装到一半发现少了文件。设计离线安装方案时,我一般会在有网的 x86 机器上把所有物料提前准备齐,再通过移动硬盘或内网传输通道拷过去。ARM 环境下的物料清单和 x86 略有不同,关键是 docker 本身也得是 ARM 版本。

下面这份清单是运行 Harbor v2.9.0 的最小集合:

物料作用说明
harbor-offline-installer-v2.9.0.tgzHarbor 主程序从 Harbor 官方 GitHub Releases 页面获取,选 v2.9.0 的离线安装包
harbor.v2.9.0.tar.gzHarbor 全部镜像内嵌在离线包里,解压后可见
docker 安装包容器运行时在对应发行版仓库中下载 ARM 版 docker 及 docker-cli
docker compose 插件容器编排docker compose v2 插件,或 docker-compose v1 二进制
自签证书工具HTTPS 支持OpenSSL 命令行工具,系统自带
其他机器的 docker远端客户端需要推拉镜像的每台机器都要配 docker

这张表最容易被忽略的是最后一行。很多人只在服务器上装好了 harbor,等从其他机器上 push 镜像时才发现客户端的 docker daemon 还没配置insecure-registries,连接直接被拒。

Harbor v2.9.0 的离线包本身不太大,解压后镜像 tar 包约 2GB 级别。部署前确认磁盘有 20GB 以上的剩余空间会比较从容,因为还有日志、数据库和镜像存储空间。我给生产环境做规划时,默认给/data单独划分一个分区挂载,避免根分区被镜像撑爆。

2.3 端口预检:80/443 被占用是离线部署最常见的开局坑

Harbor 默认通过 nginx 对外暴露 80 和 443 端口。很多 ARM 服务器上预先装了 Nginx、Apache 或者其他业务程序,80 和 443 已经被占用却没人知道,执行 install.sh 时服务起不来,日志里也看不出明显报错。

安装前先看一眼端口:

ss -tlnp | grep -E ":80|:443" # 有输出说明被占用,需要先停服务或改 harbor.yml 里的端口

如果端口被占,建议改 harbor.yml 里的 http.port 而不是去停掉已有服务。比如把 80 改成 8080,客户端访问时写https://192.168.x.x:8080。如果只是想先跑通,改成非标准端口更快,不用动现有业务。

另外,离线环境往往没有 DNS,harbor.yml 里必须要写 IP 地址而不是主机名。后面配置客户端时,docker login的地址也必须跟 harbor.yml 里的 hostname 完全一致,否则登录时会出现证书不匹配或无法解析的问题。

3. 离线安装 Harbor v2.9.0 的完整步骤:从解压到服务起来

3.1 解压离线包并熟悉包内结构

把 harbor-offline-installer-v2.9.0.tgz 和 harbor.v2.9.0.tar.gz 从有网机器拷贝到目标服务器后,第一步是解压。

Harbor 官方的离线安装包命名方式非常规律:harbor-offline-installer-v2.9.0.tgz。先创建目录再解压:

mkdir -p /opt/harbor tar -xzvf harbor-offline-installer-v2.9.0.tgz -C /opt/harbor cd /opt/harbor ls -la

解压后目录里应该能看到harbor.yml.tmpl、install.sh、common.sh和harbor.v2.9.0.tar.gz。其中harbor.yml.tmpl是配置文件模板,install.sh是安装脚本,harbor.v2.9.0.tar.gz包含了 Harbor 运行所需的全部容器镜像。

这里有一个很容易犯的错:有人以为harbor.v2.9.0.tar.gz不需要手动加载,install.sh 会自动处理。实际上 install.sh 会检查这些镜像是否已经存在于本地 docker 中,如果没有,它不会帮你从离线包里加载,而是尝试在线拉取——在内网环境下就会导致安装直接卡住。所以镜像必须提前docker load进去。

3.2 加载 Harbor 镜像:docker load 这一步决定成败

在离线环境里,docker load是整个安装流程的基石。执行前先确认磁盘空间足够,然后加载镜像:

docker load -i harbor.v2.9.0.tar.gz # 加载过程会输出每一层镜像的 Loaded 信息 # 加载完成后,用 docker images 确认镜像已经存在 docker images

执行完docker images后,应该能看到 goharbor/harbor-core、goharbor/harbor-db、goharbor/harbor-jobservice、goharbor/harbor-portal、goharbor/harbor-registry、goharbor/harbor-registryctl、goharbor/redis-photon 和 goharbor/nginx-photon 等镜像。加载耗时取决于磁盘速度,机械硬盘上可能需要十几分钟,SSD 会快很多,属于正常现象。

验证镜像架构:

docker inspect goharbor/harbor-core:v2.9.0 --format '{{.Architecture}}' # 输出 arm64 说明镜像架构正确

这一步值得单独写出来。如果你在 x86 机器上预先下载了镜像包,拷到 ARM 服务器上docker load虽然不会报错,但运行时直接报exec format error。因为镜像的架构是 amd64,在 ARM 上根本起不来。检查Architecture字段正是为了避免这种让人抓狂的情况。

3.3 修改 harbor.yml:四个必改项与两个建议项

Harbor 安装前必须把配置文件准备好。离线包提供的是harbor.yml.tmpl模板,需要先复制一份:

cp harbor.yml.tmpl harbor.yml vim harbor.yml

harbor.yml 中最关键的几项如下:

# 必改项 1: hostname 一定要写客户端能访问到的 IP hostname: 192.168.209.133 # 必改项 2: HTTP 端口,默认 80;如果被占用改成 8080 http: port: 80 # 必改项 3: 管理员密码,默认 Harbor12345,生产环境务必改掉 harbor_admin_password: YourStrongPassword # 必改项 4: 数据存放目录,改成独立数据盘 data_volume: /data/harbor # 建议项 1: HTTPS 先注释掉,等 HTTP 跑通后再开启 # https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path # 建议项 2: 日志级别 log: level: info rotate_count: 10 rotate_size: 200M

hostname这一项是整个配置里最核心的参数。如果你写localhost或127.0.0.1,安装本身没问题,但从其他机器访问时会发现根本连不上。因为 Harbor 内部生成的访问地址、重定向链接都会基于 hostname 来拼接,写localhost时所有客户端拿到的都是错误地址。

密码项需要注意,Harbor 要求管理员密码至少包含大写字母、小写字母和数字,长度超过 8 位。我见过很多人在harbor_admin_password里写纯数字,install.sh 直接报错拒绝安装。

data_volume指定了 Harbor 的所有持久化数据存放位置,包括数据库文件、镜像存储、证书和日志。建议挂在一个独立分区上,这样后续升级或迁移时只需要拷贝这个目录。

3.4 执行 install.sh 并验证服务状态

配置好 harbor.yml 后,开始安装。Harbor v2.9.0 的 install.sh 首先会自动检测 docker 和 docker compose 是否存在。这里有一个容易踩坑的细节:v2.9.0 的安装脚本要求 docker compose v2 插件,也就是能识别docker compose命令。如果你的机器上只有老版本的docker-compose单文件二进制,脚本会报错。解决方法是安装 docker compose 插件,或者做个软链接让它识别到 docker compose。

# 执行安装 ./install.sh # 脚本会自动检查环境,然后启动所有 Harbor 组件

安装过程主要做三件事:准备目录结构、用 docker compose 启动所有容器、等待各组件健康检查通过。如果前面镜像加载正确、端口没冲突、配置没有语法错误,这一步基本不会失败。

安装完成后验证:

docker compose ps # 输出中可以看到 harbor-core、harbor-db、harbor-jobservice 等组件 # STATUS 都应该是 Up,如果有关闭状态的说明启动失败

然后打开浏览器访问https://192.168.209.133(或你配置的 IP 加端口),用配置的管理员账号登录。如果页面能打开,说明 Harbor 基本已经跑起来了。登录后建议先创建一个测试项目,为后面的推送验证做准备。

4. 关键参数与部署形态:从 HTTP 模式到 HTTPS 自签证书

4.1 HTTP 模式下客户端必须具备的 daemon 配置

离线内网环境通常没有正规 CA 签发的证书,很多团队为了尽快跑通,选择 HTTP 模式部署 Harbor。这个选择没错,但只改服务端不配客户端的话,会遇到非常典型的报错:

Error response from daemon: Get "https://192.168.209.133/v2/": http: server gave HTTP response to HTTPS client

原因在于 docker 客户端默认用 HTTPS 访问仓库地址。要让它以 HTTP 方式访问 Harbor,必须在每一台需要推送或拉取镜像的机器上修改 docker daemon 配置,加入insecure-registries字段:

# 在每一台需要访问 Harbor 的机器上执行 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "insecure-registries": ["192.168.209.133"] } EOF # 改完必须重启 docker,否则配置不生效 sudo systemctl restart docker

这里有两个细节:第一,insecure-registries里填的地址必须与 harbor.yml 的hostname完全一致,IP 就是 IP,域名就是域名,混用会带来不必要的困扰;第二,如果镜像仓库端口是 8080 或 443 以外的自定义端口,daemon.json里也要带上端口号。

很多人在自己的开发机上都配好了insecure-registries,但到了另一台新服务器上忘了配,导致同样的报错反复出现。建议把这段配置写进团队的服务器初始化脚本里,作为标准动作之一。

4.2 用自签证书把 Harbor 切成 HTTPS:openssl 三步法

HTTP 模式虽然能跑通,但一旦涉及多团队协作、跨网络传输镜像,明文传输的不安全感会越来越明显。自签证书是离线环境最常用的 HTTPS 方案。在 Harbor 服务器上生成自签证书的操作步骤如下:

# 第 1 步:生成 CA 私钥 openssl genrsa -out ca.key 4096 # 第 2 步:生成 CA 证书 openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Example/CN=Harbor CA" \ -out ca.crt # 第 3 步:生成 Harbor 服务器私钥和证书请求 openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Example/CN=192.168.209.133" # 第 4 步:用 CA 签发服务器证书 openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ -CAcreateserial -out server.crt -days 3650 -sha256

注意第 4 步生成的server.crt必须和server.key放到同一目录,并且在 harbor.yml 里开启 https 段:

https: port: 443 certificate: /data/certs/server.crt private_key: /data/certs/server.key

客户端同样需要信任这个 CA。把ca.crt拷贝到客户端的/etc/docker/certs.d/192.168.209.133/ca.crt路径下,重启 docker 即可。有了这一层配置,push 和 pull 全部走 HTTPS,安全性和可靠性都提升一个档次。

4.3 数据持久化与日志轮转:ARM 服务器磁盘空间尤其需要管理

ARM 服务器多用于内网环境,磁盘配置普遍不如 x86 云服务器宽裕,Harbor 的数据增长模型需要在部署前想清楚。Harbor 的数据主要存在三块:镜像存储(registry)、数据库(PostgreSQL)、日志。

镜像存储是最大的增长源。一个团队如果频繁构建镜像,一个月增长几十 GB 很常见。data_volume所在分区要有兜底策略,通常的做法是单独挂载一块大容量数据盘,或者用软链接把/data/harbor指到大容量分区。Harbor 本身自带的镜像清理机制触发条件有限,建议定期手动执行 registry GC。

日志轮转可以在 harbor.yml 里直接控制:

log: level: info rotate_count: 10 rotate_size: 200M

这四个参数的含义:level控制日志详细程度;rotate_count保留的日志文件数;rotate_size单个日志文件达到多大就轮转。设为 10 个文件、每个 200M 时,日志最多占用 2GB 空间,不至于撑爆根分区。默认配置不设这个的话,Harbor 的日志量可能超出预期,尤其在 ARM 板子上跑时更容易暴露出问题。

数据库这块不用过多干预,Harbor 自己管理 PostgreSQL 容器的数据目录,只要data_volume有空间就行。但要注意,Harbor 升级时 PostgreSQL 数据目录的兼容性比较敏感,升级前必须做好备份,这个习惯建议从一开始就养成。

5. 避坑与排查:ARM 离线部署最容易翻车的 5 类问题

5.1 推送镜像报 dial tcp 连接超时

现象:客户端执行docker push 192.168.209.133/test/nginx:v1时卡住,然后报:

Get "https://192.168.209.133/v2/": dial tcp 192.168.209.133:443: connect: connection timed out

原因:这个问题排在 Harbor 部署问题榜首,绝大多数情况不是 Harbor 本身的问题,而是网络不通。离线环境里常见的因素包括:服务器防火墙拦截了 443 或 80 端口、客户端和服务器不在同一个网段、服务器上安全组软件限制了来源 IP。

解决:先在服务器上确认端口监听正常:ss -tlnp | grep 443。再在客户端上测试网络连通性:telnet 192.168.209.133 443。如果 telnet 不通,检查防火墙和路由,用iptables -L或firewall-cmd --list-all查看放行规则。离线内网跑 Docker 推送时,IP 冲突和 ARP 混乱也偶有发生,用arp -a看看 MAC 地址是否正常。

5.2 镜像架构不匹配导致 exec format error

现象:Harbor 部署成功,推送镜像也正常,但在 ARM 服务器上docker run镜像时直接报:

exec /bin/sh: exec format error

原因:这个坑尤其隐蔽,因为它发生在 Harbor 部署成功之后很长一段时间。团队里有人把 x86 架构的镜像推送到了 ARM 的 Harbor 仓库,ARM 服务器拉下来运行时必然起不来。Harbor 本身不做架构过滤,它只负责存储镜像,不管你推的是什么架构的。

解决:推送前先检查镜像架构,在构建镜像的机器上执行:

docker inspect your-image --format '{{.Architecture}}'

如果是amd64,说明这个镜像是 x86 架构,不能直接在 ARM 上运行。需要重新用 ARM 基础镜像构建。这个坑在混合架构团队里几乎每周都会出现一次,建议在项目文档里明确标注镜像架构。

5.3 docker compose 不是最新版导致安装脚本卡死

现象:执行./install.sh时脚本报错,说 docker compose 版本不支持或命令未找到。

原因:Harbor v2.9.0 的安装脚本默认调用docker compose命令,这是 docker compose v2 的用法。很多 CentOS 7.9 或老系统上只装了docker-composev1,命令格式不同。

解决:安装 docker compose v2 插件。在有网环境下载对应 ARM 架构的docker-compose二进制,拷贝到服务器后放到/usr/local/bin/docker-compose,或者安装docker-compose-plugin包。如果用的是已有 v1 的docker-compose,可以做一个软链接:

ln -s /usr/local/bin/docker-compose /usr/local/bin/docker compose

这个软链接命令是为了让安装脚本能同时识别两种形式的 compose 命令,属于常用规避手段。

5.4 HTTP 模式登录报 server gave HTTP response to HTTPS client

现象:Harbor 装好后,docker login 时一直报http: server gave HTTP response to HTTPS client。

原因:docker 客户端默认用 HTTPS 与仓库通信,而服务端只开了 HTTP 端口。这是协议不匹配的问题,不是用户名或密码错误。

解决:修改客户端的/etc/docker/daemon.json,加入insecure-registries配置。这个坑在第 4.1 节已经详细写过,但值得在这里再次强调,因为它是 Harbor 初装后遇到的最高频报错,没有之一。修完记得重启 docker。

5.5 上传镜像报 manifest unknown

现象:docker push 192.168.209.133/project/image:v1时,推送过程走到最后一步报manifest unknown。

原因:这个报错有两种常见场景:第一,镜像架构与仓库期望的架构不匹配;第二,同一个 tag 被推送过,但新镜像的 manifest 与旧的不一致,仓库端的引用失效。

解决:如果是架构不匹配,检查镜像是 arm64 还是 amd64,重新构建后再推。如果是 manifest 引用问题,把本地镜像重新打一个 tag,或者删掉远端仓库里的旧 tag 重新推送。Harbor 的 UI 界面上可以直接删除 tag,删掉后重推一般能恢复。

6. 安装完成后的验证方法与日常维护几个实用技巧

Harbor 服务起来之后,不要急着宣布大功告成,花十分钟把整个流程走一遍,能省下后面几天的排查时间。

第一步,验证 Harbor 自身的健康状态。Harbor 提供了 API 接口可以直接查:

curl -k https://192.168.209.133/api/v2.0/ping # 返回 Pong 说明服务正常 curl -k https://192.168.209.133/api/v2.0/health # 返回 {"status":"healthy"} 说明所有组件健康

第二步,用 docker 命令行走一遍完整的推拉流程。在客户端机器上登录、创建测试项目、推送镜像、拉取镜像、运行容器,把这五步全部走通,才算真正交付。我见过太多部署完只打开网页看一眼就收工,结果第二天团队拉镜像时发现客户端配置缺了一堆的情况。

第三步,验证镜像架构也没问题。推送一个你看过架构的测试镜像,确认能正常拉取和运行,这个动作也是对 5.2 节提到的坑的预防手段。

日常维护里有三个小习惯我一直在用:第一,每季度手动执行一次 Harbor 的镜像清理并配合 registry GC,避免数据盘被历史镜像塞满;第二,升级版本前把data_volume目录完整打包备份,Harbor 升级就像拆炸弹,备份是唯一的后悔药;第三,修改 harbor.yml 后不要直接重启容器,用./install.sh --with-trivy之类的形式重新跑一遍会比手动改 compose 更稳。

最后说一个我的个人习惯:Harbor 部署完成后,我会把 harbor.yml 的当前版本复制一份存档,把harbor_admin_password用环境变量方式管理而不是写死在配置文件里,这样可以避免团队人员变动时密码泄露自己还不知道。这个习惯帮我在一次团队交接时避免了完全重装 Harbor 的尴尬。希望这些经验能帮你在 ARM 服务器上顺利跑通 Harbor,少走几段弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询