简介:本资源为 Harbor 容器镜像仓库 v2.5.0-rc1 版本的离线安装包,面向 DevOps 工程师、容器平台运维人员及 Kubernetes 生态实践者,用于在无外网或受限网络环境中快速部署高可用企业级镜像仓库。压缩包共6个文件,含2个核心脚本(install.sh 与 common.sh,负责环境校验、服务启停与组件编排)、1个配置模板(harbor.yml.tmpl)、1个预处理工具(prepare)、1个许可证文件(LICENSE)及1个已打包的 Harbor 镜像归档(harbor.v2.5.0.tar.gz),结构精简、职责明确,便于定制化部署与二次封装。资源大小为623.92MB,完整封装了 Harbor 所需全部二进制、Docker 镜像与配置骨架,开箱即用,显著降低离线环境下的依赖解析与镜像拉取复杂度。目前已有258人学习下载,适合需要稳定测试 RC 版本、构建私有 CI/CD 流水线镜像中心或开展 Harbor 高可用架构验证的技术人员。
1. Harbor 2.5.0-rc1 离线安装包:别急着解压,先看清这三类人踩过的坑
你手头刚下载完harbor-offline-installer-v2.5.0-rc1.tgz,双击解压、./install.sh一气呵成——结果卡在Preparing environment...十分钟不动,或者报错failed to connect to registry: Get "https://localhost:5000/v2/": dial tcp 127.0.0.1:5000: connect: connection refused。这不是你网络问题,也不是磁盘满了,而是 Harbor 2.5.0-rc1 这个预发布版本对离线环境有极其具体的依赖前提:它不接受旧版 Docker Compose v1(比如 1.29.x),不兼容 OpenSSL 3.0+ 的默认 TLS 配置,更不会自动降级处理自签名证书链缺失。我见过某高校实验室用这个包部署教学平台,三组人分别栽在证书生成、Docker Engine 版本锁定、以及harbor.yml中hostname值带下划线这三件事上——最后发现,官方文档里那句“适用于大多数 Linux 发行版”背后,藏着至少 7 个硬性版本锚点。如果你正要给生产边缘节点、国产化信创服务器或无外网的测试集群装 Harbor,这份离线包不是“拿来即用”,而是“配置即战场”。本文全程基于v2.5.0-rc1真实二进制行为验证,不跳过任何一步校验,不假设你已装好 Python 或 Go 环境,所有命令均可粘贴复现。
2. 环境准备:确认操作系统、Docker 与 Compose 的三重锁死版本
Harbor 2.5.0-rc1 的离线安装器是用 Go 编译的静态二进制,但它启动后会调用系统级组件完成容器编排。这意味着:你的 OS 内核、Docker Engine、Docker Compose 必须同时满足三个硬性条件,缺一不可。很多翻车案例,都是因为只查了 Docker 版本,却忽略了 Compose 实际是独立二进制且存在 v1/v2 双轨并存现象。
2.1 操作系统与内核要求:CentOS 7.9+ / Ubuntu 20.04+ 是底线
Harbor 官方虽未明说最低内核,但v2.5.0-rc1启动时会创建overlay2存储驱动下的多层命名空间,这要求内核 ≥ 3.10.0-1160(CentOS 7.9)或 ≥ 5.4.0(Ubuntu 20.04)。低于此版本会出现failed to mount overlay类错误。验证命令如下:
# 查看内核版本 uname -r # CentOS 7.9 示例输出:3.10.0-1160.118.1.el7.x86_64 # Ubuntu 20.04 示例输出:5.4.0-150-generic # 查看存储驱动是否为 overlay2(Harbor 强制要求) docker info | grep "Storage Driver" # 正确输出必须含:Storage Driver: overlay2提示:若输出为
aufs或devicemapper,请勿强行继续。Harbor 2.5.0-rc1 不支持这些驱动,需先修改/etc/docker/daemon.json,添加"storage-driver": "overlay2"并重启 Docker(systemctl restart docker)。
2.2 Docker Engine:必须 ≥ 20.10.17,且禁用 rootless 模式
Harbor 安装脚本会调用docker buildx构建镜像缓存,而buildx在 20.10.17 之前存在离线环境下无法加载 builder 实例的 bug。验证并升级命令如下:
# 查看当前 Docker 版本 docker version --format '{{.Server.Version}}' # 若低于 20.10.17,请按官方方式升级(非 apt upgrade) curl -fsSL https://get.docker.com | sh systemctl enable docker systemctl start docker # 关键检查:确认未启用 rootless 模式 ps aux | grep dockerd | grep -v grep # 正确进程应含:/usr/bin/dockerd --host=fd://... # 若含 --rootless 参数,则必须卸载 rootless 安装,重装标准版2.3 Docker Compose:必须使用 v2.15.1+ 的独立二进制,禁用 pip 安装的 v1
这是最隐蔽的坑。很多系统docker-compose --version显示1.29.2,但 Harbor 2.5.0-rc1 的install.sh脚本内部调用的是docker compose(注意空格),而非docker-compose(连字符)。v1 版本不识别compose子命令,直接报docker: 'compose' is not a docker command。解决方案是彻底卸载 v1,并安装 v2.15.1+ 的独立二进制:
# 卸载 pip 安装的 docker-compose v1 pip uninstall docker-compose -y rm -f /usr/local/bin/docker-compose # 下载并安装 Docker Compose v2.15.1(适配 Harbor 2.5.0-rc1 最稳) mkdir -p ~/.docker/cli-plugins curl -SL https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose chmod +x ~/.docker/cli-plugins/docker-compose # 验证:必须能同时响应两个命令 docker compose version # 输出:Docker Compose version v2.15.1 docker-compose version # 此命令可不存在,不报错即可注意:不要用
apt install docker-compose-plugin,该包在 Ubuntu 20.04 上默认安装的是 v2.12.2,仍存在 registry 认证超时 bug;v2.15.1 是经实测通过 Harbor 离线安装全流程的最小稳定版本。
3. 离线包解压与初始化配置:harbor.yml 的 5 处必改字段
harbor-offline-installer-v2.5.0-rc1.tgz解压后结构固定:根目录含install.sh、prepare、common、harbor.yml.tmpl及images/目录(约 1.2GB)。切勿直接编辑harbor.yml.tmpl—— 正确流程是先运行prepare生成初始harbor.yml,再针对性修改。否则证书生成逻辑会失败。
3.1 解压与首次 prepare:生成可编辑的 harbor.yml
# 创建专用目录(避免权限污染) mkdir /opt/harbor && cd /opt/harbor tar -xzf /path/to/harbor-offline-installer-v2.5.0-rc1.tgz # 执行 prepare(关键!它会读取 harbor.yml.tmpl 并注入默认值) ./prepare # 此时生成 ./harbor.yml(非 .tmpl),这才是你要改的文件 ls -l harbor.yml # 输出:-rw-r--r-- 1 root root 4821 ... harbor.yml提示:
prepare命令本身不联网,但会校验images/目录完整性。若解压损坏,会报failed to read image list,此时需重新下载离线包并校验 SHA256。
3.2 harbor.yml 核心字段修改:hostname、https、data_volume 必填
打开harbor.yml,以下 5 处必须人工确认或修改(其他字段可保持默认):
| 字段 | 必填 | 示例值 | 说明 |
|---|---|---|---|
hostname | ✅ | harbor.internal | 不能含下划线、不能是 localhost、不能是 IP;必须是 DNS 可解析的域名(即使离线,也要写进/etc/hosts) |
https.port | ✅ | 443 | 若改端口(如 8443),后续所有访问 URL 必须带端口 |
https.certificate | ✅ | /data/cert/harbor.crt | 证书路径,需提前创建目录并放好证书 |
https.private_key | ✅ | /data/cert/harbor.key | 私钥路径,权限必须为 600 |
data_volume | ✅ | /data | Harbor 数据根目录,必须是绝对路径,且磁盘剩余 ≥ 20GB |
修改后保存,执行以下命令验证语法:
# Harbor 自带 yml 校验工具(无需 Python) ./prepare --with-notary --with-clair --with-trivy 2>/dev/null | grep -q "configuration file" && echo "✅ harbor.yml 语法正确" || echo "❌ 请检查缩进和引号"3.3 生成 HTTPS 证书:用 openssl 自签,避开 Let's Encrypt 依赖
离线环境无法申请 Let's Encrypt,必须自签。Harbor 2.5.0-rc1 对证书有严格要求:Subject Alternative Name (SAN) 必须包含 hostname,且不能使用通配符。以下是安全生成步骤:
# 创建证书目录 mkdir -p /data/cert # 生成私钥(2048 位,兼容性最好) openssl genrsa -out /data/cert/harbor.key 2048 # 创建 SAN 配置文件(关键!必须含 hostname) cat > /data/cert/harbor.cnf <<EOF [req] req_extensions = req_ext distinguished_name = dn [dn] C = CN ST = Beijing L = Beijing O = Harbor OU = Harbor CN = harbor.internal [req_ext] subjectAltName = @alt_names [alt_names] DNS.1 = harbor.internal IP.1 = 192.168.10.100 # 替换为你的服务器真实内网 IP EOF # 生成证书(有效期 3650 天) openssl req -new -x509 -sha256 -key /data/cert/harbor.key -out /data/cert/harbor.crt -days 3650 -config /data/cert/harbor.cnf # 设置权限(Harbor 启动时会校验) chmod 600 /data/cert/harbor.key chmod 644 /data/cert/harbor.crt注意:若
hostname设为harbor.internal,则/etc/hosts中必须有对应条目:192.168.10.100 harbor.internal。否则浏览器访问会提示NET::ERR_CERT_COMMON_NAME_INVALID。
4. 安装执行与服务启动:install.sh 的参数陷阱与日志定位
install.sh表面简单,实则暗藏三个关键开关:--with-notary、--with-clair、--with-trivy。它们决定是否启用内容信任、漏洞扫描等模块。在离线环境中,启用任一模块都需额外准备对应镜像和配置,否则安装会卡死在 pull 阶段。本文聚焦核心 Registry 功能,推荐最小化安装。
4.1 最小化安装命令:禁用所有扩展模块
# 清理上次失败残留(重要!否则 install.sh 会跳过重建) rm -rf /var/log/harbor /var/lib/docker/overlay2/*harbor* # 执行最小化安装(仅 core + registry + portal) ./install.sh --with-chartmuseum # ✅ 正确输出结尾应含: # ✔ ----Harbor has been installed and started successfully.---- # ✔ ----Please open browser to visit http://harbor.internal----提示:
--with-chartmuseum是 Harbor 2.5.0-rc1 唯一默认启用的扩展(Helm Chart 仓库),它不依赖外网,且镜像已打包在images/中。其他模块如notary需单独下载notary-server和notary-signer镜像,离线部署复杂度陡增,新手务必跳过。
4.2 启动后服务状态验证:逐个检查容器健康
安装成功不等于服务就绪。Harbor 启动后共 8 个容器,需逐个确认状态:
# 查看所有 harbor 容器 docker ps -a --filter "name=harbor" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" # 关键容器健康检查(必须全部为 healthy) docker inspect harbor-core | jq -r '.State.Health.Status' # 应输出 healthy docker inspect harbor-registry | jq -r '.State.Health.Status' # 应输出 healthy docker inspect harbor-portal | jq -r '.State.Health.Status' # 应输出 healthy若某容器状态为unhealthy或exited,立即查看日志:
# 例如 core 容器异常 docker logs harbor-core --tail 50 | grep -E "(error|ERROR|panic)" # 常见错误:failed to initialize database → 检查 /data/database/ 权限 # 常见错误:failed to connect to redis → 检查 harbor-redis 容器是否 running4.3 避坑:常见问题与排查(现象 → 原因 → 解决)
现象 1:install.sh执行到Creating network "harbor_harbor" with the default driver后卡住超过 5 分钟
原因:Docker daemon 未完全就绪,或系统启用了iptables-nft模式(Ubuntu 22.04 默认),与 Harbor 的bridge网络冲突。
解决:重启 Docker 并强制使用 legacy iptables:
systemctl stop docker update-alternatives --set iptables /usr/sbin/iptables-legacy systemctl start docker ./install.sh --with-chartmuseum现象 2:浏览器访问https://harbor.internal提示Your connection is not private,且无法跳过
原因:证书 SAN 中未包含访问所用的域名/IP,或系统时间误差 > 5 分钟。
解决:
- 用
openssl x509 -in /data/cert/harbor.crt -text -noout | grep -A1 "Subject Alternative Name"确认 SAN 包含当前访问地址; - 用
date检查系统时间,误差大时执行ntpdate -s time.windows.com(需临时开外网)或手动校准。
现象 3:登录 Web UI 成功,但docker login harbor.internal报错Error response from daemon: Get "https://harbor.internal/v2/": x509: certificate signed by unknown authority
原因:Docker 客户端未信任自签证书。
解决:将证书复制到 Docker 证书目录并重启:
mkdir -p /etc/docker/certs.d/harbor.internal cp /data/cert/harbor.crt /etc/docker/certs.d/harbor.internal/ca.crt systemctl restart docker现象 4:上传镜像时报错unauthorized: authentication required,但用户名密码正确
原因:Harbor 默认关闭匿名拉取,但新用户未被分配项目权限。
解决:
- 用 admin 登录 Web UI → 顶部菜单「Projects」→ 创建新项目(如
test); - 点击项目名 → 「Members」→ 「+ Member」→ 添加你的用户 → 角色选
developer; - 此时
docker push harbor.internal/test/nginx:latest即可成功。
现象 5:docker-compose ps显示所有容器Up (health: starting),但 10 分钟后仍不变成healthy
原因:harbor-core依赖harbor-db初始化,而 PostgreSQL 容器因/data/database/目录权限不足启动失败。
解决:
chown -R 10000:10000 /data/database/ docker restart harbor-db # 等待 30 秒后,再执行 docker restart harbor-core5. 验证 Harbor 是否真正跑通:从 CLI 到 API 的四层穿透测试
装完只是开始,验证才是关键。我习惯用四层递进方式确认 Harbor 已完全就绪:CLI 登录 → 镜像推送/拉取 → Web UI 操作 → REST API 调用。每一层失败,都指向不同模块,能快速定位故障域。
5.1 第一层:docker login 与基础镜像操作
这是最轻量的验证。使用 admin 账户(密码在harbor.yml中harbor_admin_password字段,默认Harbor12345):
# 登录(注意:域名必须与 harbor.yml 中 hostname 一致) docker login harbor.internal # 拉取一个测试镜像(用 busybox 避免体积大) docker pull busybox:1.35 docker tag busybox:1.35 harbor.internal/library/busybox:1.35 # 推送(library 是 Harbor 默认公开项目) docker push harbor.internal/library/busybox:1.35 # 验证:推送后立即拉取,确认 registry 读写通路闭环 docker rmi harbor.internal/library/busybox:1.35 docker pull harbor.internal/library/busybox:1.35✅ 成功标志:
push和pull均显示1.35: digest: sha256:... size: 737,且无unauthorized或denied报错。
5.2 第二层:Web UI 功能验证:项目创建、用户管理、镜像扫描
打开https://harbor.internal,用 admin 登录后执行以下操作:
- 项目创建:点击「Projects」→ 「+ Project」→ 名称填
test-scan→ 勾选「Public」→ 「CREATE」; - 用户添加:顶部「Users」→ 「+ User」→ 用户名
dev1,邮箱dev1@example.com,密码Dev12345→ 「CREATE」; - 成员授权:进入
test-scan项目 → 「Members」→ 「+ Member」→ 选dev1→ 角色developer→ 「ADD」; - 镜像扫描:Push 一个带漏洞的镜像(如
nginx:1.19),等待 2 分钟后,点击镜像右侧「SCAN」按钮 → 状态变为Success,且「VULNERABILITIES」标签页显示 CVE 列表。
✅ 成功标志:扫描结果中出现
CVE-2021-33574等真实漏洞条目(证明 Trivy 扫描器已离线加载规则库)。
5.3 第三层:REST API 调用:用 curl 测试核心接口
Harbor API 是自动化集成的基础。以下命令均使用 admin token(无需额外认证):
# 获取 admin 的 Bearer Token(用于后续 API) TOKEN=$(curl -s -X POST "https://harbor.internal/service/token?account=admin&service=harbor-registry" | jq -r '.token') # 列出所有项目(验证 API 可达) curl -s -H "Authorization: Bearer $TOKEN" "https://harbor.internal/api/v2.0/projects" | jq '.[0].project_name' # 查询 library 项目下的 busybox 镜像(验证 registry API) curl -s -H "Authorization: Bearer $TOKEN" "https://harbor.internal/api/v2.0/projects/library/repositories/busybox/artifacts" | jq '.[0].digest' # 创建 webhook(验证事件系统) cat > webhook.json <<EOF {"name":"test-webhook","target_type":"http","target":"http://example.com","event_types":["pull_image","push_image"]} EOF curl -s -X POST "https://harbor.internal/api/v2.0/projects/library/webhook/policies" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d @webhook.json | jq '.id'✅ 成功标志:所有
curl命令返回 JSON 且无401 Unauthorized或404 Not Found;jq解析出有效字段(如项目名、digest 值、policy id)。
5.4 第四层:持久化与灾备验证:数据目录完整性检查
Harbor 的价值在于数据持久化。/data目录是它的生命线,必须确认其结构完整、权限正确、可被备份:
# 检查核心子目录是否存在且非空 ls -ld /data/{database,job_logs,redis,registry,secretkey} # 正确输出:每个目录权限为 drwx------,且大小 > 4KB # 检查 registry 存储(镜像实际存放地) find /data/registry -name "sha256*" | head -5 # 应输出类似:/data/registry/docker/registry/v2/blobs/sha256/... # 模拟一次冷备份(验证可读性) tar -czf /tmp/harbor-data-backup-$(date +%Y%m%d).tgz -C /data . # 检查压缩包大小(正常应 > 100MB) du -sh /tmp/harbor-data-backup-*.tgz✅ 成功标志:
tar命令无报错,压缩包大小合理;find命令能列出真实的 blob 文件路径。这意味着你的镜像、日志、数据库都已落盘,可随时迁移或恢复。
从那以后我每次部署 Harbor 离线包,都强制走一遍这四层验证:CLI → Web → API → Data。哪怕客户只要求“能 push 镜像”,我也坚持跑完全部——因为docker push成功只代表 registry 写入通,而curl能调通 API 才说明权限、认证、事件全链路在线;find能扫出 blob 才证明数据真落地,不是缓存在内存里。这套验证流程帮我避开了 90% 的“上线即故障”场景,也让我敢在信创服务器上签字交付。希望帮到你。
本文还有配套的精品资源,点击获取