简介:本资源为 Harbor 容器镜像仓库 v2.5.0-rc1 版本的离线安装包,面向 DevOps 工程师、容器平台运维人员及 Kubernetes 生态实践者,用于在无外网或受限网络环境中快速部署企业级镜像管理服务。压缩包共6个文件,含2个核心脚本(install.sh 与 common.sh,负责环境校验、组件解压与服务启停)、1个配置模板(harbor.yml.tmpl)、1个预处理工具(prepare)、1个许可证文件(LICENSE)及1个内嵌的 harbor.v2.5.0.tar.gz 镜像归档,整体体积达623.92MB,确保所有依赖镜像与二进制均已预置。目前已有258人学习下载,适合需落地私有化 Harbor、开展高可用部署验证或研究 RC 版本新特性的中高级用户。读者可直接执行 install.sh 启动完整服务栈,结合 prepare 工具灵活生成定制化配置,并通过 tmpl 模板理解 v2.5.0 的模块化结构与 TLS/认证等关键参数设计逻辑。
1. Harbor 离线安装包 v2.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 v2.5.0-rc1 这个「候选发布版」对底层依赖有隐性硬约束:它不再兼容 Docker 20.10 以下版本,强制要求 Compose v2.12+(非 legacy docker-compose),且默认启用的 Notary 服务在离线环境下会静默失败,不报错但镜像推送永远卡住。我见过太多人在生产环境凌晨三点反复重装,就因为没注意到v2.5.0-rc1后缀里的-rc1不是彩蛋,是「Release Candidate 1」——它意味着核心组件(尤其是 chartmuseum 和 trivy adapter)的启动顺序和健康检查逻辑已重构。这套离线包专为内网高安全场景设计:无外网依赖、证书自签闭环、所有镜像与二进制全内置。适合某高校科研平台、某金融实验室的私有镜像治理项目,或某跨平台系统中需要隔离构建环境的 DevOps 流水线。如果你正被「Harbor 怎么安装」「Harbor 离线部署」「Harbor v2.5 配置」这类搜索词困住,这篇笔记就是你跳过前 8 小时排错的后悔药。
2. 环境预检与离线包结构解析:先确认你的系统能接住这个「重载包」
Harbor 离线安装包不是普通压缩包,它是一个自包含的「运行时镜像仓库 + 配置引擎 + 证书工厂」三合一黑匣子。v2.5.0-rc1 版本将harbor.yml.tmpl拆分为harbor.yml(主配置)和common/config/registry/config.yml(底层 registry 细粒度控制),同时把install.sh升级为 Python 3.6+ 脚本(内嵌 Jinja2 模板渲染)。这意味着:你不能用sh install.sh,必须用bash install.sh或直接python3 ./install.py——这是第一个血泪经验。
2.1 系统级硬性门槛:三个命令定生死
执行前务必逐条验证,任一失败即终止:
# 1. Docker 版本:必须 ≥ 20.10.12(v2.5.0-rc1 引入了 containerd 1.6+ 的 snapshotter 适配) docker version --format '{{.Server.Version}}' | grep -E '^(20\.10\.[1-9][2-9]|20\.10\.[2-9][0-9]|2[1-9]\.)' # 2. Docker Compose 版本:必须为 Compose V2(路径 /usr/bin/docker-compose 或 /usr/libexec/docker/cli-plugins/docker-compose) docker compose version --short | grep -E '^v2\.(1[2-9]|[2-9][0-9])' # 3. SELinux 状态:v2.5.0-rc1 的 registry 容器默认启用 seccomp profile,若 SELinux 为 enforcing 且未加载 harbor policy,容器会立即退出 getenforce | grep -q "Enforcing" && sestatus -b | grep -q "container_manage_cgroup" || echo "SELinux OK"提示:若
docker compose version报错command not found,说明你还在用 legacydocker-compose。请卸载旧版并安装 Compose V2 插件:curl -SL https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 -o /usr/libexec/docker/cli-plugins/docker-compose && chmod +x /usr/libexec/docker/cli-plugins/docker-compose
2.2 解压后必看的四个核心目录:它们决定了你后续怎么改配置
进入解压目录(假设为/opt/harbor),结构如下:
| 目录 | 作用 | 关键文件 | 修改建议 |
|---|---|---|---|
./common/ | 运行时模板与默认配置骨架 | config/core/env(核心服务环境变量)、config/registry/config.yml(镜像存储策略) | 不要直接改这里!所有定制化必须通过harbor.yml控制 |
./harbor.yml | 唯一权威配置入口(YAML 格式) | hostname,https,database,redis,jobservice,trivy等区块 | 这是你唯一要编辑的文件,v2.5.0-rc1 新增notary和chart区块 |
./install.sh | 主安装脚本(Bash + Python 调用混合) | 内部调用./install.py渲染模板 | 可加-d参数启用 debug 模式:bash install.sh -d |
./images/ | 全量离线镜像包(约 1.2GB) | harbor-core:v2.5.0-rc1,goharbor/trivy-adapter-photon:v2.5.0-rc1等 | 切勿删除或重命名,install.sh会校验 SHA256 |
2.3harbor.yml必配的五个字段:漏一个,安装就静默失败
v2.5.0-rc1 对配置合法性校验极严。以下字段必须显式声明(即使使用默认值),否则install.sh会直接退出并提示Validation failed:
# /opt/harbor/harbor.yml 示例(关键字段已加注释) hostname: harbor.internal.local # 必须是 FQDN,不能是 IP 或 localhost http: port: 8080 https: # 若启用了 HTTPS(推荐),此区块必须完整 port: 8443 certificate: /data/cert/harbor.crt # 自签证书路径,需提前创建目录 private_key: /data/cert/harbor.key harbor_admin_password: "Harbor12345" # 密码强度要求:至少 8 位,含大小写字母+数字 database: password: "root123" # 内置 PostgreSQL 密码,不可为空注意:
certificate和private_key路径必须指向宿主机绝对路径,且install.sh会自动创建/data/cert目录。若你计划用已有证书,请确保.crt文件包含完整证书链(即 root CA + intermediate + domain cert 合并),否则 Trivy 扫描服务会因 TLS 验证失败而崩溃。
3. 安装全流程实操:从解压到首次登录的七步闭环
v2.5.0-rc1 的安装流程已从「脚本驱动」转向「配置驱动」:install.sh本质是读取harbor.yml→ 渲染common/config/下所有模板 → 加载./images/中镜像 → 启动容器。因此,每一步都可中断、可验证、可回滚。
3.1 步骤一:准备证书(HTTPS 必选项)
Harbor v2.5.0-rc1 默认禁用 HTTP(http.port仅作内部通信),必须配置 HTTPS。快速生成自签名证书(生产环境请替换为可信 CA):
# 创建证书目录 mkdir -p /data/cert # 生成私钥(2048 位,符合 v2.5.0-rc1 的 crypto/tls 要求) openssl genrsa -out /data/cert/harbor.key 2048 # 生成证书签名请求(CSR),注意 CN 必须与 harbor.yml 中的 hostname 一致 openssl req -new -key /data/cert/harbor.key -out /data/cert/harbor.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=harbor/CN=harbor.internal.local" # 自签证书(有效期 3650 天,避免频繁更新) openssl x509 -req -in /data/cert/harbor.csr -signkey /data/cert/harbor.key -out /data/cert/harbor.crt -days 3650逻辑说明:v2.5.0-rc1 的
core服务和registry服务均通过https://harbor.internal.local相互调用。若证书 CN 不匹配,core会拒绝连接registry,导致Preparing environment卡死。此处用harbor.internal.local是示例,你必须替换成自己规划的域名。
3.2 步骤二:编辑harbor.yml—— 重点处理三个易错区块
打开/opt/harbor/harbor.yml,按顺序修改以下区块(其他保持默认即可):
# --- 区块 1:基础信息(必须改) hostname: harbor.internal.local # 与证书 CN 严格一致 harbor_admin_password: "ChangeMe123!" # 密码需满足:≥8 位,含大小写+数字 # --- 区块 2:HTTPS 配置(必须完整) https: port: 443 certificate: /data/cert/harbor.crt private_key: /data/cert/harbor.key # --- 区块 3:数据库密码(必须显式设置,不能留空) database: password: "dbPassw0rd!2024" # --- 区块 4:Trivy 扫描器(v2.5.0-rc1 默认启用,但离线需关闭更新) trivy: ignore_unfixed: false skip_update: true # 关键!离线环境必须设为 true,否则启动时会尝试访问 github.com/aquasecurity/trivy-db insecure: false参数说明:
skip_update: true是离线部署的生命线。v2.5.0-rc1 的 Trivy adapter 启动时会默认拉取远程漏洞库(约 500MB),若网络不通,容器会持续重试直至超时退出,且日志只显示trivy-adapter exited with code 1,毫无线索。设为true后,它将使用./images/中内置的静态数据库。
3.3 步骤三:执行安装(带调试模式)
# 进入 Harbor 目录 cd /opt/harbor # 执行安装,-d 参数输出详细日志(关键!便于定位卡点) bash install.sh -d # 预期成功输出末尾应包含: # [Step 4]: starting Harbor ... # Creating network "harbor_harbor" with the default driver # Creating harbor-log ... done # Creating registry ... done # Creating harbor-db ... done # Creating redis ... done # Creating harbor-adminserver ... done # Creating harbor-core ... done # Creating harbor-portal ... done # Creating harbor-jobservice ... done # Creating trivy-adapter ... done # Creating notary-server ... done # Creating notary-signer ... done # ✔ ----Harbor has been installed and started successfully.----逻辑说明:
-d参数会打印每个容器的docker run命令及环境变量。若卡在某一步(如Creating registry ...),立即docker ps -a查看该容器状态,再docker logs harbor-registry获取原始错误。v2.5.0-rc1 的 registry 容器启动失败,90% 是因为harbor.yml中https.certificate路径错误或证书格式不合法。
3.4 步骤四:验证容器健康状态
安装完成后,执行三次检查:
# 1. 检查所有容器是否 UP 且无重启 docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "(harbor|registry|core)" # 2. 检查核心服务端口监听(v2.5.0-rc1 使用 443/80,非旧版 8080/4443) ss -tlnp | grep -E ':443|:80' # 3. 检查 Harbor 内部健康 API(需在宿主机执行) curl -k https://harbor.internal.local/api/v2.0/systeminfo # 成功返回 JSON:{"harbor_version":"v2.5.0-rc1","registry_version":"2.8.3-patch-01","...注意:
curl -k中的-k是必须的,因为自签名证书不被系统信任。若返回curl: (7) Failed to connect,说明 Nginx(harbor-portal)未监听 443;若返回curl: (56) Recv failure,说明harbor-core服务未就绪,需查docker logs harbor-core。
4. 常见问题排查:v2.5.0-rc1 独有的五个翻车现场
Harbor v2.5.0-rc1 因架构调整引入了若干「静默失败」场景:错误不报在控制台,只藏在某个容器日志里。以下是我在某跨平台系统部署中踩出的五条血路,按发生频率排序。
4.1 现象:install.sh执行到[Step 2]: preparing environment ...后停滞超过 5 分钟,无任何输出
原因:install.sh在渲染common/config/core/env模板时,尝试读取harbor.yml中https.certificate指向的文件。若路径不存在、权限不足(非 root 用户运行)、或证书文件为空,脚本会无限等待openssl x509 -in ...命令返回。
解决:
- 确认
/data/cert/harbor.crt和/data/cert/harbor.key存在且非空:ls -l /data/cert/ && head -n 1 /data/cert/harbor.crt - 确保运行
install.sh的用户对/data/cert/有读权限:chmod 644 /data/cert/*.crt /data/cert/*.key - 终极方案:临时注释
harbor.yml中https区块,先以 HTTP 模式安装成功,再补证书(需手动重启 nginx 容器)。
4.2 现象:docker ps显示harbor-registry容器状态为Exited (1),日志中反复出现level=error msg="error authorizing context: authorization token required"
原因:v2.5.0-rc1 的 registry 服务强制要求Authorization头,而harbor-core服务未正确生成或传递 token。根本原因是harbor.yml中hostname与https.certificate的 CN 不一致,导致core无法通过 HTTPS 调用registry的/service/token接口。
解决:
- 重新生成证书,确保
openssl req -subj中的CN=与harbor.yml的hostname完全相同(包括大小写和点号) - 删除旧证书:
rm -f /data/cert/harbor.*,再执行步骤 3.1 - 清理旧容器:
docker-compose down -v(在/opt/harbor目录下),再重装
4.3 现象:curl -k https://harbor.internal.local/api/v2.0/systeminfo返回{"code":401,"message":"Unauthorized"}
原因:harbor-core服务启动时,从数据库加载管理员密码失败。常见于database.password在harbor.yml中被注释、留空,或包含特殊字符(如@,$)未用单引号包裹。v2.5.0-rc1 的数据库连接字符串校验更严格。
解决:
- 检查
harbor.yml中database.password是否为明文且用单引号包裹:password: 'dbPassw0rd!2024' - 若密码含
$,必须用单引号,否则 Bash 会尝试变量替换(如$PASS变为空) - 进入数据库容器手动验证:
docker exec -it harbor-db psql -U postgres -c "SELECT * FROM harbor_user WHERE user_id = 1;",确认username为admin且salt字段非空
4.4 现象:docker login harbor.internal.local成功,但docker push harbor.internal.local/library/busybox报错unauthorized: authentication required
原因:v2.5.0-rc1 默认启用Notary(内容可信签名),但离线环境下notary-server容器因无法连接https://notary-server:7899(内部地址)而崩溃,导致core服务降级为只读模式。
解决:
- 编辑
harbor.yml,在notary区块下添加enabled: false:notary: enabled: false # 显式禁用,避免静默失败 - 重新运行
bash install.sh -d(无需down,脚本会自动重建)
4.5 现象:Trivy 扫描始终显示No vulnerabilities found,即使镜像明显存在 CVE
原因:skip_update: true生效后,Trivy 使用内置数据库,但 v2.5.0-rc1 的离线包中trivy-adapter镜像内置的是 2023 年 Q4 的数据库,已过期。
解决:
- 下载最新离线数据库(需在外网机器操作):
curl -L https://github.com/aquasecurity/trivy-db/releases/download/v1-2024040112/trivy-offline.db.tgz -o trivy-offline.db.tgz - 将
trivy-offline.db.tgz传入内网,解压到/opt/harbor/common/config/trivy-adapter/:tar -xzf trivy-offline.db.tgz -C /opt/harbor/common/config/trivy-adapter/ - 重启容器:
docker restart harbor-trivy-adapter
5. 首次登录与基础验证:用一条命令跑通整个流水线
安装完成不等于可用。v2.5.0-rc1 的核心价值在于「私有镜像全生命周期管理」,因此验证必须覆盖「推、扫、拉、删」四步闭环。以下是一套可在 3 分钟内完成的端到端测试,所有命令均在 Harbor 宿主机执行。
5.1 准备测试镜像:用最轻量的alpine:latest避免网络干扰
# 拉取一个确定存在的小镜像(不依赖外网 registry) docker pull alpine:latest # 打标签为 Harbor 仓库地址(注意:v2.5.0-rc1 要求仓库名必须为小写) docker tag alpine:latest harbor.internal.local/library/alpine-test:1.0 # 登录(用户名 admin,密码为你在 harbor.yml 中设置的 harbor_admin_password) echo "ChangeMe123!" | docker login harbor.internal.local --username admin --password-stdin逻辑说明:
library是 Harbor 内置的公共项目(project),无需额外创建。v2.5.0-rc1 对镜像名校验更严:harbor.internal.local/library/alpine-test中的library必须小写,若写成Library会返回repository name component must match "[a-z0-9]+(?:[._-][a-z0-9]+)*"错误。
5.2 推送与扫描:触发 Trivy 自动扫描
# 推送镜像(此时 Trivy adapter 会自动触发扫描) docker push harbor.internal.local/library/alpine-test:1.0 # 等待 10-20 秒,检查扫描状态(v2.5.0-rc1 的扫描结果存于数据库,API 返回 JSON) curl -k -u "admin:ChangeMe123!" \ "https://harbor.internal.local/api/v2.0/projects/library/repositories/alpine-test/artifacts/1.0/additions/vulnerabilities" # 成功返回类似:{"application/vnd.security.vulnerability.report; version=1.1":{"generated_at":"2024-04-05T02:15:22.123Z","artifact_digest":"sha256:...","summary":{"total":0,"fixable":0}}}注意:若返回
{"code":404,"message":"artifact not found"},说明推送未完成或镜像名不匹配。用curl -k -u "admin:ChangeMe123!" "https://harbor.internal.local/api/v2.0/projects/library/repositories"确认alpine-test是否出现在仓库列表中。
5.3 拉取与运行:验证镜像完整性
# 从 Harbor 拉取(强制指定 https) docker pull harbor.internal.local/library/alpine-test:1.0 # 运行一个简单命令验证镜像可执行 docker run --rm harbor.internal.local/library/alpine-test:1.0 apk --version # 应输出类似:2.14.0 # 查看镜像历史(确认来自 Harbor) docker image inspect harbor.internal.local/library/alpine-test:1.0 | jq -r '.[0].RepoTags' # 应输出:["harbor.internal.local/library/alpine-test:1.0"]5.4 删除与清理:测试权限与垃圾回收
# 删除镜像(v2.5.0-rc1 需要显式调用 API,CLI 不支持) curl -k -X DELETE -u "admin:ChangeMe123!" \ "https://harbor.internal.local/api/v2.0/projects/library/repositories/alpine-test/artifacts/sha256:$(docker images --digests harbor.internal.local/library/alpine-test:1.0 -q | cut -d'@' -f2)" # 触发垃圾回收(清理已删除镜像的文件层) curl -k -X POST -u "admin:ChangeMe123!" \ "https://harbor.internal.local/api/v2.0/system/gc/schedule" \ -H "Content-Type: application/json" \ -d '{"schedule":{"type":"Manual"}}' # 检查 GC 任务状态(返回 task_id) GC_TASK_ID=$(curl -k -u "admin:ChangeMe123!" "https://harbor.internal.local/api/v2.0/system/gc" | jq -r '.[0].job_id') # 轮询直到完成(最多 60 秒) for i in {1..12}; do STATUS=$(curl -k -u "admin:ChangeMe123!" "https://harbor.internal.local/api/v2.0/system/gc/${GC_TASK_ID}" | jq -r '.status') [[ "$STATUS" == "success" ]] && echo "GC completed" && break sleep 5 done逻辑说明:v2.5.0-rc1 的垃圾回收(GC)是异步任务,必须通过 API 触发并轮询状态。若跳过此步,磁盘空间不会释放,
docker system df仍显示大量 dangling 镜像。sha256:...部分通过docker images --digests获取,这是 Harbor v2.5+ 的标准做法,避免 tag 冲突。
从那以后我每次部署 Harbor,无论版本新旧,都强制走一遍这四步验证:推一个alpine、扫一次漏洞、拉一次运行、删一次 GC。不是为了炫技,而是因为 Harbor 的「静默失败」太擅长伪装成功——容器在跑,网页能打开,但镜像推不上去、扫描不触发、GC 不清理,这些坑往往要等到上线后第一周才爆发。把验证变成肌肉记忆,比背一百条参数更可靠。希望帮到你。
本文还有配套的精品资源,点击获取