news 2026/9/26 13:11:47

ARM内网离线部署Harbor v2.10.2:aarch64私有镜像仓库实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ARM内网离线部署Harbor v2.10.2:aarch64私有镜像仓库实战指南

简介:本资源为面向国产化 ARM 架构环境的 Harbor 容器镜像仓库离线安装包,版本为 v2.10.2,适合在信创服务器、麒麟/统信等国产操作系统上部署私有镜像仓库的运维与开发人员使用,可解决内网无外网条件下快速搭建镜像仓库的问题。压缩包共包含 6 个文件,以 shell 脚本、gz 压缩包、license 许可文件、prepare 预处理文件及 tmpl 配置模板为主,分别承担安装执行、镜像数据打包、许可声明与配置生成等职责,整体约 650.11MB,属于典型的离线全量安装形态。目前已有 98 人学习下载,说明该版本在国产化替代场景中具备一定关注度。借助该包,读者可省去逐一下载组件与镜像的繁琐过程,直接完成 Harbor 的离线部署与初始化配置,并基于模板文件调整端口、存储与认证参数,快速获得可用的私有镜像仓库环境。

1. 从 harbor-offline-installer-aarch64-v2.10.2.tgz 说起:ARM 内网私有镜像仓库到底难在哪

如果你手上正好有一台鲲鹏、飞腾或者银河麒麟的 ARM 服务器,又恰好被要求「在内网搭一个 Harbor」,那你大概率已经搜到了harbor-offline-installer-aarch64-v2.10.2.tgz这个包。它不是一个普通的压缩包,而是 Harbor 官方为 aarch64 架构准备的离线安装器——里面打包了所有容器镜像的 tar 包、docker-compose 编排文件、prepare 脚本和 install.sh,解压即用,不需要在目标机器上再拉任何外网镜像。这件事在 x86 上早就被写烂了,但在 aarch64 上,坑的数量至少翻一倍:镜像架构不匹配、Docker Compose 版本对不上、内核参数没调、证书路径写死、离线包解压后目录权限丢失,任何一个都能让你在客户现场耗掉一整个下午。

这篇文章面向的是真正要在 ARM 内网里把 Harbor 跑起来的人——不是看个热闹,而是明天就要去机房的那种。我会按「这个包到底是什么 → 环境怎么准备 → 怎么装 → 怎么验证 → 坑在哪 → 怎么进阶」的顺序,把 v2.10.2 这个版本在 aarch64 上的完整落地路径讲清楚。中间会给出可直接抄的命令和配置,也会说明每个参数为什么这么设。如果你用的是 CentOS 7.9 aarch64、银河麒麟 V10 或者类似的国产 ARM 系统,这篇的步骤基本可以直接复用。

2. 拆开这个 tgz:离线安装器里到底装了什么

2.1 离线包与在线安装的本质区别

Harbor 的安装方式分两种:在线安装器(online-installer)和离线安装器(offline-installer)。在线安装器只包含编排文件和脚本,安装时通过docker pull从 Docker Hub 拉取 harbor-core、harbor-portal、harbor-db、redis、nginx 等镜像。离线安装器则把这些镜像提前docker save成 tar 包,一并塞进压缩包里。harbor-offline-installer-aarch64-v2.10.2.tgz就是后者,而且文件名里的aarch64明确告诉你:里面的镜像全是 ARM64 架构的。

这个区别在纯内网环境里是致命的。很多客户的服务器根本不通外网,甚至连内网的 yum 源都不一定有 Harbor 需要的依赖。在线安装器在这种环境下第一步docker pull就会卡死,而离线安装器解压后直接docker load,全程不需要网络。这也是为什么标题里这个包在 ARM 内网场景下几乎是唯一选择。

从体积上看,离线包通常在 600MB 到 1GB 之间,解压后镜像 tar 包会占用更多空间。所以第一件事是确认/var/lib/docker所在分区至少有 20GB 可用空间,/data分区(Harbor 默认数据目录)至少 50GB。这不是保守估计,是血泪经验——harbor-db 的 PostgreSQL 数据、registry 的 blob 存储、redis 的持久化文件都会往/data写,镜像一多,空间消耗比你想的快得多。

2.2 包内目录结构与关键文件

解压后你会看到这样的结构:

