☰
ARM架构离线部署Harbor:aarch64安装包实操与避坑指南
2026/10/10 3:52:05 网站建设 项目流程

简介:面向国产化ARM架构环境的Harbor 2.10.2离线安装包,适配信创场景下的容器镜像仓库部署需求,尤其适合鲲鹏、飞腾等国产CPU服务器使用。资源针对无法直接访问外网拉取镜像的内网环境,提供了一体化的tgz压缩包,共6个文件,包括两个shell脚本(安装与初始化)、一个镜像压缩包、许可证文件、prepare预处理文件以及harbor.yml.tmpl配置模板,整体体积约650MB。已有98人学习下载,适合需要在国产化服务器上快速搭建Harbor的运维、开发或架构人员使用。通过该包可一次性获得离线安装所需的全部组件,省去逐项下载和依赖匹配的麻烦;同时附带的配置模板和预处理脚本,便于根据实际环境调整端口、存储等参数并完成部署,对推进容器化业务在信创环境落地具有直接参考价值,也可作为离线交付场景下的标准化安装素材。

1. 内网ARM机器上搭镜像仓库,先从这份aarch64离线安装包说起

一台新到货的ARM架构服务器放进隔离内网,Docker装好了,系统也配好了,可整个环境没有外网出口,基础镜像都拉不齐。要在这台机器上自建镜像仓库,最直接的办法就是用离线安装包:harbor-offline-installer-aarch64-v2.10.2.tgz,拷进去、解压、改配置、跑脚本,一套带Web管理界面、项目权限、镜像复制功能的私有仓库就能起来,全程不需要联网。这份包解决的正是这类场景——ARM架构设备上做镜像交付,隔离网络里搭私有仓库,没有外网也照样把镜像流转起来。适合正在做ARM架构迁移、或者需要在离线环境交付镜像平台的运维和平台工程师。

2. 拆开离线安装包之前:先确认三件事再动手

离线安装包的优势是把依赖全塞进了一个文件里,但代价是这文件在解压前是个黑匣子:里面有哪些组件、目标机器跑不跑得动、镜像架构配不配,解压前全看不到。我吃过亏,所以现在拿到任何离线安装包,第一件事不是急着tar解压,而是先过三关:包内结构、环境前提、架构匹配。这三关不过,后面每一步都在给翻车埋雷。

2.1 安装包里有什么:installer脚本与离线镜像包的配合关系

解压之后,目录里的核心文件其实没几个,但各自分工非常明确。

tar xzf harbor-offline-installer-aarch64-v2.10.2.tgz cd harbor && ls -lh
文件作用
harbor.yml.tmpl主配置模板,复制为harbor.yml后才生效
install.sh安装入口,内部按顺序调用prepare、load镜像、docker compose up
prepare配置生成器,根据harbor.yml生成docker-compose.yml和各组件配置文件
common.sh公共函数库,install.sh和prepare都会引用
harbor.v2.10.2.tar.gz离线镜像包,存放Harbor全部组件的容器镜像

这里要理解一个关键点:install.sh和harbor.v2.10.2.tar.gz是配合关系。install.sh负责逻辑编排,真正的组件镜像全在那一个tgz里。install.sh执行过程中会用docker load把镜像包导入本地镜像仓库,再通过docker compose把整套服务拉起来。所以整包可以理解为「安装器+全量镜像」二合一,这也是offline-installer这个名字的来由。

Harbor v2.10.2的组件容器包括这些:harbor-core负责API、认证和项目权限;harbor-registry承担镜像存储与分发;harbor-registryctl做registry的配置与健康检查;harbor-jobservice处理异步任务,镜像复制、垃圾回收、漏洞扫描都走它;harbor-portal是Web前端;harbor-db跑PostgreSQL存元数据;redis做缓存和任务队列;nginx在最前面做反向代理统一入口,客户端访问的就是它。

2.2 部署前提检查:架构、内存、磁盘、Docker版本一项一项过

离线包里是完整运行环境,对宿主机有硬性要求。我一般先把下面这段检查脚本跑一遍,全部通过才继续。

uname -m cat /etc/os-release | head -3 free -h df -h /data docker --version docker compose version

逐项说明:uname -m 输出aarch64才说明是ARM 64位架构,包名里已经写着aarch64,这一步是双确认;os-release看发行版,Ubuntu 20.04/22.04、Debian 11/12、以及基于这些的国产发行版都能跑,但依赖包名会不一样,比如Ubuntu下docker compose插件对应docker-compose-plugin这个包;free -h主要看可用内存,Harbor完整跑起来大概占2到3G,建议物理内存不低于8G,内存不够时nginx和core容器容易反复重启;df -h /data看的是数据目录所在磁盘,默认data_volume指向/data,镜像存储和数据库全在里面,务必预留100G以上,而且最好单独挂一块数据盘而不是系统盘。

