news 2026/10/8 8:38:57

Harbor v2.13.1 ARM64离线安装包部署与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Harbor v2.13.1 ARM64离线安装包部署与避坑指南

简介:面向ARM64架构下的Kubernetes与Docker环境,Harbor v2.13.1离线安装包专为运维人员准备,核心价值是在无外网或内网隔离的ARM服务器上快速部署私有镜像仓库。压缩包为tgz格式,共6个文件,包含install.sh与common.sh两个Shell脚本,分别负责安装执行和公共函数加载;harbor.v2.13.1.tar.gz是完整的主镜像包,提供Harbor全部组件;prepare与harbor.yml.tmpl用于环境预检及核心配置模板,LICENSE文件则明确使用许可。整体约679MB,结构清晰,适合作为生产环境部署的基线资产。目前已有528人学习下载,特别适合在信创ARM平台、边缘计算节点或离线机房中搭建镜像管理系统的工程师。拿到手后可直接解压,依据模板修改端口、存储路径、证书等参数,再执行安装脚本即可完成部署;资源同时持续跟进新版离线包,便于后续升级维护。

1. 先讲清楚:Harbor 最新 v2.13.1 的 ARM64 离线安装包解决的是什么问题

一台只有 ARM64 CPU 的服务器,网络和公网隔离,却要搭一个生产可用的镜像仓库,这时候最常见的答案就是 Harbor 最新 v2.13.1 的 ARM64 离线安装包。它不是在线装完后“导出的备份”,而是官方为 aarch64 架构单独打的离线发行包:harbor-offline-installer-v2.13.1-arm64.tgz。包内置了 Harbor 全部组件镜像的 tar 捆,从解压到浏览器打开 UI,全程不需要外网。这个方案适合三类人:在做国产化适配的交付工程师、给边缘机房离线交付的平台组,以及接手 ARM64 服务器却不想折腾源码编译的运维。注意一个关键事实:它和 x86 的包是两个文件,拿错包在 ARM64 机器上启动时会直接报 exec format error,这一步走错后面全是黑匣子,后面会专门讲。

2. 安装之前:ARM64 离线包和 x86 包差在哪,环境怎么准备

2.1 架构差异与离线包的命名规则

标题里的“ARM64 版离线安装包”,在 Harbor 官方 Release 里对应的是带 arm64 后缀的 tgz。v2.13.1 这个版本同时发布几种安装介质:x86_64 机器上用 harbor-offline-installer-v2.13.1.tgz,aarch64 对应 harbor-offline-installer-v2.13.1-arm64.tgz,另外还有面向 Helm Chart 和 FIPS 加固的包。离线包内部结构一致,但 harbor.v2.13.1.tar.gz 里的镜像架构不同:x86 包导出的是 amd64 镜像层,ARM64 包导出的是 arm64/v8 镜像层。有人会问“Harbor 镜像不是 multi-arch 吗,我在 ARM64 上 load x86 包能不能跑?”manifest 列表确实是多架构的,但 docker save 导出的是具体某个镜像 manifest 下的层,不是把整个列表塞进去。你把 amd64 的 tar 在 aarch64 上 load 出来,docker images 能看到,docker run 才暴露问题:harbor-core、harbor-registry 这类容器一启动就抛 “exec format error”,反复 CrashLoopBackOff。

还有一类更隐蔽的情况:在 x86_64 开发机上用 qemu 模拟 ARM64 来“体验”这个离线包。qemu user-mode 确实能让 amd64 容器跑起来,但 Harbor 这种带数据库、JobService 多服务的编排,在 qemu 下经常遇到线程库和信号处理不兼容的问题,安装脚本里部分探测命令也会因为模拟器行为差异给出错误结果。可以做冒烟测试,但不建议作为交付依据。我一般拿到机器第一件事就是 uname -m 和 docker info 看 Architecture,再决定用哪个包。这个动作 10 秒钟,能省掉后面一整天的排障。

2.2 离线包里装的是什么:组件清单与数据流

解压离线包后,目录里最关键的是这几个文件:

mkdir -p /opt/harbor-install && cd /opt/harbor-install tar -xzf harbor-offline-installer-v2.13.1-arm64.tgz cd harbor ls -lh # 主要文件: # harbor.yml # 唯一需要手改的配置入口 # install.sh # 离线安装总入口 # prepare # 生成 docker-compose.yml 的预处理工具 # common.sh # 安装脚本公共函数,含镜像列表 # harbor.v2.13.1.tar.gz # 所有组件镜像的 docker save 产物 # LICENSE # 软件许可

