首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
arm64内网环境离线安装Harbor 2.13.1完整避坑指南
📅 2026/10/8 14:42:59
✍️ 爱科研究院
👁 阅读 3,247
简介面向ARM架构服务器的Harbor 2.13.1离线安装包适合在内网隔离或无法访问外网的容器化环境使用帮助运维工程师与平台交付人员在国产化ARM服务器上快速搭建企业级镜像仓库。压缩包共6个文件包含安装脚本、环境预检工具、配置模板、授权文件以及核心的镜像离线压缩包总大小约513.28MB整体采用tgz格式封装。以离线包方式提供官方编译好的arm64组件可免去逐层拉取镜像与依赖的麻烦安装流程覆盖配置渲染、环境检查、镜像导入和服务启动全链路。已有414人学习下载资源内嵌的模板和脚本支持自定义端口、存储路径、数据库及认证方式适合私有云交付、容灾恢复和长期离线运维场景。对于需要快速复制Harbor环境的ARM平台团队这份打包完整的离线安装方案能显著降低部署门槛提升交付效率。1. arm环境装Harbor 2.13.1先把这个离线包看懂再动手arm环境里装Harbor 2.13.1最省事的路径就是拿到harbor-offline-installer-v2.13.1-arm64.tgz这个离线包。它把 Harbor 运行需要的全部镜像打成一个 tgz解压后改完harbor.yml跑一次install.sh就能得到一个能推送、能拉取的私有镜像仓库。这个方案解决的是内网服务器和信创机器上在线安装拉不动包的问题不需要外网版本锁定为 2.13.1arm64 架构下的镜像格式也提前筛好了。适合三类人要给 arm 服务器装私有仓库的运维想把存量 Harbor 升级到 2.13.1 的维护者以及在内网环境从零搭镜像源的开发。离线包不是灵丹妙药前面细节不对照样翻车下面把动作和坑一次讲清楚。2. arm架构下为什么只能选离线包在线安装的五个拦路虎很多人在 arm 服务器上第一次装 Harbor 会下意识走在线安装先去 Docker Hub 拉镜像再手动写 docker-compose 文件。这套流程在 x86 公网机器上很顺但到了 arm64 内网机器上会连续踩到五道坎机器连不上外网、Docker Hub 匿名拉取被限流、arm64 镜像的 tag 经常不全、docker-compose 与 Docker Engine 版本不匹配、老版本升级时数据库迁移中途断掉。离线包把这五道坎一次全部绕开代价是你要接受它给你锁死的版本和镜像集合。这也是从业者选离线包的根本原因它把「能不能成功装上」从网络问题变成了本地问题。2.1 在线安装的真正瓶颈拉镜像不稳与 arm64 镜像缺失常见做法是先下载 Docker Engine再安装 docker-compose最后从 Docker Hub 拉取 harbor 相关镜像。但 Harbor 2.13.1 的编排里至少有十个镜像包括 harbor-core、harbor-registry、harbor-jobservice、redis、postgresql这些镜像在 Docker Hub 上虽然有 arm64 变体但匿名用户每小时拉取次数是有限的镜像一多就容易触发限流。更麻烦的是有些辅助镜像的 arm64 tag 更新滞后你按照文档写的 tag 去拉Docker Hub 返回 manifest unknown此时就只能自己找替代 tag版本组合就乱了。离线包harbor-offline-installer-v2.13.1-arm64.tgz里带的是harbor.v2.13.1.tar.gz这是打包阶段就已经下载好的完整镜像集。install.sh会执行docker load把它们一次性导进本地 Docker不需要访问任何外部仓库。镜像架构也已经验证过不会再出现「amd64 镜像在 arm 机器上能 load 不能 run」的尴尬。我一般会在解压后先算一次 sha256sum和下载页面给的 checksum 对一遍防止包在传输过程里损坏。这个动作三十秒但能省掉后面镜像加载中断的半天折腾。另一个值得说的点是 qemu 模拟 arm64。有的机器是 x86 实体机想用 qemu 模拟 arm64 来跑这个离线包常见命令是docker run --platform linux/arm64。但 Harbor 里的 postgresql、redis 对 CPU 指令集敏感qemu 翻译层的稳定性撑不住长时间读写容器启动阶段就可能抛异常。这个方案只适合验证镜像内容不适合做生产仓库后文避坑章节还会专门展开。2.2 离线包的结构与版本语义tgz里到底装了什么解压harbor-offline-installer-v2.13.1-arm64.tgz之后目录里不是只有一个安装脚本而是一套完整的部署材料。核心文件有这么几个harbor.yml是安装时的总配置hostname、端口、管理员密码都写在这里prepare负责读取配置并生成 docker-compose.ymlinstall.sh是真正的安装入口common.sh是被 install.sh 调用的公共函数库harbor.v2.13.1.tar.gz是所有运行镜像的合集。文件清单里没有额外的数据库初始化脚本因为 postgresql 和 redis 都作为容器跑起来了数据落盘位置由data_volume指定。arm64后缀决定这个包只能用在 arm64 处理器上和 x86_64 的 tgz 不通用。有人把 x86 的离线包拷到 arm 机器上执行docker load 能成功因为镜像文件本身只是归档但运行 registry 容器时会直接识别不了可执行格式。反过来arm64 包放到 x86 机器上也是一样的结果。装之前用uname -m确认机器架构输出aarch64才和包匹配。2.13.1 这个版本号里的语义也要看清它是 2.13 主版本线的第一个补丁版本主要修复的是安全漏洞和镜像同步的一些边界问题。如果你是从 2.8 或 2.10 这种老版本升级上来install.sh 会自动触发数据库迁移路径是 postgresql 容器启动后的初始化迁移。升级前务必备份整个data_volume迁移脚本一旦中途失败回滚只能靠备份。我遇到过同事直接拿着新包去覆盖旧目录结果数据库版本不兼容整个 Harbor 起不来最后恢复备份重来。3. 用离线包在arm64上装Harbor解压到install.sh的完整动作安装流程本身不长但每一步都有必须盯住的参数。下面的操作以 root 用户执行机器是 arm64 架构、系统为 Ubuntu 22.04 或麒麟 V10 都适用。先创建目录、解压、备份配置文件再改关键参数最后跑安装脚本。3.1 解压离线包并修改harbor.ymlhostname和端口是命门mkdir -p /opt/harbor tar -xzvf harbor-offline-installer-v2.13.1-arm64.tgz -C /opt/harbor/ cd /opt/harbor cp harbor.yml harbor.yml.v2.13.1.bak vi harbor.ymltar 解压时建议加-C指定目标目录避免文件散落在当前目录。解压后立刻备份harbor.yml这个动作看起来多余但后面调证书、改端口时随时能和默认配置做 diff。备份文件带上版本号后缀比harbor.yml.bak更容易辨别。harbor.yml里有这么几个必改项。hostname是客户端用来访问仓库的地址不能写localhost否则其他机器 push 镜像时解析不到生产环境一般写内网 IP比如192.168.209.133或者写一个内网 DNS 域名。http.port默认是 80如果机器上已经有 nginx 占了 80改成 8080后面 docker push 时地址要写成192.168.209.133:8080。harbor_admin_password默认是Harbor12345上线前必须改而且长度大于等于 8 位。如果暂时不配置 HTTPS就把https这一段整个注释掉否则prepare阶段会去找证书文件找不到直接终止。# 关键配置段示例 hostname: 192.168.209.133 http: port: 8080 harbor_admin_password: ChangeMe_2025 data_volume: /data/harbordata_volume我习惯单独设到一块大分区不要用默认的/opt/harbor同目录。镜像仓库的数据增长很快根分区一旦写满registry 容器会反复重启后面避坑章节会单独说这个现象。其他配置项比如log.level默认 info日常够用要排查问题可以临时改成 debug验证完再改回来。3.2 执行install.sh离线加载镜像与启动编排的原理# 确认 docker compose 插件可用 docker compose version # 执行离线安装 ./install.shinstall.sh 内部做的事可以拆成三步。第一步用docker load -i harbor.v2.13.1.tar.gz把镜像归档灌进本地 Docker这一步会输出一串Loaded image: ...耗时看磁盘速度一般三到五分钟。第二步执行prepare它读取harbor.yml生成最终的docker-compose.yml并且把 nginx 配置、证书目录都按配置铺好。第三步是docker compose up -d启动全部容器。执行 install.sh 之前必须先验证docker compose命令可用。Harbor 2.13 要求 Docker Compose v2 插件传统的docker-compose独立二进制在这里会被脚本拒绝。检查方式就是docker compose version如果没有输出用 apt 安装docker-compose-plugin或者按 Docker 官方文档把插件放到~/.docker/cli-plugins/目录下。这里踩坑率很高我在避坑章节列了详细的现象和解决方式。install.sh 也支持加参数来启用附加组件。--with-trivy会启动镜像漏洞扫描--with-notary启动镜像签名--with-chartmuseum启动 Helm Chart 仓库。默认安装只带核心功能日常够用内网环境如果还要做供应链安全可以加上--with-trivy。注意这些参数要写进 install.sh 执行命令里它和harbor.yml里的配置是两层逻辑prepare 阶段会根据附加参数再补一份组件配置。# 启用扫描组件的安装方式 ./install.sh --with-trivy装完以后用docker compose ps看状态所有容器处于running状态才算成功。第一次启动时 postgresql 会做数据初始化nginx 会监听配置的端口这个过程大约几十秒。页面访问http://192.168.209.133:8080能出登录界面就算装通了。如果机器上有防火墙记得放行对应端口否则自己 curl 没问题别的机器访问会超时。4. 避坑arm64离线包安装Harbor的4个典型坑每个都踩过离线包把大部分网络问题挡在门外但本地的环境问题一个都不会少。下面四条是按踩坑频率排的每一条都按现象、原因、解决三个层次说清楚。4.1 安装了docker-compose却提示command not found现象install.sh 跑到底部输出提示docker-compose command not found或者直接报exec: docker-compose: executable file not found in $PATH。原因Harbor 2.13 的安装脚本调用的是 Docker Compose v2 插件命令docker compose不是传统的独立二进制docker-compose。很多人习惯装完 docker 后单独 pip 装一个 docker-compose这在老版本 Harbor 里没问题但在 2.13 里脚本检测不到 compose 插件就终止。更隐蔽的情况是docker-compose和docker compose都存在但版本不一致脚本优先找 v2 插件。解决安装 Docker Compose 插件然后直接验证docker compose version。sudo apt-get update sudo apt-get install -y docker-compose-plugin docker compose version如果系统是离线环境没有 apt 源常见做法是把 compose 插件二进制放到/usr/lib/docker/cli-plugins/docker-compose再给执行权限然后重新跑 install.sh。这个文件在安装包体系里不属于 Harbor 离线包需单独从 Docker 官方下载对应架构的版本。arm64 机器记得下aarch64二进制下错架构执行时会直接报错。4.2 推送失败报错get https://192.168.209.133/v2/: dial tcp 连接拒接现象docker login 成功了但 docker push 时报类似get https://192.168.209.133/v2/: dial tcp 192.168.209.133:443: connect: connection refused或者直接提示http: server gave HTTP response to HTTPS client。原因Docker 客户端默认用 HTTPS 访问仓库地址但 Harbor 的harbor.yml里只开了 HTTP没有任何证书。login 成功是因为客户端做了兼容尝试但 push 时协议协商失败连接被拒。另一种常见情况是harbor.yml里配了自签 HTTPS 证书但客户端不信任这个证书握手直接失败。解决把 Harbor 地址加进 Docker daemon 的insecure-registries列表然后重启 Docker。sudo vi /etc/docker/daemon.json # 内容示例 { insecure-registries: [192.168.209.133:8080] } sudo systemctl restart docker如果走的是自签证书模式除了配 insecure-registries也可以把 ca.crt 放到/etc/docker/certs.d/harbor地址/ca.crt效果更精准不影响该地址以外的仓库。注意重启 Docker 会把正在运行的 Harbor 容器也重启一遍所以这个动作要放在推送前做不要在仓库正在同步数据的时候操作。4.3 在x86上用qemu模拟arm64来装离线包registry容器反复重启现象拿到 arm64 包后在 x86 机器上启用 qemu 模拟 arm64docker load 成功但启动 Harbor 后harbor-registry容器反复重启日志里出现执行格式错误或者类似bad linux arm64 image magic的启动异常。postgresql 容器的表现更隐蔽状态一直是 unhealthy。原因qemu 用户态模拟能骗过 Docker 的镜像加载阶段但 Harbor 运行时不只有容器启动还有容器内的 CPU 指令执行、信号处理、网络握手。postgresql、redis 这类对指令敏感的服务在翻译层的稳定性很差某些 arm64 指令没有对应翻译实现进程直接被杀掉。这个环境只适合验证镜像 tar 包内容不适合跑真实仓库负载。解决不要在 x86 上模拟 arm64 跑 Harbor。拿一台真实 arm64 实体机或云主机直接在原生架构上装这个离线包。如果手上只有 x86 机器就下载对应 x86_64 的harbor-offline-installer-v2.13.1-amd64.tgz而不是强行用模拟层。这条经验值钱的地方在于离线包本身没错错的是平台的架构匹配检查uname -m只要两秒钟看到x86_64就直接放弃 arm64 包别浪费时间折腾模拟。4.4 镜像存多了harbor-registry容器反复重启现象刚装完一切正常推了几百个镜像后harbor-registry容器每隔几分钟重启一次docker logs里能看到no space left on device但df -h显示根分区并没有 100% 满。原因Harbor 的数据目录默认和安装目录同分区harbor.yml里没有改data_volume时registry 的镜像层、数据库文件都写在根分区。根分区通常还跑着系统日志、Docker 自身的 overlay2 目录空间被占满后 registry 写不进去。df -h看的是整个文件系统如果你看的是别的挂载点容易漏掉根分区已满的事实。解决先把根分区里可清理的东西清掉让 registry 恢复可用。然后停掉 Harbor修改harbor.yml的data_volume指向一块独立大分区重新执行prepare和docker compose up -d。cd /opt/harbor docker compose down # 把旧数据迁移到新分区 mv /data/harbor /data1/harbor_data # 修改 harbor.yml 中的 data_volume 为 /data1/harbor_data ./prepare docker compose up -d注意data_volume改动后必须重新跑prepare它会重新生成容器挂载配置只改 yml 不重新 prepare容器还是按旧配置启动。迁移前先确认新分区的权限Harbor 容器内运行用户是 10000目录属主不对会导致启动时权限拒绝。这个坑在离线部署里最常见因为离线环境往往没有额外的自动化运维工具盯着磁盘。5. 推送镜像到Harbor登录、打标签和一条龙验证安装完成不是终点能顺利推送和拉取镜像才算闭环。这一章把从客户端登录到用 API 验证的完整路径走一遍这也是每天使用 Harbor 最高频的一组操作。5.1 docker login与push失败排查证书和insecure-registries怎么配docker login 192.168.209.133:8080 -u admin按提示输入密码后返回Login Succeeded就说明认证通了。登录成功后拉一个测试镜像打上 Harbor 地址的标签然后推送。docker pull nginx:alpine docker tag nginx:alpine 192.168.209.133:8080/library/nginx:alpine docker push 192.168.209.133:8080/library/nginx:alpinelibrary是 Harbor 里默认的公开项目新建的镜像默认都推到这里。如果你的环境里建了别的项目名把library换成项目名即可。推送成功后输出里会有一行latest: digest: sha256:...这行 digest 是镜像在仓库里的唯一指纹记录它可以用来回滚版本。如果 push 阶段卡在Waiting或者直接报连接错误优先检查三样东西第一harbor.yml里开的到底是 http 还是 https客户端用错协议时最容易出现连接被拒第二/etc/docker/daemon.json里insecure-registries是否包含完整的地址和端口少一个端口号都不行第三客户端机器能不能 telnet 通 Harbor 的端口防火墙挡着的话Harbor 日志里完全看不到请求记录。5.2 用Harbor API验证项目、仓库和镜像列表页面 UI 能看到数据但脚本化运维需要 API。Harbor 2.13 提供 v2.0 API地址以/api/v2.0开头。下面三个接口分别查项目列表、仓库列表和镜像版本列表。# 查看所有项目 curl -k -u admin:密码 \ https://192.168.209.133:8443/api/v2.0/projects?page1page_size10 # 查看 library 项目下的所有仓库 curl -k -u admin:密码 \ https://192.168.209.133:8443/api/v2.0/projects/library/repositories # 查看 nginx 仓库下的所有镜像版本 curl -k -u admin:密码 \ https://192.168.209.133:8443/api/v2.0/projects/library/repositories/nginx/artifacts-k参数在自签证书环境下必须加否则 curl 会因为证书校验失败直接返回空。返回的 JSON 里项目接口能看到project_id和repo_count仓库接口能看到name和artifact_count镜像接口能看到digest和push_time。这些字段在做容量统计和镜像清理时非常有用。如果 API 请求返回 401先确认账号密码是否是 URL 里-u传入的格式正确密码里如果带特殊字符要做 URL 编码。返回 404 时检查地址里是/api/v2.0而不是/apiHarbor 2.x 的旧版 API 路径是/api返回的内容结构也不一样。在日常巡检脚本里我会定期调仓库列表接口统计镜像数量再配合磁盘监控能提前发现数据增长过快的项目。6. 让离线包发挥余热一条脚本把本地镜像批量搬进Harbor装好 Harbor 之后最常碰到的需求是把本机已有的镜像批量迁移进去。手动docker tag加docker push在镜像少时没问题镜像一多就容易把项目名敲错。我习惯写一个循环脚本自动完成打标签和推送。#!/bin/bash HARBOR_ADDR192.168.209.133:8080 PROJECTlibrary for img in $(docker images --format {{.Repository}}:{{.Tag}} | grep -v none); do # 跳过已经带 Harbor 地址的本地镜像避免重复打标签 if [[ $img $HARBOR_ADDR/* ]]; then continue fi # 原始镜像名里可能带域名或路径直接用原名拼接会破坏项目路径 short_name$(echo $img | cut -d/ -f2-) docker tag $img $HARBOR_ADDR/$PROJECT/$short_name echo pushing $img - $HARBOR_ADDR/$PROJECT/$short_name docker push $HARBOR_ADDR/$PROJECT/$short_name done脚本里最关键的是short_name这一行。本地镜像如果叫registry.local:5000/app/web:v1直接拼上去会变成192.168.209.133:8080/library/registry.local:5000/app/web:v1冒号把 tag 切错push 必定失败。用cut -d/ -f2-去掉第一段地址后得到的名字才是干净的应用路径。批量推送时如果网络抖动出现失败脚本不会自动重试我一般会在循环里加一个简单的重试计数器同一个镜像失败三次就跳过并记录到日志文件。推送结束后用docker images | grep 192.168.209.133查看哪些镜像已经带上了 Harbor 地址对照日志确认有没有遗漏。这套做法解决的不只是搬运问题也让离线包的价值在版本升级后继续延续新包导入后老镜像可以快速回流到新仓库不需要手工挨个敲命令。我自己的习惯是升级前先跑一遍脚本做全量备份推送升级后跑一遍拉取校验两次输出对比就能确认数据完整性。希望帮到你。本文还有配套的精品资源点击获取
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/8 14:42:59
Windows 64位下OpenAL部署与避坑:从DLL错位到3D音频接入
2026/10/8 14:42:59
戴尔R7515部署Debian12.5与Mellanox网卡全栈适配指南
2026/10/8 14:42:58
Windows照片查看器恢复教程:解决照片应用卡顿,秒开图片
2026/10/8 15:38:17
联想昭阳N4620驱动包安装指南:兆芯KX-6640MA平台Win10驱动顺序与避坑
2026/10/8 15:38:17
HyperFrames高帧率重建:光流估计与运动补偿插帧实战解析
2026/10/8 15:38:17
PE150X250颚式破碎机设计全流程:参数计算、三维建模与试机要点
2026/10/8 15:38:17
Open-AutoGLM+ADB键盘:Android设备自动化实战与踩坑指南
2026/10/8 15:38:17
LangChain大模型接入全攻略:云端API、Ollama与vLLM实战
2026/10/8 15:33:17
微软语音合成SDK实现女声改男声的完整指南
2026/10/8 0:04:11
Agent Skills 完全指南:原理、写法、安装与实战避坑
2026/10/8 0:04:11
Agent Skills 实战:从 Genkit 定义到 GKE 部署与排查
2026/10/8 0:04:11
Agent Skills 实战:从设计到调试的完整指南
2026/10/8 5:02:14
Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化
2026/10/7 9:55:49
多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系
2026/10/7 14:02:03
hindsight:面向LLM应用的事后可观测性工程实践
2026/10/8 4:30:43
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/8 2:46:15
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/8 4:32:33
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)