Docker版本这条最容易漏。Harbor v2.10用的是docker compose v2语法,也就是docker compose这个子命令,而不是老式的docker-compose独立二进制。Docker Engine版本建议20.10以上,同时确认compose插件存在。之前碰到过一台只装了docker-ce没装compose插件的主机,install.sh跑到最后一步直接报docker: 'compose' is not a docker command。

2.3 aarch64与x86的镜像不能混用:为什么load成功却跑不起来

很多人觉得离线包嘛,能解压能load就能用,实际上容器镜像是按CPU架构编译的,镜像的manifest里明确记录了architecture字段。docker load只负责把tar里的镜像层导入本地,不做架构校验,所以你在aarch64机器上能成功load一个amd64镜像。但容器一启动,内核执行第一个进程时就炸了,最常见的报错是exec user process caused: exec format error,容器状态反复CrashLoopBackOff。

判断镜像架构最直接的办法是inspect。

docker image inspect harbor-core:v2.10.2 --format '{{.Architecture}}'

拿到的值如果是amd64,那这镜像就是x86的,加载到ARM机器上必然翻车。这也是Harbor离线安装包要区分aarch64和amd64两个版本的根本原因:镜像层是架构绑定的,没法通用。我在一个交付项目里就见过有人图省事,把x86的包拷到ARM机器上,docker load全成功,结果install.sh跑完容器全部异常退出,排查半天才意识到是架构不对。从那以后我养成个习惯:任何服务器上装任何容器服务,第一件事先uname -m,再确认包名和架构对得上。

3. 从解压到Harbor登录页:完整部署过程与参数解释

前提全部确认完之后,部署本身反而是体力活。Harbor的离线安装设计得比较规整,核心就四步:解压、改配置、prepare、install。但每步里都有值得细说的参数和坑,照着做能一次过。

3.1 解压与配置就位:为什么必须复制harbor.yml.tmpl而不是直接改

先把包解压到目标位置,建议放到/opt或/usr/local这类固定目录,别扔在/tmp里,后面升级和排查都要用。

mkdir -p /opt/harbor-offline tar xzf harbor-offline-installer-aarch64-v2.10.2.tgz -C /opt/harbor-offline cd /opt/harbor-offline/harbor cp harbor.yml.tmpl harbor.yml

这里有个隐藏约定:Harbor的安装脚本只认harbor.yml,不认模板文件。直接从tmpl改虽然也能用,但会破坏原始模板,后面要对比默认配置或重新生成时就没有参照了。正确的做法永远是cp一份出来改,模板保留原样。复制完可以用grep -v '^#' harbor.yml | grep -v '^$'快速看一眼生效的配置项,确认没有语法层面的低级错误。

3.2 修改harbor.yml核心项:hostname、密码、数据目录是三个命门

harbor.yml里要改的项不多,但有三个地方改错会让整个仓库不可用:hostname、harbor_admin_password、data_volume。下面是一份典型的配置片段。

hostname: 192.168.209.133 http: port: 80 harbor_admin_password: Harbor@2024! data_volume: /data log: level: info local: rotate_count: 15 rotate_size: 200M

hostname这条最要命。它不只是给Harbor自己用的,所有客户端执行docker login、docker push时访问的地址都以它为准。填localhost的话,只有本机能登录,局域网内其他机器全连不上;填一个IP,那这个IP就是整个环境的固定入口,后续IP变了全部客户端都要跟着改配置。所以上线前一定想清楚:是填内网固定IP,还是填一个能长期稳定的内部域名。如果走域名,记得在所有客户端机器的/etc/hosts里配好解析。

harbor_admin_password是admin账号的初始密码,要求至少8位且包含大小写字母和数字。很多人忽略的是:这个字段只在首次初始化时生效,如果装完第一次登录后改了密码,再重装时harbor.yml里的旧密码不会覆盖已存在的账号。数据卷路径data_volume决定镜像和数据库落盘位置,建议指向独立数据盘,比如/data,且目录要先建好、属主改成当前用户,否则prepare阶段会报权限错误。

3.3 手动执行prepare再install:分开跑能少走弯路

很多教程直接叫人跑./install.sh,但我会把prepare单独拎出来先执行一遍。

./prepare

prepare的作用是根据harbor.yml生成docker-compose.yml,并写入nginx、core、registry等组件的配置。跑它不启动任何容器,纯粹做配置渲染和格式校验。如果harbor.yml里有语法错误或必填项缺失,这一步就会直接报错,不至于等到install.sh跑到一半才暴露。确认prepare输出没有error后再执行真正的安装。