这里我不建议手动docker load -i harbor.v2.13.1.tar.gz,install.sh 会自动做,但你要知道这个 tar 很大。ARM64 版整包通常以 GB 计,加上解压后的镜像层、数据卷,磁盘预留至少要比 tar 大一倍。Harbor v2.13.1 的组件镜像包括:harbor-core(API 和调度核心)、harbor-registry(镜像存储,基于 Docker Distribution)、harbor-db(内嵌 PostgreSQL)、harbor-portal(前端页面和反向代理)、harbor-jobservice(GC、复制、漏洞扫描等后台任务)、harbor-log(统一日志收集)、harbor-registryctl(保护 registry 配置的辅助容器),再加上可选的 trivy-adapter(漏洞扫描)、notary-server / notary-signer(镜像签名)。这些服务安装后由 docker compose 编排,端口和数据卷都从 harbor.yml 映射出来。

理解这个组件清单对排错很重要。比如 push 失败时,你至少要知道流量先到 harbor-portal(监听 80/443),再反代到 harbor-core,最后由 core 把镜像层转发给 harbor-registry。任何一层的容器没起来,报错都像“连接被拒”。我见过有人把 harbor-portal 容器误删后,整整一天在改客户端 daemon.json,方向完全错了。

2.3 环境预检:磁盘、内存、Docker 与端口

离线包虽然免外网,但目标机器本身要满足最低运行条件。我习惯按生产标准而不是官方最低要求来预检,避免装完发现是纸面部署:

# 确认 CPU 架构必须是 aarch64 uname -m # 期望输出: aarch64 # 确认磁盘:镜像数据目录所在分区预留 100GB 以上(按实际业务量调整) df -h /opt /data # 确认内存:含 Trivy 建议 8GB 以上,不含至少 4GB free -h # 确认 Docker:版本不低于 20.10,且是标准的 containerd 运行时 docker version --format '{{.Server.Version}}'

几个容易翻车的点注意一下。第一,如果是 Ubuntu 系,Harbor 容器默认用 host 网络和自定义 bridge,升级内核或重启 Docker 后 iptables 策略可能变化,安装前把 docker.service 设为开机启用,并确认没有防火墙规则挡 80/443。第二,Harbor 的 data_volume 不要放在系统盘根分区,镜像仓库的存量增长比想象快。第三,如果这台机器之前装过旧 Harbor,先确认 compose 项目名和网络名是否冲突,避免安装脚本“以为你升级”而实际是并存部署。我之前在一个残留环境上直接跑 install.sh,结果新旧两套容器同时监听 80 端口,谁也起不来。

Docker 与 compose 的版本配合也很关键。Harbor v2.13.1 的 install.sh 同时兼容 docker-compose v1(docker-compose 命令)和 v2(docker compose 子命令)。但如果你机器上同时有这两个命令,脚本默认用 compose v2,而你后续手动维护时用 v1 操作,两个命令看到的是不同的项目元数据,升级时就容易“找不到项目”。统一用一种语法,别混用。

3. 用离线包安装 Harbor v2.13.1:解压、改配置、跑脚本

3.1 解压与修改 harbor.yml:6 个必动参数

进入解压目录后,先备份默认配置再改,这是后悔药:

cd /opt/harbor-install/harbor cp harbor.yml harbor.yml.bak vim harbor.yml

Harbor v2.13.1 的配置项很多,但离线部署真正需要动的是下面这 6 个。改错了不至于立刻报错,但后续 push/pull 一定会反噬,所以一次改对。

参数默认值离线环境建议
hostnamereg.mydomain.com填客户端能访问到的 IP 或域名,比如 192.168.209.133
http.port80保持 80,除非和系统服务冲突;客户端端口要与此一致
harbor_admin_passwordHarbor12345至少 12 位,包含大小写和数字;首登后建议轮换
data_volume/data改成挂载大分区的绝对路径,例如 /data/harbor
database.passwordroot123改成独立强密码,别和 admin 密码相同
trivy.skip_updatefalse离线环境改成 true,否则 Trivy 启动会尝试连公网更新漏洞库

说明一下关键逻辑。hostname 是最容易踩坑的,如果填 localhost 或者 127.0.0.1,外部机器 push 时 Docker 客户端把仓库地址解析到它自己的回环地址,直接连接被拒。建议填局域网 IP 或规划好的域名,并让所有客户端能解析到这个地址。http.port 改动时,客户端 insecure-registries 里的端口也要跟着变,两处不一致是高频翻车点。data_volume 决定镜像 blob 落在哪,后续迁移备份都依赖这个路径,升级时路径不能变,否则旧数据就像消失了一样。

