☰
ARM服务器离线安装Harbor 2.4.0实战:避坑指南与验证步骤
2026/10/28 2:51:27 网站建设 项目流程

简介:面向需要在 ARM 架构服务器上私有化部署容器镜像仓库的运维与开发人员,这份 Harbor v2.4.0 离线安装包解决的是内网或受限网络环境下无法在线拉取镜像、依赖安装繁琐的问题。包内共 6 个文件,以 sh 安装脚本、gz 镜像归档、yml 配置文件及 license 等为主,分别承担一键安装、镜像导入与参数配置等用途,压缩包整体约 402MB,解压后按说明执行脚本即可完成部署,前置条件为已装好 docker 与 docker-compose。内容围绕离线场景组织,安装脚本与配置文件配合,便于读者快速搭建可用的镜像仓库,并在此基础上调整端口、存储路径等参数,减少逐项排查依赖的时间。目前已有 1578 人学习下载,适合具备一定 Linux 与容器基础、希望在内网环境落地 Harbor 的中级用户参考使用。

1. 一次在 ARM 服务器上装 Harbor 2.4.0 的翻车记录

上周帮一个做私有镜像仓库的团队在 ARM 服务器上装 Harbor 2.4.0,本以为半小时能收工,结果卡了整整一个下午。问题不在 Harbor 本身,而在于我一开始按 x86 的习惯去准备离线包,镜像架构对不上,docker load全部报no matching manifest。Harbor 2.4.0 这个版本在 ARM 上装的人不算多,但一旦装好,私有镜像仓库、镜像扫描、项目隔离这些能力都能落地,适合内网环境、信创服务器、边缘节点这类不能随便连外网的场景。这篇笔记按「装什么版本 → 怎么准备离线包 → 怎么配 → 坏了怎么救 → 怎么验证」走一遍,新手能照着跑通,熟手能看到 ARM 架构下几个容易忽略的参数取舍。

2. 装前把环境列清:ARM 架构下 Harbor 2.4.0 的版本与依赖

2.1 硬件与操作系统的最低要求

Harbor 2.4.0 官方给的最低配置是 2 核 CPU、4 GB 内存、40 GB 磁盘,但这是「能跑起来」的底线,不是「能稳定用」的配置。我一般会按 4 核、8 GB 内存、100 GB 磁盘来准备,因为 Harbor 自带 PostgreSQL、Redis、Registry、Trivy 扫描器、Jobservice 这一堆容器,内存不够时最先出问题的是 Trivy 扫描任务,表现为扫描一直排队或者直接失败,日志里看不到明显报错,属于典型的玄学问题。

操作系统方面,ARM 服务器上常见的是麒麟、统信、Ubuntu 20.04/22.04 的 ARM 版、CentOS 的 ARM 衍生版。内核建议 4.19 以上,低于这个版本时 Docker 的 cgroup v2 支持不完整,容器启动会偶发失败。文件系统用 ext4 或 xfs 都行,但不要用 overlay 作为宿主机根文件系统,Docker 的存储驱动会和它打架。

2.2 版本对照表:Harbor、Docker、docker-compose 的搭配

组件推荐版本说明
Harborv2.4.0本文目标版本,ARM 离线包需自行构建或找对应架构的 release
Docker Engine20.10.x2.4.0 的 compose 文件用的是 compose v3 语法,20.10 足够
docker-compose1.29.x 或 2.x1.29 是 Python 版最后一版,2.x 是 Go 版,两者命令兼容
PostgreSQL内置 13Harbor 自带,不用单独装
Redis内置 6Harbor 自带,不用单独装

这里有个容易踩的点:Harbor 2.4.0 的docker-compose.yml里写的镜像 tag 是v2.4.0,但这些镜像默认只有 amd64 架构。ARM 上要么用官方后来补的 multi-arch 镜像,要么自己用源码构建。我这次用的是团队提前构建好的 ARM 镜像包,tag 保持一致,只是 manifest 是 arm64。

2.3 离线包到底包含什么

离线安装包不是单个文件,而是一组东西:Harbor 的安装包(harbor-offline-installer-v2.4.0.tgz)、所有依赖镜像的 tar 包、以及可选的 Trivy 漏洞库离线包。ARM 架构下,镜像 tar 包必须是用docker save从 arm64 环境导出的,不能拿 amd64 的包凑数。判断方法很简单,docker load之后执行docker inspect <image> --format '{{.Architecture}}',输出必须是arm64。