harbor/ ├── harbor.v2.10.2.tar.gz # 所有容器镜像的打包文件 ├── harbor.yml.tmpl # 配置模板 ├── prepare # 生成最终 docker-compose.yml 的脚本 ├── install.sh # 一键安装脚本 ├── common.sh # 公共函数库 └── docker-compose.yml.tmpl # 编排模板

harbor.yml.tmpl是你要改的核心文件。prepare脚本会读取harbor.yml(你从模板复制出来的),结合docker-compose.yml.tmpl生成最终的docker-compose.yml。install.sh则依次执行prepare、docker load、docker-compose up -d。理解这个流程很重要,因为出问题时你需要知道是哪一步挂了。

提示:不要直接改docker-compose.yml.tmpl,那个文件是模板,prepare每次都会重新生成docker-compose.yml,你的修改会被覆盖。所有配置改动都在harbor.yml里做。

2.3 aarch64 架构带来的额外约束

x86 上装 Harbor,你基本不用操心镜像架构。但在 aarch64 上,如果镜像 tag 对应的 manifest 不是 ARM64,docker load之后docker-compose up会直接报exec format error。v2.10.2 的 aarch64 离线包已经帮你处理好了这个问题——里面的镜像都是官方构建的 ARM64 版本。但如果你中途想升级某个组件,或者从别处拷了一个 x86 的镜像 tar 包进来,就会翻车。

另一个约束是 Docker 和 Docker Compose 的版本。Harbor v2.10.2 要求 Docker 20.10 以上、Docker Compose v2 以上。CentOS 7.9 aarch64 默认 yum 源里的 Docker 版本往往偏低,需要手动指定版本安装。银河麒麟 V10 的情况类似,系统自带的容器工具链版本参差不齐,建议统一用 Docker 官方提供的 aarch64 静态二进制包来装。

3. 装之前先把地基打好:ARM 服务器环境准备清单

3.1 系统层:内核参数、SELinux 与防火墙

在 aarch64 的 CentOS 7.9 或银河麒麟 V10 上,装 Harbor 之前有几件事必须先做。第一是内核参数,Harbor 的 nginx 和 harbor-core 在高并发下会打开大量文件描述符,默认的 1024 不够用:

# 查看当前限制 ulimit -n # 永久修改,写入 /etc/security/limits.conf cat >> /etc/security/limits.conf <<EOF * soft nofile 65536 * hard nofile 65536 EOF # 内核层面也调一下 cat >> /etc/sysctl.conf <<EOF net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 vm.max_map_count = 262144 EOF sysctl -p

net.ipv4.ip_forward = 1是 Docker 网络转发的前提,vm.max_map_count是 Elasticsearch 组件(Harbor 的日志存储)需要的,不设的话 ES 容器会启动失败。bridge-nf-call-iptables这两个参数在 CentOS 7.9 aarch64 上默认可能是关闭的,不打开会导致容器间网络不通。

第二是 SELinux。Harbor 的容器需要挂载宿主机目录,SELinux enforcing 模式下会拒绝这些挂载:

# 查看状态 getenforce # 临时设为 permissive setenforce 0 # 永久关闭,编辑 /etc/selinux/config,把 SELINUX=enforcing 改为 SELINUX=disabled sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

第三是防火墙。如果你只是内网测试,可以直接systemctl stop firewalld && systemctl disable firewalld。如果必须开防火墙,需要放行 Harbor 用到的端口:80(HTTP)、443(HTTPS)、4443(如果启用 Notary)。注意 Harbor 的 nginx 容器会占用宿主机 80 和 443,如果宿主机上已经有 nginx 或 httpd 在跑,先停掉。

3.2 容器运行时:Docker 与 Docker Compose 的 aarch64 安装

CentOS 7.9 aarch64 的默认 yum 源里,Docker 版本通常是 1.13 或更早,完全不满足 Harbor v2.10.2 的要求。推荐用 Docker 官方的静态二进制包安装:

# 下载 aarch64 版本的 Docker 静态包 # 注意:这里需要你提前把对应的 tgz 传到内网,或者从内网源获取 tar -xzvf docker-24.0.7.tgz cp docker/* /usr/bin/ # 创建 systemd 服务文件 cat > /etc/systemd/system/docker.service <<EOF [Unit] Description=Docker Application Container Engine After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP \$MAINPID LimitNOFILE=infinity LimitNPROC=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable docker systemctl start docker docker version

Docker Compose 在 v2 之后变成了一个 Go 二进制,不再依赖 Python。aarch64 版本可以从内网源获取,放到/usr/local/bin/docker-compose并加执行权限即可。验证:

docker-compose version # 应该输出 Docker Compose version v2.x.x

注意:Harbor v2.10.2 的install.sh会检查docker-compose命令是否存在。如果你只装了docker compose插件而没有独立的docker-compose二进制,脚本会报错。建议两个都装上,或者做一个软链接。

3.3 存储与目录规划

Harbor 默认把数据放在/data目录下,包括/data/database(PostgreSQL)、/data/registry(镜像 blob)、/data/redis、/data/log等。在生产环境里,建议把/data单独挂一块盘,或者至少确保它所在的分区有足够空间。

# 创建数据目录 mkdir -p /data # 如果 /data 是单独分区,确认挂载 df -h /data # 设置权限,Harbor 容器内以特定 UID 运行,需要目录可写 chmod 755 /data

另外,harbor.yml里可以配置data_volume来改变数据目录位置。如果你想把数据放到/opt/harbor-data,就在配置里改这一项,而不是去改 docker-compose 文件。

4. 从解压到登录:harbor-offline-installer-aarch64-v2.10.2.tgz 的完整安装流程

4.1 解压与 harbor.yml 的最小化配置

把 tgz 包传到目标服务器后,第一步是解压:

tar -xzvf harbor-offline-installer-aarch64-v2.10.2.tgz cd harbor ls -lh

你会看到harbor.v2.10.2.tar.gz这个镜像包,以及harbor.yml.tmpl。复制一份作为实际配置:

cp harbor.yml.tmpl harbor.yml

然后编辑harbor.yml,最小化配置只需要改这几项:

# 主机名,可以是 IP 或域名。内网环境建议直接用 IP hostname: 192.168.1.100 # HTTP 配置,内网如果不做 HTTPS,只留 http 段 http: port: 80 # HTTPS 配置,如果不用就整段注释掉 # https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path # Harbor 管理员初始密码,务必改掉默认的 Harbor12345 harbor_admin_password: YourStrongPassword123 # 数据目录 data_volume: /data # 数据库密码,离线安装会自动生成,也可以手动指定 database: password: root123 max_idle_conns: 100 max_open_conns: 900 # 日志配置 log: level: info local: rotate_count: 50 rotate_size: 200M location: /data/log

hostname这一项特别关键。如果你填了 IP,后面docker login就必须用这个 IP;如果填了域名,需要确保内网 DNS 能解析,或者在各客户端的/etc/hosts里加记录。填错了会导致docker push时报dial tcp: lookup xxx: no such host。

harbor_admin_password是 admin 用户的初始密码,v2.10.2 默认是Harbor12345,但很多安全扫描会直接把这个默认密码列为高危项。建议在安装前就改掉,而不是装完再去 UI 里改。

4.2 执行 install.sh 与各阶段日志解读

配置改好后,执行安装脚本:

./install.sh

这个脚本会依次做几件事,每件事的输出都值得关注:

第一阶段是prepare,它会检查harbor.yml的语法,然后生成docker-compose.yml。如果这一步报错,通常是 YAML 缩进问题或者某个必填项没填。比如hostname为空、data_volume路径不存在等。

第二阶段是docker load,把harbor.v2.10.2.tar.gz里的镜像逐个加载到本地。这一步在 ARM 服务器上可能比较慢,因为镜像层解压和写入磁盘需要时间。如果中途报no space left on device,就是/var/lib/docker空间不够。

第三阶段是docker-compose up -d,启动所有容器。启动完成后,脚本会输出:

----Harbor has been installed and started successfully.----

但这不代表所有容器都健康。用以下命令检查:

docker-compose ps

正常情况下你会看到 9 到 10 个容器,状态都是Up或Up (healthy)。如果有容器是Exit或Restarting,就需要看日志:

docker-compose logs -f harbor-core docker-compose logs -f harbor-db

harbor-db启动失败最常见的原因是数据目录权限问题或者 PostgreSQL 版本与数据目录不兼容(如果你之前装过旧版本,/data/database里有旧数据)。

4.3 验证安装:API 健康检查与 docker login

容器都起来后,先做 API 健康检查:

curl -k https://192.168.1.100/api/v2.0/health # 如果只配了 HTTP curl http://192.168.1.100/api/v2.0/health

正常返回是一个 JSON,包含status: healthy。如果返回 502,说明 nginx 容器起来了但后端 harbor-core 还没就绪,等几十秒再试。