3.2 prepare 与 install.sh:核心命令到底干了什么

配置改完后,官方离线安装入口是 install.sh,但很多新人不理解 prepare 的作用。install.sh 内部会调用 prepare,不过我建议手动跑一次 prepare 来暴露问题,减少把错误攒到启动阶段:

# 预处理:基于 harbor.yml 生成 docker-compose.yml 和配置文件 ./prepare # 如果上面输出正常,再执行安装;按需开启 Trivy 和 Notary sudo ./install.sh --with-trivy --with-notary

install.sh 的执行顺序大致是:读取 common.sh 里的镜像列表 → 用 docker load 导入 harbor.v2.13.1.tar.gz → 检查 compose 是否存在 → 调用 prepare 生成 docker-compose.yml 与各组件配置 → 最后 docker compose up -d 拉起所有服务。几个容易忽略的点:install.sh 需要 root 或 sudo 权限,因为要创建数据卷目录、写日志相关配置;你不用事先生成 docker-compose.yml,prepare 会按 harbor.yml 生成,手动去改 docker-compose.yml 反而会在 prepare 时被覆盖。

--with-trivy 和 --with-notary 是按需组件。离线环境里 Trivy 的漏洞库如果不打算更新,必须保证 harbor.yml 里 skip_update: true,否则 trivy-adapter 容器反复重启。notary 只在需要镜像签名时开,默认可以不开,省一点内存。另外注意一个细节:prepare 脚本会检测 docker-compose 是否可用,如果系统里只有 docker 没有 compose 插件,安装会在这一步骤中断。Debian/Ubuntu 系通常要单独装 docker-compose-plugin 或 docker-compose-v2 包。

3.3 首次验证:容器列表、健康检查与 UI

安装过程正常,等一两分钟后用 compose 看状态:

cd /opt/harbor-install/harbor docker compose ps # 期望看到 harbor-core、harbor-db、harbor-registry、harbor-portal 都是 running # 用 docker ps 过滤,确认没有 CrashLoopBackOff docker ps -a --format '{{.Names}}\t{{.Status}}' | grep -E 'harbor|trivy|notary'

我没有加 --with-chartmuseum 这类旧组件开关。Harbor 从 2.8 左右的版本开始默认不装 chartmuseum,新版本里 Chart 仓库能力已经调整,所以在 v2.13.1 上不要硬找这个开关,除非你明确需要旧版兼容。UI 验证直接浏览器访问 http:// ,账号 admin 加 harbor.yml 里设置的密码。命令行验证更靠谱:

curl -u admin:'你的密码' http://192.168.209.133/api/v2.0/projects # 返回 JSON 数组即说明核心 API 正常

如果这里通但页面打不开,先看 harbor-portal 容器日志,往往是前端静态文件权限或者代理配置问题,和核心服务无关。到这里,一个 ARM64 的 Harbor 已经能用了,但上线前把下一章的四个坑过一遍,能少走不少弯路。

4. ARM64 离线环境避坑:4 个高频问题的现象、原因和解决

4.1 坑 1:qemu 模拟 ARM64 导致容器反复重启

现象:在 x86 开发机上用 qemu 模拟 ARM64 跑安装脚本,install.sh 执行完,docker compose ps 显示 harbor-db 一会儿 Up 一会儿 Restarting,日志里出现数据库初始化失败。偶尔还会看到容器以类似 “bad linux arm64 image magic!” 的格式错误退出,其实是宿主内核在尝试以自身架构解析镜像二进制。

原因:qemu user-mode 的“模拟”只覆盖用户态系统调用,Harbor 中 harbor-db 依赖的 PostgreSQL 对并发和信号处理比较敏感;而镜像格式检查发生在内核 exec 路径,qemu 配合 binfmt_misc 时,某些轻量环境没有注册 aarch64 解释器,于是内核拿 x86 的逻辑去读 ARM64 的 ELF,直接报错。这不是 Harbor 的问题,是运行环境没真正具备执行 ARM64 二进制的能力。

解决:不要在 x86 机器上交付 ARM64 部署。真的要测试,用支持硬件虚拟化的 ARM64 云主机,或者带 aarch64 的工控机。如果已经在模拟环境踩进去了,先把 binfmt_misc 注册好,比如 Debian 系上执行update-binfmts --enable qemu-aarch64,能救回来一部分场景,但也只是“能 run”,不代表生产可用。结论明确:ARM64 离线包必须跑在真 ARM64 主机上,否则你后续排查的所有问题都可能被模拟器噪声干扰。