提示:离线包里的镜像数量在 10 个左右,包括 nginx、harbor-core、harbor-db、harbor-jobservice、harbor-portal、harbor-registry、registryctl、redis、trivy-adapter、harbor-exporter。少一个都会在docker-compose up时报 image not found。

3. 离线安装实操:从解包到 Harbor 起来的完整命令链

3.1 解包与目录规划

先把离线包传到服务器上,我习惯放在/opt/software下,安装目录用/opt/harbor,数据目录单独挂一块盘到/data,这样以后升级或者迁移时数据不会跟着安装目录一起被覆盖。

# 创建目录结构 mkdir -p /opt/software /opt/harbor /data/harbor # 解压安装包 cd /opt/software tar -xzf harbor-offline-installer-v2.4.0.tgz -C /opt/ # 确认解压结果 ls -l /opt/harbor/

解压后/opt/harbor下会有harbor.yml.tmpl、install.sh、prepare、common.sh这几个文件。harbor.yml.tmpl是配置模板,不能直接改,要先复制成harbor.yml。这一步很多人图省事直接改 tmpl,结果install.sh读的是harbor.yml,配置根本没生效,装完发现端口还是默认的 80。

3.2 导入 ARM 镜像并确认架构

镜像导入是 ARM 离线安装里最容易翻车的一步。把所有 tar 包放到一个目录,循环 load,然后逐个检查架构。

# 进入镜像包目录 cd /opt/software/images # 循环导入所有 tar 包 for img in *.tar; do echo "loading $img" docker load -i "$img" done # 检查所有镜像的架构,非 arm64 的要单独处理 docker images --format '{{.Repository}}:{{.Tag}}' | while read img; do arch=$(docker inspect "$img" --format '{{.Architecture}}') echo "$img -> $arch" done

docker load本身不校验架构,所以 amd64 的镜像也能 load 成功,但docker-compose up时会报exec format error。上面这段检查就是提前把这个坑挖出来。如果发现某个镜像是 amd64,要么换包,要么用docker buildx重新构建,不要试图用--platform强行跑,Harbor 的 core 组件是 Go 编译的二进制,架构不对直接起不来。

3.3 配置 harbor.yml:ARM 环境下必须改的五个参数

复制模板后,重点改这几项。ARM 服务器通常不对外暴露 80/443,或者 80 被别的服务占了,所以端口要改;数据目录要指到独立盘;hostname不能写localhost,否则客户端 push 镜像时解析不到。

# /opt/harbor/harbor.yml hostname: harbor.internal.example # 改成实际可解析的域名或 IP http: port: 8080 # 避开被占用的 80 https: port: 8443 certificate: /data/harbor/cert/server.crt private_key: /data/harbor/cert/server.key harbor_admin_password: ChangeMe_2024 data_volume: /data/harbor # 数据落独立盘 trivy: ignore_unfixed: false skip_update: true # 离线环境必须 true,否则扫描器启动时联网失败

skip_update: true是离线环境的关键,Trivy 默认启动时会去拉漏洞库,内网拉不到就一直重试,表现为trivy-adapter容器反复重启。data_volume改了之后,install.sh会把 registry 的存储、数据库数据、日志都放到这个目录下,所以这个目录的权限要给足,我一般chown -R 10000:10000 /data/harbor,因为 Harbor 容器内用的 uid 是 10000。

3.4 执行安装与首次启动检查

配置改完,先跑prepare生成 compose 文件,再跑install.sh。prepare会根据harbor.yml渲染出docker-compose.yml,这一步如果报错,多半是 yml 缩进或者证书路径不对。

cd /opt/harbor # 生成配置文件,--with-trivy 表示启用扫描器 ./prepare --with-trivy # 执行安装,--with-trivy 同样要带上 ./install.sh --with-trivy

安装脚本会做几件事:检查 Docker 和 compose 是否可用、加载镜像、启动容器、等待健康检查。最后输出Harbor has been installed and started successfully才算完。如果卡在Waiting for Harbor to come up,先别急着重装,用docker-compose ps看哪个容器是unhealthy或restarting,再看那个容器的日志,八成是端口冲突或者数据目录权限问题。

4. 配置调优与常见故障排查

4.1 端口、证书与外部访问的取舍

ARM 服务器上 80 端口经常被系统自带的 web 服务占用,所以改http.port是最省事的做法。但改端口之后,客户端docker login要带上端口号,比如docker login harbor.internal.example:8080,这一点要在团队里说清楚,否则会有人反馈「登录不上」其实是没带端口。