./install.sh

install.sh内部做了三件事:先调用prepare,再用docker load导入离线镜像包,最后docker compose up -d启动全部服务。跑完看容器状态:

docker compose ps

正常状态应该是所有服务都是Up,端口监听在80和443。如果看到某个容器反复Restarting,用docker compose logs -f <服务名>看日志定位,常见是磁盘不足、端口被占、数据库初始化失败。

3.4 部署后的第一轮验收:页面、登录、推送一条龙

容器起来了不代表能用,我习惯按下面这条链路做验收,每个环节过了再进下一步。

curl -I http://192.168.209.133/ docker login 192.168.209.133:80 -u admin docker tag busybox 192.168.209.133:80/library/busybox:v1 docker push 192.168.209.133:80/library/busybox:v1

先curl看nginx响应头,确认80端口有HTTP应答;再docker login验证认证链路;然后tag一个镜像推到library项目。选library是因为它是系统自带公共项目,推镜像时绕开了项目权限这层干扰,能最快定位是认证问题还是存储问题。这里有个前置条件:如果daemon.json里没配insecure-registries,而Harbor又没开HTTPS,docker login会直接报x509证书错误,这是预期内的,按第4章4.2节处理。

4. 部署与使用中的高频问题排查:现象、原因与处理

Harbor部署完成只是起点,日常使用中推送失败、登录报401、页面打不开这几类问题,我几乎每个交付项目都遇到过。下面是踩坑后沉淀的排查清单,每条都按现象、原因、解决三个维度拆开。

4.1 docker push报错:get "https://192.168.209.133/v2/": dial tcp 192.168.209.133: 后面是空的

这个报错是Harbor使用里最高频的,没有之一。完整错误里dial tcp后面的端口经常是空的,或者跟一句connect: connection refused,看起来像被截断了。本质是docker客户端连不上Harbor的nginx入口。

原因有三类,要分清楚再动手。第一类是Harbor服务没起来,docker compose ps能看到nginx状态是Exit或Restarting,这种情况多半是80端口被占用导致容器起不来。第二类是网络层不通,宿主机防火墙没放行80/443端口,或者客户端和服务器之间存在网络隔离策略。第三类最常见:daemon.json没配insecure-registries,docker默认先走HTTPS,而Harbor只开了HTTP端口,请求发到HTTPS的443上,nginx没监听,连接直接被拒。

解决路径也按这个顺序排查。

telnet 192.168.209.133 80 docker compose ps cat /etc/docker/daemon.json

telnet能通但docker push不通,基本就是HTTPS问题;telnet都不通,去看防火墙和服务状态。daemon.json里需要这样配:

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

注意:如果Harbor的http端口改成了非80,比如8080,那insecure-registries里要写成["192.168.209.133:8080"],端口必须带上。改完daemon.json要重启docker生效:systemctl restart docker,但这一步会让机器上所有容器跟着重启,有存量业务的话提前找维护窗口。

4.2 docker login报401或x509:认证与证书问题要分开看

现象很直观:docker login要么提示unauthorized: authentication required,要么报x509: certificate signed by unknown authority。两个错误指向完全不同的问题。

401是认证链路问题。admin密码被改过但你还用harbor.yml里那个旧值;或者账密对但项目权限不够,普通用户登录后只能看有权限的项目。另外Harbor里admin账号默认启用了两阶段密码,如果配置了LDAP认证但没真正连接上目录服务,也会出现密码正确但登不上的诡异情况。

x509是证书信任问题。Harbor没配HTTPS证书,但docker客户端默认走HTTPS;或者Harbor配了自签证书,但客户端不认这个签发机构。解决x509有两条路:要么在daemon.json里把Harbor地址加进insecure-registries,让docker对这个地址跳过HTTPS校验;要么把自签证书的CA放到客户端信任目录里。内网环境图省事走前者,生产环境还是按第5章的HTTPS方案正规配一遍。

4.3 页面能开但项目接口报500:数据库或redis先掉链子

现象比较隐蔽:Web首页能打开,登录也成功,但创建项目、查看复制任务、清理垃圾回收这些操作一点就报500。这时候去看后端日志最直接。

tail -n 100 /var/log/harbor/core.log

常见两个原因。一个是磁盘写满,data_volume所在分区满了以后,PostgreSQL写入失败,所有涉及元数据的接口全部500,但nginx和portal因为是静态服务,页面照常打开。用df -h确认后清理大文件或无用的镜像层。另一个是redis端口冲突:宿主机上如果装了系统自带的redis-server并占用6379端口,Harbor的redis容器绑定失败,core服务拿不到缓存和任务队列,表现就是页面能看但所有写操作都失败。解决要么停掉宿主机的redis,要么在harbor.yml里给Harbor的redis改端口,然后重新prepare和install。