4.2 坑 2:docker push 报 dial tcp 192.168.x.x 连接被拒

现象:在客户端机器上执行 docker push,报错形如:

get "https://192.168.209.133/v2/": dial tcp 192.168.209.133: connect: connection refused

注意报错 URL 里 IP 后面的端口或协议不对。原因往往不是 Harbor 挂了,而是三选一:harbor-portal 没监听该地址;harbor.yml 里 hostname 配的是 localhost;客户端和 Harbor 不在同一网段但配置里用了无法路由的 IP。这类错误几乎每天都有同行遇到,单看报错确实像服务没起。

解决:先在 Harbor 服务器本机用 curl 验证:

curl -v http://192.168.209.133/v2/ # 本机通、客户端不通,查防火墙和安全组端口 # 本机也不通,回到 harbor.yml 检查 hostname 和 http.port

确认 harbor.yml 中 hostname 是实际可路由的 IP,重新./prepare && sudo ./install.sh让改动生效。然后客户端 push 之前,把仓库地址显式写成 IP:端口,同时确认 docker 配置的 insecure-registries 覆盖了该地址,HTTP/HTTPS 协议才不会打架。

4.3 坑 3:HTTP registry 被 Docker 客户端拒绝(insecure-registries)

现象:Harbor 走 HTTP(未配置证书),客户端 docker login 提示:

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

原因:Docker 客户端默认只信任 HTTPS registry,HTTP 需要在 daemon.json 里显式声明为 insecure registry。这是自建 Harbor 最常踩的一道门槛,和服务端无关。很多新手看到报错里的 http 字样,以为是 Harbor 配置问题,其实问题在客户端 Docker 守护进程。

解决:在每台要 push/pull 的客户端机器上改 /etc/docker/daemon.json:

{ "insecure-registries": ["192.168.209.133", "192.168.209.133:80"] }

改完先sudo systemctl reload docker,再 docker login。如果还报错,就重启 docker:sudo systemctl restart docker。注意 reload 对 daemon 配置不一定完全生效,重启更稳,但会造成节点上正在运行的容器短暂中断,生产环境挑窗口操作。这里有一个经验:insecure-registries 的列表是“地址+端口”的精确组合,只写 IP 不写端口,而你 push 时又写了端口,系统会认为这是另一台机器,重新走 HTTPS 验证,照样失败。所有节点上的地址、端口、协议要保持一致。

4.4 坑 4:从旧版跨版本升级,数据库迁移失败

现象:旧版本 Harbor(比如 2.9)直接用 v2.13.1 的 install.sh 覆盖,启动后 harbor-core 或 harbor-db 报迁移失败,日志里出现找不到表或列。原因:Harbor 数据库迁移是逐个版本累积的,跨两个以上大版本时,install.sh 不一定帮你补中间步骤,prepare 生成的数据库初始化脚本只针对当前版本。

解决:不要在 ARM64 离线环境里强行“跳级”。升级前备份整个 data_volume,尤其是 /database 子目录,然后按官方路径逐版本升级。比如 2.9 → 2.10 → 2.11 → 2.12 → 2.13.1,每个版本下载对应离线包、改好 harbor.yml 的路径保持不变、跑 prepare 和 install.sh。如果你拿的是 ARM64 包,确认每个中间版本都有 arm64 产物,没有的话说明该版本不支持 ARM64,不要硬用 x86 包加 qemu 凑合。这条没有捷径,数据库迁移不是玄学,是建表语句的依赖链。

5. 把离线部署变成可持续操作:升级路径与三层验证

到这里,Harbor v2.13.1 的 ARM64 离线安装已经不是一次性动作。我建议把“装完”当起点,把升级和验证固化成脚本,因为它直接决定这个离线包投入值不值。

升级路径方面,常见做法是:备份 data_volume → 停旧服务 → 解压新版本 ARM64 离线包 → 沿用旧的 data_volume 路径和数据库密码 → 执行 prepare → 执行 install.sh,组件开关保持和升级前一致。升级后健康检查要单独做,尤其是数据库迁移。我给一个三层验证脚本的最小示例:

