ARM64 离线部署 Harbor 镜像仓库:离线包安装全流程指南
发布时间:2026/10/14 8:30:23 锦皓数字建站

简介Harbor 2.7.0 ARM64离线安装包专为网络隔离或弱网环境下的企业级容器镜像仓库部署而设计面向运维工程师、平台架构师及需要搭建私有仓库的技术团队。Harbor作为成熟的开源镜像管理项目提供RBAC权限控制、操作审计、跨实例复制及Docker Content Trust签名校验等能力该版本可直接在ARM64架构服务器上落地生产级镜像存储与分发。资源包共包含6个文件以shell安装脚本、Harbor离线镜像数据包、配置模板和许可证文件为主整体约704.87MB其中prepare与install脚本可引导完成环境预检及部署流程harbor.yml.tmpl便于按需调整认证、存储和网络参数。目前已有150人学习下载。通过这份离线安装包用户无需外网拉取镜像即可在可信环境中快速完成Harbor安装并借助内置的镜像复制和同步机制支撑多地域容灾场景同时为后续的权限策略配置和日志审计打下基础适合内网生产环境及等保合规要求较高的企业使用。1. Harbor 离线安装包ARM64 环境下最稳妥的上手方式拿到harbor-offline-installer-v2.7.0-arm64.tar.gz这个文件时第一反应别是又一个安装包而是要想清楚它到底解决了什么问题。Harbor 作为企业级镜像仓库在线安装依赖网络拉取大量容器镜像而离线安装包把 Harbor 服务本身、依赖组件和初始化镜像全部打包在一个压缩文件里解压后即可在隔离网络环境完成部署。v2.7.0 这个版本在功能上已经相当成熟支持 OIDC 认证、镜像签名、漏洞扫描等企业级特性而 arm64 架构则是为信创环境、ARM 服务器或边缘机房准备的。这个安装包适合谁内网部署者、离线环境运维、以及需要在 ARM 架构上搭建镜像仓库的团队。最容易被忽略的一点是这个包不是解压就能用的安装脚本会检测磁盘、Docker 版本和端口占用任何一个环节不满足都会中途退出。我习惯把这类离线安装包当作黑匣子来看待——它能用但你得先知道它的边界在哪里。Harbor 离线包的解压后体积在 1GB 以上安装时会自动加载十几个容器镜像到 Docker 中整个过程需要 root 权限并且对内核版本有隐性要求。如果你手头的机器是 CentOS 7.9 或 Ubuntu 20.04 以下的 ARM 设备需要先确认内核版本是否在 3.10 以上否则 Docker 可能无法正常运行。后面我会把整个流程拆开从环境准备、配置修改、安装执行到常见问题逐步说清楚。2. 为什么选离线包和 arm64先搞懂这层兼容关系2.1 离线安装包的内部结构不只是 Harbor 本身离线安装包和在线安装最大的区别在于自包含程度。在线安装时安装脚本会从 Docker Hub 拉取 Harbor 依赖的 PostgreSQL、Redis、Nginx、Trivy 等多个镜像而离线包把所有这些镜像都用 Docker save 的方式导出成了 tar 文件安装时直接 docker load 进本地镜像库。harbor-offline-installer-v2.7.0-arm64.tar.gz解压后主要包含三部分harbor.yml.tmpl 配置文件模板、install.sh 安装脚本、以及 harbor.v2.7.0.tar.gz 镜像压缩包。# 解压离线安装包 tar -zxvf harbor-offline-installer-v2.7.0-arm64.tar.gz # 解压后目录结构 cd harbor ls -lh # 关键文件说明 # harbor.yml.tmpl —— Harbor 服务的完整配置模板安装前必须基于它生成 harbor.yml # install.sh —— 一键安装脚本支持 --with-trivy 等参数 # harbor.v2.7.0.tar.gz —— 预导出的所有依赖容器镜像约 1GB 以上 # common.sh —— 安装脚本依赖的公共函数库通常无需改动这里有个常见的误解很多人以为解压后直接运行 install.sh 就行结果脚本报错说找不到配置。实际上 install.sh 会先检查同目录下是否存在 harbor.yml如果不存在就提示你从 harbor.yml.tmpl 复制一份并修改。所以标准操作是先复制模板再改配置最后执行安装。参数说明--with-trivy表示启用漏洞扫描组件--with-chartmuseum表示启用 Helm Chart 仓库支持这两个都是可选参数按需添加即可。我一般会建议至少加上 --with-trivy因为镜像漏洞扫描是 Harbor 的核心卖点离线环境下尤其需要它来弥补外部扫描服务的缺失。2.2 ARM64 架构下的 Docker 兼容性检查在 ARM64 机器上装 Harbor第一个要确认的是 Docker 本身是否正常工作。ARM64 平台的 Docker 镜像和 x86_64 平台不通用这一点在离线包里的镜像 tar 文件上体现得很明显。当你 docker load 一个 arm64 镜像到 x86 机器上时虽然能成功加载但运行时就会报exec format error因为 CPU 指令集不匹配。反过来也一样——harbor-offline-installer-v2.7.0-arm64.tar.gz这个包只能在 arm64 架构的机器上使用。# 确认当前系统架构必须是 aarch64 或 arm64 uname -m # 输出示例aarch64 # 确认 Docker 版本和架构信息 docker version --format {{.Server.Arch}} # 输出示例aarch64 # 检查 Docker 存储驱动推荐 overlay2 docker info | grep Storage Driver # 输出示例Storage Driver: overlay2架构匹配是第一道门槛很多翻车事故的根源就在于前置检查没做。Docker 版本方面Harbor 2.7.0 要求 Docker 17.06.0 和 Docker Compose 2.x但我在实际部署中发现 Docker 20.10.x 是最稳定的选择过老的版本在容器网络初始化时容易出现偶发失败。存储驱动如果显示的是 devicemapper建议先切换到 overlay2否则镜像层多的时候 IO 性能会明显下降。检测到架构不符合时不要试着把包内的镜像重新打 tag 绕过去那是徒劳——二进制指令集的问题无法通过重命名解决。2.3 为什么 2.7.0 这个版本在 ARM 生态里值得用Harbor 版本迭代到了 2.10但 2.7.0 在 ARM64 上的表现反而更成熟。原因在于 Harbor 从 2.5 版本开始才正式提供 arm64 官方镜像2.5 到 2.7 的过渡版本在 ARM 平台上的 bug 修复最为密集到了 2.7.0 已经相当稳定。我对比过 2.6.2 和 2.7.0 在同样的 ARM 机器上的资源占用2.7.0 的 PostgreSQL 容器内存消耗大约少了 15%这得益于官方对 ARM 内存优化提交的合并。对于生产环境来说稳定性和资源占用往往比新功能更重要。选择 2.7.0 还有一个现实原因它兼容的操作系统范围很广。无论是 Ubuntu 18.04/20.04 还是 CentOS 7.6 的 ARM 版本都能正常安装。而更新的 Harbor 版本比如 2.9对内核和 glibc 的要求更高在旧系统上容易出现container init failed的问题。如果你的业务场景是信创或国产化替代操作系统往往不是最新版本这时 2.7.0 的兼容性优势就体现出来了。当然如果有条件用更新的 ARM 服务器和较新的 OS那可以考虑更高版本但在硬件条件受限的情况下2.7.0 是投入产出比最高的选择。3. 从解压到跑通ARM64 离线部署 Harbor 的完整流程3.1 磁盘规划与内核参数调整Harbor 安装对磁盘的要求集中在两个维度——容量和 inode。镜像仓库的存储目录默认在/data这个路径在 harbor.yml 里通过data_volume参数指定。如果/data所在的磁盘空间不足会在垃圾回收或镜像推送时出现no space left on device。我遇到过一个案例某开发者把 Harbor 装到了根分区只有 30GB 的 ARM 小主机上镜像推了几十个后整个磁盘满了连 Harbor 的数据库容器都起不来最后只能离线删镜像。建议数据目录预留 100GB 以上如果是长期使用300GB 起步更稳。# 检查磁盘空间和 inode 数 df -h /data df -i /data # 如果 /data 不存在或者是根分区创建独立挂载点 sudo mkdir -p /data # 假设有独立的 /dev/sdb1 分区挂载到 /data sudo mount /dev/sdb1 /data echo /dev/sdb1 /data ext4 defaults 0 0 | sudo tee -a /etc/fstab # 调整内核参数增大网络连接数Harbor 频繁的镜像推送需要大量并发连接 sudo tee -a /etc/sysctl.conf EOF net.ipv4.ip_local_port_range 1024 65535 net.ipv4.tcp_max_syn_backlog 4096 EOF sudo sysctl -p除了磁盘内核参数也是 ARM 平台上容易被忽略的坑。ARM 服务器的默认网络栈参数在 docker0 网桥存在的情况下连接数上限偏低当客户端并发推镜像时会出现connection reset by peer。修改ip_local_port_range和tcp_max_syn_backlog是成本最低的加固手段。还有一点ARM 平台经常使用 SD 卡或 eMMC 作为系统盘这类存储的 IOPS 很低建议把/data挂到 SSD 或 NVMe 盘上否则垃圾回收时 IO 等待会拖垮 Harbor 的 API 响应速度。3.2 配置 harbor.yml从模板到可用的最小改动Harbor 的配置集中在 harbor.yml 中harbor.yml.tmpl是官方提供的模板里面每个参数都有注释。安装脚本只认harbor.yml所以第一步永远是复制模板。最小化配置只需关注四个关键项hostname、端口、管理员密码、数据目录。在这个环节最容易翻车的是把 hostname 配成了带 http:// 前缀的完整 URL导致重定向异常。# 复制配置模板 cp harbor.yml.tmpl harbor.yml # 编辑 harbor.yml重点关注以下参数用 vim 或 nano vim harbor.yml# harbor.yml 关键配置项节选 # 对外访问地址不要带 http 或 https 前缀IP 或域名都可以 hostname: 192.168.1.100 # HTTP 端口默认 80如果需要同时开 HTTPS下方 https 配置也要改 http: port: 80 # HTTPS 配置生产环境强烈建议启用这里给出证书路径示例 # https: # port: 443 # certificate: /data/cert/server.crt # private_key: /data/cert/server.key # 管理员初始密码要求长度至少 8 位包含大小写和数字 harbor_admin_password: Harbor12345 # 数据持久化目录所有数据库文件、镜像存储、redis 数据都在这下面 data_volume: /data # 日志级别的可选值debug、info、warning、error、fatal log: level: info配置项里还有几个容易忽略的延展参数external_url用于反向代理场景database的password参数可以自定义 PostgreSQL 密码redis参数支持外部 Redis 地址。在离线环境中如果没有特殊需求建议保持默认因为外部数据库和 Redis 的引入会增加部署复杂度。特别注意harbor_admin_password在首次启动后就会写入数据库后续修改需要进容器操作或者使用 API 接口不能在 yml 里改完重跑 install.sh 就生效。所以初始密码一定要想清楚再写别用弱密码图省事。3.3 执行安装install.sh 的实际行为和参数解读配置完成后运行install.sh它会依次执行以下动作检查 Docker 和 Docker Compose 版本 → 检查 harbor.yml 是否存在 → docker load 加载 harbor.v2.7.0.tar.gz 里的全部镜像 → 生成 docker-compose.yml → 启动所有容器。安装过程的耗时主要取决于磁盘 IO 和镜像数量ARM 平台上通常在 2 到 5 分钟之间。# 执行安装启用漏洞扫描组件 sudo ./install.sh --with-trivy # 如果还需要 Helm Chart 仓库支持 sudo ./install.sh --with-trivy --with-chartmuseum # 安装完成后验证所有服务状态 docker ps # 期望输出harbor-core、harbor-db、harbor-registry、harbor-portal、harbor-log、harbor-jobservice、nginx # 查看 Harbor 整体的启动日志 docker compose -f docker-compose.yml logs -f参数说明--with-trivy会额外加载 Trivy 漏洞扫描器镜像并启动一个trivy-adapter容器--with-chartmuseum会启动 Chartmuseum 容器用于存储 Helm Charts。首次安装并且磁盘紧张的情况下可以先不加这两个参数后续需要时再补装。有一点要注意install.sh 是幂等的吗理论上多次执行不会重复创建容器但如果中途失败导致 docker-compose.yml 已经生成下次执行前最好先docker compose down -v清理残留卷否则容易出现数据库初始化冲突。安装完成后用浏览器访问 http://IP默认端口 80输入 admin 和你设置的密码如果能打开 Harbor 管理界面说明核心服务已经正常。3.4 容器服务的组成和健康检查方法Harbor 2.7.0 的容器拓扑比早期版本复杂一共八个核心容器。理解每个容器的职责在后续排查故障时能少走很多弯路。nginx是统一入口负责转发所有请求harbor-core是核心业务逻辑服务harbor-registry是镜像存储服务基于 Docker Distributionharbor-db是 PostgreSQL 数据库harbor-redis是缓存和 session 存储harbor-jobservice处理复制、垃圾回收等异步任务harbor-portal是前端页面harbor-log收集所有日志。# 通过 docker compose ps 查看所有服务的健康状态 docker compose -f /opt/harbor/docker-compose.yml ps # 输出中的 STATUS 列如果显示 healthy说明该容器通过了健康检查 # 检查 Harbor 的整体组件状态通过 API 方式 curl -u admin:Harbor12345 https://你的IP/api/v2.0/health # 返回 JSON 中的 status 字段为 healthy 表示全部组件正常 # 手动查看关键日志core 服务报 500 时优先看这里 docker logs harbor-core --tail 100容器健康检查是 Harbor 运维里最实用的技巧。docker compose ps输出的healthy/starting/unhealthy状态很直观当某个容器停在 unhealthy 时不要盲目重启整个栈先看对应容器的日志定位具体问题。/api/v2.0/health接口返回的是一个 JSON 数组里面逐项列了 core、db、redis、jobservice 等组件的健康状态。如果是数据库容器挂了日志里通常是connection refused或者文件锁错误优先检查磁盘空间和 PostgreSQL 数据文件权限。4. Harbor 离线安装部署的五个高频踩坑记录4.1 容器启动报 no space left on device 但 df 显示还有空间这个坑在离线安装后第一次推送镜像时最明显。现象是 docker 报no space left on device但df -h一看还有几十 GB 剩余。原因是 inode 耗尽了尤其是在数据目录使用了 XFS 文件系统且默认分配 inode 较少的情况下。Harbor 的镜像存储目录/data/registry/docker/registry/v2下会创建海量的小文件每个镜像层对应一个目录和多个文件镜像多了 inode 数量会快速增长。解决方法是先确认 inode 使用率df -i /data # 如果 IUse% 接近 100%就是 inode 耗尽然后换用重新格式化文件系统的方案。对于已经部署的环境最直接的办法是清理无用的镜像层——运行 Harbor 的垃圾回收# 通过 API 触发垃圾回收 curl -u admin:Harbor12345 -X POST https://IP/api/v2.0/system/gc # 或者在 UI 中 管理-垃圾回收 中手动执行但如果 inode 已经 100% 且垃圾回收也跑不动只能扩容或换盘。经验是在安装前就规划好/data的文件系统类型ext4 在同等容量下 inode 数通常比 XFS 默认值多如果必须用 XFS可以在 mkfs 时指定-i maxpct50让 inode 占比更高。这个坑的根因不是 Harbor 本身而是存储规划没跟上镜像仓库的业务特征。4.2 ARM64 环境执行 install.sh 出现 exec format errorexec format error 是 ARM 平台最容易遇到的错误。现象是在 x86 机器上解压 arm64 的离线包然后手动执行里面的脚本或二进制直接报exec format error。另一个场景是ARM 机器上装了 x86 版本的 Docker 或容器镜像导致运行时崩溃。这个错误非常直观二进制文件的 CPU 架构和当前系统不匹配。原因只有一种架构混用。解决办法也是唯一的确认包名是 arm64 后在 ARM64 系统上重新解压安装。但有一种情况更容易被忽略——宿主机的 Docker 容器可以跑 ARM 镜像吗如果你是 arm64 宿主机运行 amd64 镜像会报同样的错误。所以不要试图在树莓派上拿 amd64 镜像硬抗。另外需要提醒的是shell 脚本本身没有架构限制但脚本内调用的 docker 命令和二进制工具是有架构限制的。出现这种错误时先执行uname -m和file 二进制文件确认当前系统和文件的架构类型再检查镜像标签里的linux/arm64标注。4.3 Harbor 页面能打开但登录后显示 502nginx 容器反复重启502 的根源在于 nginx 到 harbor-core 的网络链路断裂。现象是登录页能打开输入账号密码后页面转圈或直接 502。原因通常是 harbor-core 容器处于 unhealthy 状态或者 harbor 网络内 DNS 解析异常。值得注意的是ARM 平台上 Docker 默认 DNS 配置在某些系统比如 Ubuntu 的 systemd-resolved下会导致容器间域名解析失败。# 先看 nginx 日志确认 502 是哪个上游返回 docker logs harbor-nginx --tail 100 # 日志中出现 connect() failed (111: Connection refused) 说明 core 端口没监听 # 确认 core 容器状态和日志 docker ps | grep harbor-core docker logs harbor-core --tail 100 # 如果是 DNS 问题修改 Docker daemon 配置 sudo tee /etc/docker/daemon.json EOF { dns: [8.8.8.8, 114.114.114.114] } EOF sudo systemctl restart docker但修改 Docker DNS 后需要重启整个 Harbor 栈才能生效sudo docker compose -f docker-compose.yml down sudo docker compose -f docker-compose.yml up -d这个问题的背后还涉及一个 ARM 平台的衍生坑某些 ARM 主板的网卡驱动如瑞昱 RTL 系列在 Docker 网桥模式下会出现数据包丢失导致容器间的 TCP 连接不稳定。如果 Log 里看到大量connect() failed (110: Connection timed out)而不是 111优先检查网卡驱动和交换机协商速率。4.4 harbor-db 容器启动失败locks must be owned by this userHarbor 的数据库容器以 postgres 用户运行但在宿主机的/data/database目录权限不正确时会出现FATAL: data directory /var/lib/postgresql/data has invalid permissions或locks must be owned by this user之类的错误。这种现象在离线安装后首次启动时最常出现也与安装时用了sudo执行导致数据目录 root 权限有关。解决方法是把数据目录的所有权改为 uid 999postgres 容器内用户的 uid同时确保目录权限是 700# 停止 Harbor sudo docker compose -f docker-compose.yml down # 修改数据库目录权限 sudo chown -R 999:999 /data/database sudo chmod -R 700 /data/database # 重新启动 sudo docker compose -f docker-compose.yml up -d这个问题的根源是 Harbor 的容器化架构宿主机目录挂载进入容器后宿主机用户的 UID 映射到容器内用户会出现差异。下次执行 install.sh 前检查/data下所有目录的属主是否匹配容器内用户 UID——registry 是 10000database 是 999redis 是 999。出现数据库文件权限问题时不要改为 root 去绕过否则后续 PostgreSQL 会因为root execution is not permitted而拒绝启动。4.5 公网环境下端口冲突导致 install.sh 中途失败install.sh 中间步骤失败但 Docker 容器已经启动了一部分的现象并不少见最常见的导火索是 80 端口被占用。ARM 服务器上经常预装 Nginx 或某个 Web 管理面板比如宝塔占用了 80。install.sh 不会提前检查端口它执行到 docker compose up nginx 时才发现 bind 失败。# 检查 80 端口占用 sudo netstat -tlnp | grep :80 # 结果示例tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1234/nginx # 更换 Harbor 端口修改 harbor.yml 的 http.port 为 8080 vim harbor.yml # 将 http.port 改为 8080 # 重新 prepareHarbor 提供了重新生成配置的命令 sudo ./prepare # 重新启动容器 sudo docker compose -f docker-compose.yml up -d如果你不希望和现有服务抢端口也可以保持 80 端口不动而在 nginx 前做反向代理。但需要注意Harbor 的hostname参数在启用 HTTPS 后会写入 URL 中作为绝对跳转地址如果通过反向代理暴露hostname应设置为外部访问域名否则登录成功后页面会跳转到内部的http://IP:8080导致打不开。这个问题的排查方法就是看浏览器地址栏里的 URL 是不是变了如果跳到了 IP:8080 说明 hostname 配错了。5. 从离线安装到镜像拉取验证部署完整性的五个实用技巧5.1 使用 docker login 和 push/pull 验证镜像通道Harbor 界面能打开只代表 Web 服务正常真正的镜像存取链路需要从客户端侧验证。在 ARM 开发机上执行 docker login、pull、push 一套流程能同时验证 DNS 解析、鉴权模块、registry 存储、以及与 Harbor 的数据库同步。# 在 ARM 客户端上登录 Harbor echo Harbor12345 | docker login 192.168.1.100 -u admin --password-stdin # 输出含 Login Succeeded 才算成功 # 拉取一个测试镜像先 pull 下来再重新 push 上去 docker pull ubuntu:22.04 docker tag ubuntu:22.04 192.168.1.100/library/ubuntu-test:22.04 docker push 192.168.1.100/library/ubuntu-test:22.04 # push 成功后到 UI 的镜像仓库页面确认是否显示 # 验证拉取 docker rmi 192.168.1.100/library/ubuntu-test:22.04 docker pull 192.168.1.100/library/ubuntu-test:22.04如果 push 过程中出现401 Unauthorized排查方向是 admin 密码是否与 harbor.yml 一致如果 push 到一半报403 Forbidden检查项目Project的访问级别是否允许推送——Harbor 默认library项目可以 push但用户自定义项目可能需要额外授权。这组命令是 Harbor 部署完成后最应该跑一遍的冒烟测试它能覆盖从客户端到服务端全链路的完整性。ARM 客户端本身也要注意镜像架构拉取 ubuntu:22.04 时会自动匹配 arm64 变体不用手动指定。5.2 通过 API 检查系统健康与垃圾回收状态Harbor 的 REST API 是判断系统状态更精确的手段。打开 Swagger UI地址/devcenter-api-2.0/可以交互式测试每个接口脚本化监控时则直接 curl。状态检查接口返回的不是简单的健康/不健康而是包含 edge、core、database、redis、jobservice、portal 等模块的状态。# 查看系统总体健康状态 curl -u admin:Harbor12345 https://192.168.1.100/api/v2.0/health # 查看系统单例配置用于确认启动时间、版本号等 curl -u admin:Harbor12345 https://192.168.1.100/api/v2.0/systeminfo # 查看所有项目列表确认建项目权限正常 curl -u admin:Harbor12345 https://192.168.1.100/api/v2.0/projects?page1page_size10API 返回 JSON 格式每一项组件有status字段。对于监控系统来说对比上一次调用的状态差即可判断异常。需要注意的是/api/v2.0/health不会主动检查存储闲置空间如果磁盘满了但这个接口仍然返回 healthy所以实际监控时还要叠加磁盘阈值检查。在 ARM 平台部署的 Harbor 上API 响应时间如果超过 3 秒大概率是数据库查询变慢需要检查磁盘 IO 和 PostgreSQL 的连接数。5.3 配置本地 DNS 或 hosts避免镜像地址频繁改动镜像拉取需要长域名192.168.1.100这种 IP 虽然能用但每次 docker login 和推送都要带 IP一旦 IP 变更所有客户端里的镜像地址全部失效。在离线环境中我们通常给 Harbor 配一个内部域名比如harbor.internal。# 在客户端机器上的 /etc/hosts 添加解析 192.168.1.100 harbor.internal # 或者更规范的做法在内部 DNS 服务器添加 A 记录 # 这样 docker login harbor.internal 即可 docker login harbor.internal -u admin -p Harbor12345配置域名带来的另一个好处是可以用正规的 HTTPS 证书而不是自签的 IP 证书。Harbor 支持在 harbor.yml 中的https段配置证书路径证书域名匹配harbor.internal后客户端 docker 只需在/etc/docker/daemon.json里配置insecure-registries: [harbor.internal]或者在系统信任证书仓库里安装 CA就能免去 TLS 报错的烦恼。ARM 机器如果和 Harbor 在同一个局域网建议优先用 hosts 而不是外部 DNS减少一层依赖。5.4 定期回收镜像存储空间GC 的正确打开方式Harbor 不会主动删除镜像物理层删除仓库里的镜像只是标记删除。磁盘空间只有在执行垃圾回收GC时才会真正释放。离线环境下的镜像仓库通常用久了会有几十 GB 的标记删除数据如果不管它磁盘很快就会满。# 通过 API 触发实时垃圾回收 curl -u admin:Harbor12345 -X POST https://192.168.1.100/api/v2.0/system/gc # 通过 API 查看回收历史确认上次 GC 结果 curl -u admin:Harbor12345 https://192.168.1.100/api/v2.0/system/gc # 如果你想定时回收可在 Harbor 服务器的 crontab 中加入任务 0 2 * * * /usr/bin/curl -u admin:Harbor12345 -X POST https://192.168.1.100/api/v2.0/system/gc /var/log/harbor-gc.log 21GC 执行期间 Harbor 的推送服务会受影响吗实际上由于 GC 会读取 registry 的 manifest过程中不建议并发向 Harbor 推送大镜像否则可能产生digest mismatch错误。所以定时 GC 的时间点要选在业务低峰期。注意 GC 不会清理 tag 为 latest 之外的历史版本所需的层它只清除没有任何 tag 引用的孤儿对象。如果想保留最近 N 个版本而删掉更旧的需要先通过 API 删除对应 tag再执行 GC。5.5 配置保留策略Retention Policy自动清理过期镜像手动删镜像再 GC 还是太麻烦Harbor 2.7.0 提供了保留策略功能可以在 UI 的配置管理中设置规则比如按 tag 数量保留最近 10 个版本或者只保留最近 30 天的镜像。离线环境下CI/CD 流水线每次构建都往 Harbor 推镜像如果没有保留策略存储会被快速填满。# 通过 API 创建一个简单的保留策略保留每个仓库最近 5 个 tag # 这里以 curl JSON 格式演示实际 UI 操作更直观 curl -u admin:Harbor12345 -X POST https://192.168.1.100/api/v2.0/retentions \ -H Content-Type: application/json \ -d { algorithm: or, rules: [ { disabled: false, action: retain, template: latestPulledK, params: {latestPulledK: 5}, tag_selectors: [ { kind: doublestar, decoration: matches, pattern: ** } ], scope_selectors: { repository: [ { kind: doublestar, decoration: repoMatches, pattern: ** } ] } } ], trigger: { kind: Schedule, settings: {cron: 0 0 2 * * *} } }这个 API 请求创建了一个每晚 2 点执行的策略对每个仓库保留最近被拉取过的 5 个 tag。字段说明algorithm是or表示满足任一条规则即执行action是retain表示保留也可以设为deletetemplate是latestPulledK表示按最近拉取次数保留 K 个。如果按标签数量保留改latestPushedK。这条 API 需要正确理解 JSON 结构才能一次调通新手建议先在 UI 界面操作然后通过浏览器开发者工具观察实际发出的请求体再复刻到脚本里。6. 离线场景下的 Harbor 镜像同步用 dragonfly 给大规模集群分发提速在离线内网环境中几十台 ARM 节点同时拉取同一个基础镜像时Harbor 会成为瓶颈。一次docker pull可能要持续好几分钟多个节点并发拉取Harbor 的带宽和 IO 都会被压满。这个问题在生产环境很常见——比如某个版本发布所有节点需要更新同一个应用镜像。解决方式之一是利用 Harbor 的镜像复制功能把镜像从主 Harbor 复制到区域 Harbor但更轻量的方案是结合 dragonfly 做 P2P 分发。dragonfly 的架构中有 supernode中心调度器和 dfagent各节点客户端。当节点 A 拉取镜像时supernode 会记录该镜像片段在哪些节点上已经存在后续节点拉取时直接从相邻节点获取数据块而不是都从 Harbor 拉取。离线环境里Harbor 只在最初提供一个源节点间互相充当数据源大幅降低 Harbor 的出口带宽压力。# 在 Harbor 服务器上部署 dragonfly supernode容器方式 docker run -d --name supernode-dragonfly \ --restartalways \ -p 8002:8002 \ -p 8003:8003 \ -v /data/dragonfly:/data \ dragonflyoss/supernode:v2.1.0 # 在 ARM 开发机上安装 dfclient # 下载 ARM64 版本的 dfclient 并配置 supernode 地址 sudo tar -zxvf dfclient_arm64.tar.gz -C /usr/local/bin/ sudo tee /etc/dragonfly/dfdaemon.yml EOF registry_mirror: addr: harbor.internal scheme: https cert: /etc/dragonfly/harbor-ca.crt supernodes: - addr: 192.168.1.1:8002 EOF # 启动 dfdaemon 作为 docker pull 的代理 sudo dfdaemon --config /etc/dragonfly/dfdaemon.yml 配置了 dfdaemon 后节点上的 docker 需要把 Registry Mirror 指到本地 65001 端口dfdaemon 默认监听端口sudo tee /etc/docker/daemon.json EOF { registry-mirrors: [http://127.0.0.1:65001] } EOF sudo systemctl restart docker这套结构里节点第一次拉取时仍然从 Harbor 取数据同时被 dfdaemon 缓存后续其他节点再拉取dfdaemon 会优先从已有数据的节点上获取分片。对 ARM 节点集群来说这能把发布会拉的等待时间从几分钟压缩到几十秒。第一次部署 dfdaemon 的时候我栽过跟头——端口 65001 被本机的 tcp 连接占用了导致 docker pull 直接报 connection refused。解决方法是在 dfdaemon.yml 里显式配置http_proxy_port: 65001确保和 daemon.json 里的 registry-mirrors 端口一致。不过要注意dragonfly dfdaemon 的方案不适合单机或者双机的小集群节点少于 5 台时收益不明显反而增加了运维复杂度。如果只是几台 ARM 测试机直接用 Harbor 原始拉取就够用了。但这个方案给离线大规模集群提供了一条性价比极高的路径它没有改变 Harbor 本身的行为只是在 docker pull 这层加了个智能分发风险可控。我现在的习惯是任何 Harbor 集群到 10 台以上 ARM 节点就自动纳入 dragonfly 分发能有效避免镜像风暴把 Harbor 服务器打挂。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。