证书方面,内网环境可以用自签证书,但要把 CA 分发到所有需要 push 的机器上,放到/etc/docker/certs.d/harbor.internal.example:8080/ca.crt,然后重启 Docker。不这么做的话,docker push会报x509: certificate signed by unknown authority,很多人第一反应是去改 Harbor 配置,其实是客户端没信任 CA。

4.2 数据目录权限与磁盘规划

前面提到data_volume要 chown 到 10000,这里补充一个细节:如果/data是单独挂载的盘,挂载后要先chown再跑install.sh,因为安装脚本不会帮你改挂载点的属主。我遇到过装完之后 registry 容器一直重启,日志里是permission denied写/storage,查了半天发现是/data/harbor属主是 root。

磁盘规划上,registry 的 blob 增长最快,建议/data至少留 200 GB,并且配一个定时清理策略。Harbor 2.4.0 自带垃圾回收,在「系统管理 → 垃圾清理」里可以配 cron,我一般设成每周日凌晨跑一次,保留最近 30 天的 untagged 镜像。

4.3 五个高频踩坑记录

现象一:docker-compose up报no matching manifest for linux/arm64。原因:镜像包是 amd64 的,load 进去但架构不匹配。 解决:换 arm64 镜像包,或者用docker buildx build --platform linux/arm64从源码重新构建,构建完docker save导出再 load。

现象二:harbor-core容器启动后立刻退出,日志只有一行panic: runtime error。原因:harbor.yml里hostname写成了localhost或者带了下划线,Harbor 的配置校验不认。 解决:改成合法域名或纯 IP,不要带下划线,改完重新./prepare再docker-compose up -d。

现象三:Trivy 扫描任务一直处于Pending,trivy-adapter容器反复重启。原因:离线环境没设skip_update: true,扫描器启动时联网拉库超时。 解决:在harbor.yml的trivy段加skip_update: true,然后./prepare --with-trivy && docker-compose up -d。漏洞库需要手动导入的话,用trivy image --download-db-only在能联网的机器上拉好,再拷到/data/harbor/trivy-adapter/下。

现象四:docker push报received unexpected HTTP status: 500。原因:registry 的存储目录权限不对,或者磁盘满了。 解决:df -h /data看磁盘,docker logs registry看具体错误,权限问题就chown -R 10000:10000 /data/harbor,磁盘满就清旧镜像或者扩容。

现象五:升级或重装后,原来的镜像和项目全没了。原因:重装时data_volume指到了新目录,或者docker-compose down -v把 volume 删了。 解决:重装前先备份/data/harbor,docker-compose down不要带-v,harbor.yml里的data_volume保持和原来一致。

5. 装完怎么验证:三条命令确认 Harbor 真的可用

装完看到successfully不代表真的能用,我一般会走三步验证,缺一步都不算完。

第一步,看容器状态和健康检查。docker-compose ps里所有容器的State应该是Up,Health是healthy。如果有unhealthy,先看那个容器的日志,不要直接重启,重启解决不了配置问题。

cd /opt/harbor docker-compose ps # 期望输出:所有服务 State 为 Up,Health 为 healthy(没有 healthcheck 的显示 Up 即可)

第二步,用 API 探活。Harbor 2.4.0 的/api/v2.0/health会返回各组件的健康状态,比看容器状态更准,因为它会实际检查数据库和 registry 的连通性。

curl -s http://harbor.internal.example:8080/api/v2.0/health | python3 -m json.tool # 期望:status 为 healthy,components 里 database、registry、redis 都是 healthy

第三步,走一遍完整的 push/pull。这一步最能暴露问题,因为涉及认证、存储、网络三块。

# 登录 docker login harbor.internal.example:8080 -u admin -p 'ChangeMe_2024' # 打 tag 并 push 一个测试镜像 docker tag alpine:3.18 harbor.internal.example:8080/library/alpine:test docker push harbor.internal.example:8080/library/alpine:test # 删掉本地镜像再 pull,确认存储真的写进去了 docker rmi harbor.internal.example:8080/library/alpine:test docker pull harbor.internal.example:8080/library/alpine:test

push 成功但 pull 失败,多半是 registry 的存储路径问题;push 直接 401,是认证或者项目权限没配;push 报 413,是 nginx 的client_max_body_size太小,Harbor 2.4.0 默认是 0(不限制),但如果前面还有一层反向代理,要检查那一层的配置。

从那以后我每次装完 Harbor,不管多急,都强制走一遍这三步验证,尤其是 push/pull 那一步,因为容器状态 healthy 但 registry 写不进去的情况我见过不止一次。希望帮到你。

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

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

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

立即咨询