然后验证docker login:

docker login 192.168.1.100 -u admin -p YourStrongPassword123

如果报Error response from daemon: Get "https://192.168.1.100/v2/": dial tcp ...: connect: connection refused,说明你配了 HTTPS 但证书有问题,或者端口不对。如果报x509: certificate signed by unknown authority,说明用的是自签证书但 Docker 不信任。内网环境最简单的做法是只配 HTTP,然后在 Docker 的 daemon.json 里加insecure-registries:

{ "insecure-registries": ["192.168.1.100"] }

改完重启 Docker:systemctl restart docker。注意,重启 Docker 会导致 Harbor 容器全部停止,需要重新docker-compose up -d。

登录成功后,可以做一个完整的 push/pull 测试:

# 拉一个小的 ARM64 镜像做测试 docker pull arm64v8/alpine:latest # 打 tag docker tag arm64v8/alpine:latest 192.168.1.100/library/alpine:test # push docker push 192.168.1.100/library/alpine:test # 删掉本地镜像再拉回来 docker rmi 192.168.1.100/library/alpine:test docker pull 192.168.1.100/library/alpine:test

这一套走通,说明 Harbor 的存储、认证、registry 组件都正常。

5. 避坑指南:aarch64 内网装 Harbor 最容易翻车的 5 个点

5.1 现象:docker load 报 exec format error

原因:镜像 tar 包里的镜像不是 ARM64 架构。这种情况通常发生在你从 x86 环境拷贝了某个镜像 tar 包,或者离线包在传输过程中被替换过。docker load本身不检查架构,但docker-compose up启动时会因为无法执行而报错。

解决:用docker inspect检查镜像的 Architecture 字段:

docker inspect harbor-core:v2.10.2 | grep Architecture # 应该输出 "Architecture": "arm64"

如果是amd64,说明镜像不对。重新从官方 aarch64 离线包里获取,或者用docker pull --platform linux/arm64从内网源拉取正确的镜像。

5.2 现象:harbor-db 容器反复重启,日志显示 permission denied

原因:/data/database目录的属主或权限不对。Harbor 的 PostgreSQL 容器以 UID 999 运行,如果宿主机上这个目录是 root 所有且权限是 700,容器内进程无法写入。

解决:

chown -R 999:999 /data/database chmod 700 /data/database docker-compose restart harbor-db

如果之前已经因为权限问题导致数据目录损坏,可能需要清空/data/database重新初始化。注意这会丢失所有 Harbor 的元数据(项目、用户、策略),但 registry 里的镜像 blob 还在,需要重新扫描。

5.3 现象:docker push 时卡在 Waiting 然后报 413 Request Entity Too Large

原因:Harbor 的 nginx 容器默认限制请求体大小为 0,但某些版本的 nginx 配置模板里可能带了限制。另外,如果 Harbor 前面还有一层负载均衡或反向代理,那一层也可能有限制。

解决:检查common/config/nginx/nginx.conf里的client_max_body_size,v2.10.2 默认是 0(不限制)。如果前面有代理,在代理层也放开。另外,harbor.yml里可以配max_job_workers和registry的max_threads,但 413 通常不是这些参数导致的。

5.4 现象:安装完成后浏览器访问显示 502 Bad Gateway

原因:harbor-core 容器还没完全启动,或者 harbor-core 依赖的 redis、db 没就绪。Harbor 的组件启动有顺序依赖,docker-compose up -d虽然会按 depends_on 顺序启动,但容器内的服务就绪还需要时间。

解决:等 1 到 2 分钟,然后看 harbor-core 的日志:

docker-compose logs --tail=100 harbor-core

如果日志里还在输出waiting for db或waiting for redis,说明依赖组件还没好。如果日志里有panic或fatal,那就是配置问题,需要根据具体错误排查。

5.5 现象:重启服务器后 Harbor 没有自动启动

原因:docker-compose up -d启动的容器默认 restart policy 是no,服务器重启后容器不会自动拉起。Harbor 的install.sh没有配置 systemd 服务。

解决:手动创建一个 systemd 服务:

cat > /etc/systemd/system/harbor.service <<EOF [Unit] Description=Harbor After=docker.service systemd-networkd.service systemd-resolved.service Requires=docker.service Documentation=http://github.com/vmware/harbor [Service] Type=simple Restart=on-failure RestartSec=5 ExecStart=/usr/bin/docker-compose -f /root/harbor/docker-compose.yml up ExecStop=/usr/bin/docker-compose -f /root/harbor/docker-compose.yml down [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable harbor

