简介:本资源为 Harbor 2.5.5 版本专为 ARM64 架构服务器定制的离线安装包,面向容器化平台运维工程师、私有云部署人员及国产化信创环境实践者,解决在无外网或受限网络中快速部署企业级容器镜像仓库的核心需求。压缩包共24个文件,含6个环境配置文件(env)、5个YAML格式服务定义(如docker-compose.yml、harbor.yml),5个Conf类配置模板,以及prepare脚本、install.sh部署入口、证书(crt)与许可证(LICENSE)等关键组件,结构完整覆盖安装准备、证书生成、服务编排与权限初始化全流程。资源大小531.33MB,已适配主流ARM64服务器(如鲲鹏、飞腾平台)。目前已有206人学习下载,用户可直接解压即用,获得开箱即用的离线部署能力、标准化目录组织、预置安全策略模板及Harbor核心服务(registry、core、portal、clair等)的完整容器镜像集合(harbor.v2.5.5.tar.gz)。
1. Harbor 离线安装包 v2.5.5-arm64 到底装什么?不是“一键部署”,而是把镜像仓库的完整运行时、依赖、配置骨架和校验机制,原封不动塞进一个压缩包里——专为没有公网、不能拉镜像、CPU 是 ARM64 架构(比如树莓派 4B/5、华为鲲鹏、苹果 M 系列芯片开发机、国产信创服务器)的生产环境准备的“自包含交付单元”。
它解决的不是“要不要用 Harbor”的问题,而是“怎么在断网审计环境里让 Harbor 启得动、推得进、查得到、删得掉”的刚性交付需求。典型场景包括:某高校实验室的边缘计算教学平台(所有节点禁外网)、某制造企业内网产线质检系统(ARM64 工控机集群)、某金融信创 PoC 环境(国产化服务器 + 无互联网出口)。你不需要docker pull、不依赖helm repo add、不走 GitHub Release API——整个 Harbor 栈(core、registry、notary-server、clair、trivy、redis、postgresql)的二进制、配置模板、SQL 初始化脚本、TLS 证书生成逻辑、甚至install.sh的校验逻辑,全被打包进这个.tgz文件。它不是替代在线安装器,而是在线安装器的“离线快照编译产物”。如果你正在为 arm64 架构的离线环境部署容器镜像仓库发愁,这个包就是你跳过网络墙、跳过架构适配、跳过版本对齐的第一块确定性基石。
2. 解压即得完整 Harbor 运行目录结构:从压缩包到可执行安装器的还原
Harbor 离线安装包不是 tar 包套 tar 包的嵌套谜题,而是一个经过严格分层打包的“自解压式应用目录”。它的设计哲学是:解压后,目录即安装根,根下即运行态。我们不追求“最小体积”,而追求“最小心智负担”——解压完就能./install.sh,不查文档、不改路径、不猜依赖。
2.1 解压命令与目录结构验证(必须做)
# 创建专用安装目录(避免污染 /root 或 /opt) mkdir -p /opt/harbor-offline-v2.5.5 cd /opt/harbor-offline-v2.5.5 # 解压(注意:必须用 tar -xzf,不能用图形界面解压工具,否则可能丢权限或 symlink) tar -xzf /path/to/harbor-offline-installer-v2.5.5-arm64.tgz # 验证核心文件是否存在且可执行 ls -l install.sh harbor.yml common/config/registry/config.yml # 正常应看到: # -rwxr-xr-x 1 root root ... install.sh ← 可执行权限必须存在 # -rw-r--r-- 1 root root ... harbor.yml ← 主配置模板 # drwxr-xr-x 3 root root ... common/ ← 公共组件(nginx、core、jobservice 等二进制) # drwxr-xr-x 4 root root ... common/config/ ← 所有服务的 config 模板目录提示:
install.sh是整个离线包的入口门禁。它内部硬编码了common/目录相对路径、校验harbor.yml是否被篡改、检查docker和docker-compose版本(v2.5.5 要求 docker ≥ 20.10,compose ≥ 2.2.0),并拒绝在非 arm64 平台执行。不要试图chmod +x一个不存在的install.sh——如果解压后没看到,说明下载损坏或非官方包。
2.2 目录结构深度解析:为什么common/是心脏?
离线包解压后,目录结构固定为:
/opt/harbor-offline-v2.5.5/ ├── install.sh # 安装主控脚本(含校验、预检、compose up 封装) ├── prepare # 配置生成器(Python 脚本,读 harbor.yml 生成最终 config) ├── harbor.yml # 主配置模板(YAML,定义 hostname、https、storage、database 等) ├── LICENSE ├── README.md └── common/ # ← 全部二进制、配置模板、SQL 脚本的“只读仓库” ├── config/ # 所有服务的 config 模板(registry.yml, core.yaml, jobservice.conf...) │ ├── registry/ │ ├── core/ │ └── ... ├── docker-compose.notary.yml # Notary 服务 compose 片段(可选启用) ├── docker-compose.trivy.yml # Trivy 扫描服务 compose 片段(可选启用) ├── docker-compose.yml # 主 compose 文件(v2.5.5 使用 v2.2+ 语法) ├── nginx/ # Nginx 配置模板(含 HTTPS 重定向、proxy_pass) ├── migrate/ # 数据库迁移脚本(v2.5.5 → v2.6.0 的 SQL 补丁) └── binaries/ # ← 关键!所有 arm64 编译好的二进制 ├── registry # Docker Registry v2.8.1-arm64 ├── core # Harbor Core v2.5.5-arm64 ├── jobservice # Jobservice v2.5.5-arm64 ├── notary-server # Notary Server v0.6.1-arm64(签名服务) ├── trivy-adapter # Trivy Adapter v0.27.0-arm64(漏洞扫描桥接) └── ...common/binaries/下的每个二进制都经过file命令验证:
file common/binaries/core # 输出应为:ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), statically linked, Go BuildID=..., stripped参数说明:
statically linked表示该二进制不依赖 glibc 动态库,这是离线环境存活的关键——很多国产信创 OS(如 EulerOS、Kylin V10)的 glibc 版本老旧,动态链接会直接No such file or directory。Harbor v2.5.5 的 Go 二进制全部采用-ldflags '-s -w -buildmode=pie'编译,确保零外部依赖。
2.3install.sh的真实行为拆解:它到底执行了哪几步?
不要被./install.sh的简洁迷惑。它本质是以下 5 步原子操作的封装:
预检(Pre-check):
uname -m | grep -q "aarch64"→ 拒绝 x86_64 机器command -v docker >/dev/null 2>&1 || { echo "Docker missing"; exit 1; }docker version --format '{{.Server.Version}}' | awk -F. '$1>=20 && $2>=10 {exit 0} {exit 1}'sha256sum -c ./SHA256SUMS 2>/dev/null || { echo "Integrity check failed"; exit 1; }← 校验所有common/下文件未被篡改
配置生成(Prepare):
- 执行
./prepare --with-notary --with-trivy(若启用了对应选项) - 该命令调用 Python 脚本,将
harbor.yml中的hostname: myharbor.local、https: {certificate: ..., private_key: ...}等字段,注入到common/config/core/app.conf、common/config/registry/config.yml等 12 个模板中,生成最终./common/config/下的运行时配置
- 执行
Compose 文件组装(Compose merge):
- 若启用 Notary,则
cat common/docker-compose.yml common/docker-compose.notary.yml > docker-compose.yml - 若启用 Trivy,则追加
common/docker-compose.trivy.yml - 最终
docker-compose.yml是多文件拼接结果,非原始单文件
- 若启用 Notary,则
数据目录初始化(Data init):
mkdir -p /data/{ca_download,config,job_logs,redis,registry,secretkey,template}chown -R 10000:10000 /data/registry← 注意:Harbor v2.5.5 默认使用 UID 10000 运行 registry 容器,非 root
启动(Up):
docker-compose -f docker-compose.yml up -d- 等待
curl -f http://localhost/api/v2.0/ping返回{"code":200,"message":"OK"}(超时 120 秒)
这五步不可跳过,也不建议手动执行——install.sh内部有状态锁(/tmp/harbor-install.lock)和错误回滚逻辑(如up失败则down并清理/data中新建的子目录)。
3.harbor.yml配置避坑:90% 的离线安装失败源于这 4 个字段填错
harbor.yml是离线安装的唯一配置入口,但它不是自由文本编辑器能随便改的 YAML。v2.5.5 对字段名、缩进、值类型极其敏感。以下是最常翻车的 4 个点,按现象→原因→解决结构列出:
3.1 现象:./install.sh报错FATAL: failed to generate configuration: yaml: unmarshal errors:
原因:harbor.yml中https块缩进错误。v2.5.5 要求https必须与hostname同级,且其下port、certificate、private_key必须严格 2 空格缩进。常见错误是复制粘贴导致 Tab 混入,或用 4 空格缩进。
解决:用vim打开,:set list显示不可见字符,确认https:行前无空格,其下三行均为port:(两个空格开头),且无 Tab(显示为^I)。保存前执行yamllint harbor.yml(需提前pip install yamllint)。
3.2 现象:安装成功,但浏览器访问https://myharbor.local提示NET::ERR_CERT_INVALID,且docker login报x509: certificate signed by unknown authority
原因:https.certificate和https.private_key指向的文件路径是相对于harbor.yml所在目录的路径,而非绝对路径。很多人写成/root/certs/harbor.crt,但install.sh会尝试从./common/config/nginx/下找该路径,导致 Nginx 启动失败(日志在docker logs nginx中可见open() "/etc/nginx/ssl//root/certs/harbor.crt" failed)。
解决:将证书文件放在harbor.yml同级目录,例如:
https: port: 443 certificate: ./harbor.crt # ← 必须以 ./ 开头,表示相对路径 private_key: ./harbor.key然后cp your.crt ./harbor.crt && cp your.key ./harbor.key。
3.3 现象:docker-compose up后core容器反复重启,docker logs core显示failed to connect to postgresql: dial tcp 172.19.0.2:5432: connect: connection refused
原因:database.password字段值包含特殊字符(如@,/,+,=),未被 URL 编码。PostgreSQL 连接字符串为postgres://harbor:PASSWORD@postgresql:5432/registry?sslmode=disable,若PASSWORD是mypass@123,则@会被解析为 URL 用户名/密码分隔符,导致连接串解析错误。
解决:对密码进行 URL 编码。例如mypass@123编码为mypass%40123。可用 Python 快速编码:
from urllib.parse import quote print(quote("mypass@123")) # 输出:mypass%40123填入harbor.yml:
database: password: "mypass%40123" # ← 必须加双引号包裹3.4 现象:启用--with-trivy后,trivy-adapter容器启动失败,日志报failed to initialize database: failed to ping database: dial tcp 172.19.0.3:5432: connect: connection refused
原因:Trivy Adapter 在 v2.5.5 中强制复用 Harbor 主数据库(即postgresql容器),但harbor.yml中database配置块未被prepare脚本自动注入到 Trivy Adapter 的配置中。这是一个已知的离线包配置缺陷(非在线安装器问题)。
解决:手动补全common/config/trivy-adapter/config.yaml:
# 在 common/config/trivy-adapter/config.yaml 末尾添加: database: type: postgresql postgresql: host: postgresql port: 5432 username: "harbor" password: "mypass%40123" # ← 必须与 harbor.yml 中 database.password 一致 database: "registry" sslmode: "disable"血泪经验:这个字段缺失不会导致
install.sh报错,但会导致 Trivy 扫描功能完全不可用,且日志埋得很深(需docker logs trivy-adapter | grep -A5 "database"才能看到)。务必在install.sh执行前补上。
4. 离线环境下的证书与信任链:如何让docker login和kubectl都认你的 Harbor
离线环境最大的玄学不是安装失败,而是安装成功后“推不上去、拉不下来”。根源几乎全是 TLS 证书信任问题。Harbor v2.5.5 的 HTTPS 配置只是第一步,客户端信任才是最后一公里。
4.1 为 Docker Daemon 添加私有 CA 信任(所有推送/拉取节点必做)
Docker 默认只信任公共 CA(Let's Encrypt、DigiCert 等),对自签名或内网 CA 颁发的证书直接拒绝。解决方案是将你的 Harbor 证书(harbor.crt)注入 Docker 的信任链:
# 步骤 1:创建 certs.d 目录(路径必须精确匹配 hostname) mkdir -p /etc/docker/certs.d/myharbor.local:443 # 步骤 2:复制证书(注意:必须是 .crt 后缀,且内容为 PEM 格式) cp /opt/harbor-offline-v2.5.5/harbor.crt /etc/docker/certs.d/myharbor.local:443/ca.crt # 步骤 3:重启 Docker(关键!否则不生效) systemctl restart docker # 步骤 4:验证(返回 should be OK) curl -k https://myharbor.local/api/v2.0/ping # -k 绕过 curl 自身校验 docker login myharbor.local # 应提示输入用户名密码,不再报 x509 错误注意:
/etc/docker/certs.d/<your-hostname>:<port>/ca.crt是 Docker 的硬编码路径。<port>必须与harbor.yml中https.port一致(默认 443)。如果填myharbor.local但实际用https://myharbor.local:8443访问,则路径必须是/etc/docker/certs.d/myharbor.local:8443/ca.crt。
4.2 为 Kubernetes 集群添加信任(若用 Helm 或 Kubectl 推送镜像)
Kubernetes 的 kubelet 和 containerd 不读取 Docker 的 certs.d,需单独配置:
方案 A:Containerd(推荐,v1.4+ 默认)
# 编辑 containerd 配置 vi /etc/containerd/config.toml # 在 [plugins."io.containerd.grpc.v1.cri".registry.configs] 下添加: [plugins."io.containerd.grpc.v1.cri".registry.configs."myharbor.local:443".tls] ca_file = "/opt/harbor-offline-v2.5.5/harbor.crt"然后systemctl restart containerd。
方案 B:Kubelet(传统方式)
# 将证书注入 kubelet 启动参数(修改 /var/lib/kubelet/kubeadm-flags.env) --container-runtime-endpoint=unix:///run/containerd/containerd.sock \ --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 \ # ← 无需改此行,重点是下一步:更可靠的是:将harbor.crt加入系统 CA 信任库(影响所有系统级进程):
cp /opt/harbor-offline-v2.5.5/harbor.crt /usr/local/share/ca-certificates/harbor.crt update-ca-certificates # Ubuntu/Debian # 或 trust extract-compat # CentOS/RHEL/Fedora4.3 浏览器信任:让 Chrome/Firefox 不再弹红页
开发者常忽略这点:即使docker login成功,浏览器访问https://myharbor.local仍会显示“不安全”。这不是 Harbor 问题,而是浏览器未信任你的 CA。
正确做法(非导入单个证书):
- 如果你用 OpenSSL 自建 CA,将CA 根证书(不是
harbor.crt,而是签发harbor.crt的那个ca.crt)导入操作系统信任库(同 4.2 方案 B 的update-ca-certificates),然后重启浏览器。 - 如果你用
mkcert工具生成证书,它会自动将根证书注入系统,但需手动在浏览器中访问https://localhost:8443(mkcert 的本地 CA 端口)并点击“Install Certificate”。
后悔药:若已误将
harbor.crt(终端证书)导入浏览器,需在浏览器设置中找到该证书并删除,否则会冲突。Chrome 地址栏锁图标 → “Connection is not secure” → “Certificate is not valid” → 查看证书路径,删除最顶层的“Your Root CA”。
5. 验证与故障定位:5 个命令锁定 95% 的离线运行问题
安装完成不等于运行稳定。Harbor v2.5.5-arm64 在离线环境的典型问题是“静默失败”——容器在跑,但某个服务没响应。以下是我在某跨平台系统交付中沉淀的 5 个黄金命令,按执行顺序排列,覆盖从网络连通性到业务逻辑的全链路:
5.1 第一关:宿主机网络与端口可达性(排除防火墙/SELinux)
# 检查 Harbor 宿主机是否监听 443/80 端口(Nginx) ss -tlnp | grep ':443\|:80' # 正常输出应有:LISTEN 0 128 *:443 *:* users:(("nginx",pid=1234,fd=6)) # 检查容器网络是否就绪(bridge 网络名通常是 harbor_harbor) docker network ls | grep harbor # 应看到:harbor_harbor bridge local # 检查容器 IP 分配(关键!离线环境常因 DNS 配置错误导致容器间无法解析) docker inspect harbor-core | grep '"IPAddress"' -A1 # 应看到类似:"IPAddress": "172.19.0.4"排查逻辑:如果
ss看不到监听,说明 Nginx 没起来(查docker logs nginx);如果docker network ls没输出,说明docker-compose up未成功(查docker-compose ps);如果IPAddress为空,说明容器启动失败(查docker ps -a看 STATUS)。
5.2 第二关:核心服务健康检查(API 层)
# 用 curl 直接测 Harbor Core API(绕过 Nginx 和证书) curl -k -u admin:Harbor12345 https://localhost/api/v2.0/systeminfo # 应返回 JSON:{"with_notary":false,"with_trivy":true,"registry_url":"myharbor.local"} # 测 Registry API(验证镜像存储通路) curl -k -u admin:Harbor12345 https://localhost/service/token?service=harbor-registry&scope=repository:test/test:pull,push # 应返回 {"token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}参数说明:
-k绕过证书校验,-u传入管理员凭据。service/token是 Docker Registry V2 协议的认证端点,返回 token 证明 registry 服务已注册且可鉴权。
5.3 第三关:数据库连接验证(PostgreSQL)
# 进入 PostgreSQL 容器执行 SQL 查询 docker exec -it harbor-db psql -U postgres -d registry -c "SELECT now();" # 应返回当前时间戳 # 检查 Harbor 所需表是否存在(关键表:project, repository, artifact) docker exec -it harbor-db psql -U postgres -d registry -c "\dt" # 应看到:public | project | table | postgres # public | repository | table | postgres # public | artifact | table | postgres避坑:
harbor-db容器名是固定的(由docker-compose.yml定义),不是postgresql。如果docker exec报错“no such container”,说明db服务根本没启动(查docker-compose ps db)。
5.4 第四关:Redis 状态(Jobservice 和 Clair 依赖)
# 检查 Redis 是否响应 PING docker exec -it harbor-redis redis-cli PING # 应返回:PONG # 检查 Jobservice 是否在 Redis 中注册了队列(关键!否则 UI 上传镜像会卡住) docker exec -it harbor-redis redis-cli LRANGE harbor_job_queue 0 10 # 初始为空是正常的,但执行一次镜像推送后,此处应有 job ID5.5 第五关:Trivy 扫描功能实测(若启用)
# 推送一个测试镜像(先确保本地有 busybox) docker pull busybox:1.35 docker tag busybox:1.35 myharbor.local/library/busybox:1.35 docker push myharbor.local/library/busybox:1.35 # 等待 30 秒,检查扫描状态(通过 Harbor API) curl -k -u admin:Harbor12345 "https://myharbor.local/api/v2.0/projects/library/repositories/busybox/artifacts/1.35?with_scan_overview=true" | jq '.scan_overview' # 应返回:{"application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0":{"report_id":"xxx","scan_status":"Success","severity":"None"}}技巧:
jq是必备工具(apt install jq),用于解析 JSON。scan_status为Success且severity不为Unknown,才代表 Trivy 扫描链路打通。如果一直是Pending,查docker logs trivy-adapter看是否报数据库连接失败(回到 3.4 节)。
6. 生产就绪加固:3 个必须做的离线环境专项优化
离线环境不是“装上就行”,而是要扛住长期运行、审计合规、故障自愈。基于某图像处理 Demo 的 6 个月 ARM64 离线集群运维经验,我总结出三个不写在官方文档里、但能让你少熬三次夜的硬核技巧:
6.1 日志轮转:防止/var/lib/docker被core和jobservice日志撑爆
Harbor v2.5.5 的core和jobservice默认无限追加日志到容器 stdout,而 Docker 的json-file驱动不自动轮转。离线环境往往磁盘小(如树莓派 SD 卡),3 天就满。
解决方案:全局配置 Docker 日志驱动
编辑/etc/docker/daemon.json:
{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }然后systemctl restart docker。此配置对所有容器生效,包括 Harbor 启动的core、registry等。
验证:
docker inspect harbor-core | grep LogConfig应看到"MaxSize": "10m", "MaxFile": "3"。ls -lh /var/lib/docker/containers/*/logs/*应只有最多 3 个*-json.log文件,每个 ≤10MB。
6.2 数据持久化加固:将/data挂载到独立磁盘分区
Harbor 默认将/data(镜像、数据库、日志)放在宿主机根分区。一旦/data/registry存储大量镜像,根分区爆满会导致系统瘫痪。
最佳实践:用 LVM 或独立 SSD 挂载
# 假设新磁盘为 /dev/sdb,创建 LVM 逻辑卷 pvcreate /dev/sdb vgcreate harbor-vg /dev/sdb lvcreate -L 100G -n>services: core: # ... 其他配置保持不变 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/api/v2.0/ping"] interval: 30s timeout: 10s retries: 3 start_period: 40s restart: on-failure:5然后docker-compose up -d重载。这样当core的/api/v2.0/ping返回非 200,Docker 会在 3 次检测失败后自动重启容器。
我的习惯:每次
install.sh执行完,我都会cp docker-compose.yml docker-compose.yml.bak,然后立即编辑加入健康检查。这行配置让我在某次内存泄漏事件中,避免了 4 小时的手动干预。希望帮到你。
本文还有配套的精品资源,点击获取