4.4 宿主机重启后Harbor连不上:恢复顺序比命令本身更重要

机房断电或reboot之后,Harbor页面打不开,这是运维最常见的深夜告警。排查时先看docker服务,再看容器状态。

systemctl status docker cd /opt/harbor-offline/harbor docker compose up -d docker compose ps

很多人直接在harbor目录下重新跑一遍./install.sh,这其实没必要。install.sh会再load一次离线镜像包,纯属浪费时间,正确动作是docker compose up -d把已有容器拉起即可。前提是docker服务本身开机自启,确认一下:systemctl enable docker。如果data_volume是独立挂载的数据盘,还要确认数据盘挂载顺序在docker启动之前,否则容器起来后数据目录还是空的,数据库会重新初始化,等于数据全丢。这块我一般会在/etc/fstab里加nofail选项,避免数据盘挂载失败导致系统启动卡住。

4.5 把x86机器的镜像包直接搬到aarch64机器上:exec format error

这个问题在ARM架构迁移场景下反复出现。现象是docker load显示Loaded image成功,但容器启动失败,docker logs看到exec user process caused: exec format error。原因就是镜像架构是amd64,在aarch64内核上无法执行。docker load不做架构校验,只有真正运行到exec阶段才会暴露。

排查用inspect命令确认架构:

docker image inspect library/busybox:v1 --format '{{.Architecture}}'

如果显示amd64,这镜像就是错的。解决思路只有一个:去aarch64环境重新拉对应架构的镜像,再用docker save打包带回来,不要试图在ARM机器上转换架构。顺带说一句,docker manifest子命令可以一次性列出镜像的所有可用架构:docker manifest inspect busybox:latest,在离线环境里提前确认好架构能省掉一轮无效搬运。

5. 上线前的加固与维护:HTTPS、备份、GC和版本锁定

如果Harbor只在内网跑、不对外暴露,前面部署完已经可以用了。但作为长期服务的镜像仓库,有几件事我建议上线前做掉,不然后面补起来成本更高。

5.1 给Harbor配一张自签HTTPS证书

内网环境不一定要花钱买证书,自签足够。先准备CA和服务器证书,注意SAN里要把hostname对应的IP和域名都写进去。

mkdir -p /data/cert && cd /data/cert openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt openssl req -newkey rsa:4096 -nodes -sha256 -keyout server.key -out server.csr

生成CSR后建一个extfile.cnf,内容加上SAN:

subjectAltName = IP:192.168.209.133,DNS:harbor.internal

然后用CA签发服务器证书,最后在harbor.yml里启用HTTPS段落:

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

改完重新./prepare和./install.sh即可。客户端那边要把ca.crt放到/etc/docker/certs.d/192.168.209.133:443/ca.crt,然后重启docker,daemon.json里的insecure-registries就可以去掉了。

5.2 备份范围、GC清理与镜像复制

备份Harbor不是简单打包目录,重点是保证数据一致性。我一般先停服再备份。

cd /opt/harbor-offline/harbor docker compose down tar czf harbor-data-backup-$(date +%Y%m%d).tgz /data docker compose up -d

这份备份包含了数据库、镜像存储、密钥和配置,整机迁移时在同版本Harbor上恢复最可靠。GC是回收已删除镜像层的功能,在Web界面的「垃圾回收」里触发,能缓解磁盘压力,但替代不了扩容。镜像复制适合做多机房镜像同步,配置目标仓库后由jobservice异步执行,大镜像跨机房同步记得评估带宽和时间窗口。

5.3 版本锁定的价值:升级别跳版本

Harbor官方升级策略是逐版本走,跨大版本跳跃不做支持。v2.10.2这种离线安装包的好处是:安装器版本和镜像版本绑定,依赖整体可控,不存在装完发现某个组件被意外升级的情况。升级时同样下载目标版本的aarch64离线包,在现有配置上重新prepare和install,数据卷保留不动,风险相对可控。升级前一定先做完整备份,并且确认新版本离线包的架构还是aarch64,别在ARM机器上误下amd64版本。

这里补一句我的习惯:从那以后我每次在ARM机器上部署Harbor,都会先在交付文档里记录三样东西——uname -m的输出、harbor.yml里hostname字段的最终值、数据卷所在磁盘的挂载点。装完强制走一遍「docker compose ps全部Up + 推一个镜像到library」的验收流程再交接。这套动作已经帮我避掉不少低级事故,希望帮到你。

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

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

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

立即咨询