#!/bin/bash # 验证脚本:check_harbor.sh HOST="192.168.209.133" ADMIN="admin" PASS="你的密码" # 第一层:容器都起来,且没有 CrashLoopBackOff docker ps -a --format '{{.Names}}\t{{.Status}}' | grep harbor | grep -v Up # 第二层:核心 API 返回 200 curl -s -o /dev/null -w '%{http_code}' -u "$ADMIN:$PASS" \ "http://$HOST/api/v2.0/health" # 第三层:实际推拉一个测试镜像(离线环境用 busybox arm64 镜像) docker push $HOST/library/test:arm64 && docker pull $HOST/library/test:arm64

第三层最接近真实用户体验,最容易暴露配置不一致问题,比单纯看 docker compose ps 更可靠。我习惯在一次升级后完整跑一遍三层,前面两层挂掉立即停止后续操作,因为数据库迁移失败后再推镜像,故障现场会被污染。

还有一个验证升级后配置的技巧:升级前把旧的 docker-compose.yml 复制一份,升级后 diff 一下,看数据卷映射和网络是否有非预期变化,这是容器化部署里少有的便宜可靠的后悔药。凡是容器、存储、网络卷标有漂移,优先怀疑 compose 项目名和 network 名冲突,而不要先怀疑 Harbor 程序本身。

硬件层面,保留一条快速回滚动作:备份 data_volume 后压缩到独立文件系统,万一升级失败,解压回去再把旧版本离线包 install 一遍。在 ARM64 机器上做这件事比在 x86 上更慢,因为 Postgres 数据文件的 io 压力会直接拖慢恢复。所以我的习惯是:能一次升级到位,就不反复切版本,否则等待时间都会让你怀疑人生。

是否值得投入这个方向,我的判断是:离线、ARM64、私有化交付这三个词叠加时,Harbor 的官方 ARM64 离线包几乎是目前把方案落地成本压到最低的路径。它比在线安装少一个外网依赖,比自编译省掉一整个工具链,比跨架构模拟稳定得多。只要把 hostname、端口、insecure-registries 和版本升级路径这四个点管住,这个方案就是能长期运转的。把第一次排障学到的经验写进脚本,比记住“重启大法”更有用,希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 8:38:57

SSM+Flask双技术栈,打造高校宿舍管理系统全栈实战

一说宿舍管理系统,每年毕业设计季它都是“流量担当”。你搜一下“JavaSSM高校宿舍管理系统”,能出来一大批带源码、带论文(也就是标题里那个LW)、带调试文档和讲解视频的完整项目。作为一个把这些年帮人调过各种烂代码、也带过不少…

作者头像 李华
网站建设 2026/10/8 8:36:26

C#存储分层策略:从GC压力到毫秒级响应的实战方案

做了快十年C#性能优化,我见过太多系统在内存上翻车的样子:GC线程把CPU干到100%,响应时间从5毫秒直接冲破500毫秒大关,内存占用像坐火箭一样往上蹿。很多人第一反应就是把锅甩给“对象太多、忘释放”,但真正打开dump分析…

作者头像 李华
网站建设 2026/10/8 8:36:08

本科毕设文本摘要实战:BART微调与ROUGE评估全流程

简介:本资源是一套面向本科生的深度学习文本摘要实践项目,聚焦自然语言处理中的关键任务——自动摘要生成,特别适合作为本科毕业设计选题与实现参考。项目基于Transformer架构构建端到端摘要模型,涵盖数据预处理、模型训练、评估&…

作者头像 李华
网站建设 2026/10/8 8:35:23

Superpowers技能包:让Claude Code告别重复提示词,拥有稳定工作流

如果你也在用 Claude Code 做日常开发,大概早就被它的“Agent 自主干活”能力惊艳过,但用久了你会发现一个尴尬:每次让它做同一类事,比如整理需求、拆任务、生成示意图,它都要重新理解一遍你的流程,像是每次…

作者头像 李华
网站建设 2026/10/8 8:33:35

Teigha4实战:脱离AutoCAD用C#读写DWG的完整流程与避坑指南

简介:面向AutoCAD二次开发人员的Teigha(原OpenDwg/DWGdirect)开发资料包,专门解决不启动AutoCAD即可读写DWG文件的技术难题,也可为独立CAD工具链提供底层支持。资料附带完整的帮助文档,并提供VB.NET与C#两套…

作者头像 李华
网站建设 2026/10/8 8:32:42

Unity5跨平台游戏开发:C#源码组织与平台适配技巧

简介:《Unity5实战:使用C#和Unity开发多平台游戏》源码,是一份面向初、中级Unity开发者的学习型资源,尤其适合想要系统掌握跨平台游戏开发流程的读者。资源以Unity5引擎和C#语言为核心,从组件系统、Transform与脚本协同…

作者头像 李华