注意ExecStart里的路径要改成你实际的 harbor 目录。这样服务器重启后 Harbor 会自动拉起。

6. 进阶:让 ARM 内网 Harbor 真正扛住生产流量

装完只是开始。在 aarch64 内网环境里,Harbor 要真正当生产仓库用,还有几件事值得做。

第一是启用 HTTPS。内网虽然可以走 HTTP,但 Docker 客户端对 insecure-registry 的支持在有些版本上不稳定,而且很多 CI/CD 工具链默认要求 HTTPS。用自签证书的话,需要把 CA 证书分发到所有客户端的/etc/docker/certs.d/192.168.1.100/目录下。具体做法是:生成 CA 和服务器证书,在harbor.yml里配好https段,重新执行./install.sh。注意重新执行 install.sh 会重新生成 docker-compose.yml 并重启容器,但不会丢失数据。

第二是配置存储后端。Harbor 默认把镜像存在本地文件系统,对于多节点或需要共享存储的场景,可以配 S3 兼容对象存储。在harbor.yml里加:

storage_service: s3: accesskey: your_access_key secretkey: your_secret_key region: us-west-1 bucket: harbor-registry endpoint: http://minio.internal:9000 insecure: true

改完同样需要重新./install.sh。注意,切换存储后端不会自动迁移已有镜像,需要手动用docker pull+docker push或者 Harbor 的复制功能来迁移。

第三是垃圾回收。Harbor 删除镜像后,registry 的 blob 不会立即释放,需要手动触发 GC:

# 进入 harbor-db 容器执行 GC docker-compose exec harbor-db psql -U postgres -d registry -c "SELECT * FROM blob_upload;" # 或者用 Harbor 的 API 触发 curl -u admin:YourPassword -X POST "http://192.168.1.100/api/v2.0/system/gc/schedule" \ -H "Content-Type: application/json" \ -d '{"schedule":{"type":"Manual"}}'

GC 期间 registry 会进入只读模式,建议在业务低峰期做。在 ARM 服务器上,GC 的 CPU 和 IO 消耗比 x86 更明显,因为 ARM 的单核性能通常弱一些,大仓库的 GC 可能跑几十分钟。

第四是监控。Harbor 暴露了 Prometheus 格式的 metrics,在harbor.yml里可以配metrics段开启。对于 ARM 内网环境,建议至少监控/data分区使用率、harbor-core 的 JVM 堆内存(如果用的是 Java 组件)、以及 registry 的请求延迟。我一般会在 Harbor 同一台机器上跑一个轻量级的 node_exporter 和 cAdvisor,用 Prometheus 抓取,Grafana 出图。ARM 上跑这些监控组件资源消耗不大,但能让你在磁盘写满之前收到告警。

最后说一个我自己的习惯:每次在客户现场装完 Harbor,我都会立刻做一个「恢复演练」——把/data目录打包备份,然后故意删掉一个测试项目,再从备份里恢复。这个动作花不了十分钟,但能让你在真正出问题时心里有底。ARM 内网环境往往没有外网可以查资料,现场能依靠的只有自己的笔记和备份。希望帮到你。

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

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

生产级RAG知识库与Agent网关优化实战:检索质量与调度策略

1. 生产级知识库和 Agent 网关到底在解决什么问题先把场景摆出来。你手头有一套 RAG 知识库&#xff0c;可能是 Dify 流水线拉的&#xff0c;也可能是 Ollama LangChain Chroma 自己拼的&#xff0c;文档进了向量库&#xff0c;检索也能跑通。然后你接了一个 Agent&#xff0…

作者头像 李华
网站建设 2026/9/26 13:08:50

CLI才是王道:OpenClaw与InfiniSynapse的共识——TaoToken统一Key接入实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 13:06:52

企业AI落地的完整方法论:从业务盘点到两周样板间

2000人抢着上一门课&#xff0c;放在哪个行业都算稀罕事。课程火成这样&#xff0c;不是我PPT讲得多漂亮&#xff0c;而是从第一天起我就把话说死了&#xff1a;这门课教的不是“用AI”&#xff0c;是“替公司把AI用起来”。个人学AI&#xff0c;解决的是“我怎么更快把活干完”…

作者头像 李华