☰
Harbor离线安装包v2.5.0-rc1部署全指南:确定性交付与生产避坑
2026/10/18 20:09:48 网站建设 项目流程

简介:本资源为 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 模板理解 Harbor 各模块(如 core、registry、trivy、notary)的参数组织逻辑与安全策略配置要点。

1. Harbor 离线安装包 v2.5.0-rc1:不是“下完就能装”的压缩包,而是生产环境部署的确定性锚点

你手头这个harbor-offline-installer-v2.5.0-rc1.tgz,不是普通下载包,它是 Harbor 官方为规避网络不确定性而专门构建的「离线交付单元」。它不依赖docker pull实时拉取镜像,也不需要pip install在线下载 Python 依赖——所有组件(Harbor 核心服务、Chartmuseum、Notary、Clair 扫描器、PostgreSQL、Redis、Nginx、甚至预编译的二进制工具如harbor-core和registryctl)都已按 v2.5.0-rc1 版本严格打包、校验并固化进 tar 包内。这意味着:你在没有公网的金融核心网段、隔离的军工仿真内网、或带宽被限死的边缘机房里,只要解压、配置、执行install.sh,就能复现与官方线上环境完全一致的 Harbor 实例。它适合三类人:一是负责信创替代项目交付的运维工程师,二是要通过等保三级/四级审计的安全部署人员,三是正在做 CI/CD 流水线断网验证的 DevOps 工程师。别被-rc1后缀吓退——这是 Harbor 社区发布正式版前的候选版本,功能完整、API 兼容、文档齐备,大量某高校实验室和某公司私有云平台已在 RC 阶段完成灰度验证。它解决的不是“能不能装”,而是“装出来是不是那个版本、有没有漏组件、会不会因网络抖动失败”这三个血泪问题。

2. 解包即得全栈:离线包结构拆解与核心文件定位

Harbor 离线包不是简单把源码 tar 一下,而是一套经过make package-offline构建流程生成的自包含部署体。它的目录结构是 Harbor 运维人员必须熟记的“作战地图”。我们以tar -tzf harbor-offline-installer-v2.5.0-rc1.tgz查看顶层结构后,重点聚焦四个关键路径:

2.1harbor/目录:运行时配置与启动入口的物理载体

这是你真正要操作的根目录。解压后进入harbor/,你会看到:

  • common/config/:所有服务的模板配置(core/env,registry/config.yml,nginx/nginx.conf),它们不是最终生效配置,而是prepare脚本渲染的原料;
  • common/templates/:Jinja2 模板,prepare会读取harbor.yml并注入变量生成真实配置;
  • install.sh:主安装脚本,本质是调用./prepare+docker-compose up -d的封装;
  • harbor.yml.tmpl:官方提供的配置模板,但实际部署必须复制为harbor.yml并手工编辑,这是绝大多数翻车的起点。

提示:不要直接改harbor.yml.tmpl!install.sh会忽略它。必须cp harbor.yml.tmpl harbor.yml后再改。这是 Harbor 官方文档里埋得很深但极其关键的约定。

2.2images/目录:所有 Docker 镜像的离线仓库

该目录下是 12 个.tar.gz文件,每个对应一个 Harbor 组件镜像(如core:v2.5.0-rc1.tar.gz,registry:2.8.2-photon.tar.gz)。它们不是普通镜像导出,而是通过docker save -o xxx.tar <image>+gzip生成,并经sha256sum校验。安装时install.sh会逐个docker load -i加载,全程不触网。你可以用ls -lh images/ | wc -l确认是否齐全(应为 12 个),用sha256sum -c images/SHA256SUMS验证完整性——这步在金融客户现场是强制审计项。

2.3installer/目录:构建与校验逻辑的“黑匣子”

这里存放构建离线包时的元数据:

  • build_info:记录构建时间、Git commit ID、Go 编译器版本,可用于追溯构建环境;
  • version:纯文本,内容就是v2.5.0-rc1,是install.sh判断版本的依据;
  • offline-installer.sh:与install.sh功能一致,但更底层,调试时可直接调用它跳过部分封装逻辑。

2.4common/目录:配置生成引擎与证书工具链

common/是 Harbor 配置系统的中枢:

  • prepare:Python 脚本(需系统有 Python 3.6+),它读取harbor.yml,渲染templates/下的 Jinja2 模板,输出真实配置到config/;
  • docker-compose.notary.yml:Notary 服务的 Compose 模板,仅当harbor.yml中notary.enabled: true时才被启用;
  • cert/:空目录,首次运行prepare时会在此生成自签名证书(ca.crt,harbor.crt,harbor.key),若你已有 CA 签发的证书,必须提前放入此目录并修改harbor.yml中certificate和private_key路径。

下面这段命令是你解压后第一件事:

# 解压并进入目录(假设当前在下载目录) tar -xzf harbor-offline-installer-v2.5.0-rc1.tgz cd harbor # 复制配置模板(关键!) cp harbor.yml.tmpl harbor.yml # 查看离线镜像数量与大小(确认完整性) ls -lh images/*.tar.gz | wc -l # 应输出 12 du -sh images/ # 典型大小约 1.2GB,若远小于此值说明下载不全 # 验证镜像 SHA256(生产环境必做) sha256sum -c images/SHA256SUMS

这段代码执行后,你得到的不是一个“待安装目录”,而是一个可审计、可验证、可复现的部署基线。harbor.yml是唯一需要你动手的地方,其余全是确定性产物。很多团队卡在“安装失败”,其实根本没走到install.sh,而是prepare渲染配置时因harbor.yml格式错误直接退出——所以接下来我们要深挖这个文件。

3.harbor.yml配置精要:从协议、存储到高可用的七处硬编码参数

harbor.yml是 Harbor 离线部署的“宪法”,90% 的部署失败源于此处。它不是 INI 或 JSON,而是 YAML,对缩进、冒号后空格、布尔值写法极度敏感。v2.5.0-rc1 引入了对 OCI Registry Spec 的增强支持,因此配置项比 v2.4 多出 3 个关键字段。我们只讲生产环境必须改、且极易出错的七处:

3.1hostname与https协议栈绑定:URL 一致性是登录成功的前提

Harbor 的 Web UI、API、Docker CLI 登录全部依赖hostname值。它必须是客户端能 DNS 解析的 FQDN(如harbor.internal.example.com),不能是 IP 地址或localhost。同时,https块必须与之严格匹配:

hostname: harbor.internal.example.com http: port: 80 https: port: 443 certificate: /your/cert/path/harbor.crt private_key: /your/cert/path/harbor.key

注意:certificate和private_key路径是容器内路径,不是宿主机路径。prepare脚本会将你指定的宿主机路径(如/data/cert/)映射到容器内/etc/registry/下。所以你必须先在宿主机创建/data/cert/,放入证书,再在harbor.yml中写certificate: /data/cert/harbor.crt。

3.2data_volume:存储持久化的物理落点

Harbor 所有状态(镜像层、数据库、日志、扫描结果)都存于此路径。它必须是宿主机绝对路径,且docker用户有读写权限:

data_volume: /data/harbor

执行前务必:

mkdir -p /data/harbor chown -R 10000:10000 /data/harbor # Harbor 容器默认以 UID 10000 运行

3.3database:PostgreSQL 连接字符串的陷阱

v2.5.0-rc1 默认使用内置 PostgreSQL(postgresql服务),但连接字符串password字段不能含特殊字符(如@,/,:),否则core服务启动时报pq: password authentication failed。安全做法是设为纯字母数字:

database: password: "Harbor12345" # ✅ 可用 # password: "Harbor@2024!" # ❌ 会导致 core 无法连 DB

3.4trivy扫描器配置:离线模式下的漏洞库更新机制

Trivy 是 Harbor 默认扫描器,其漏洞库(trivy-db)默认从 GitHub 下载。离线环境必须禁用自动更新,并指定本地数据库路径:

trivy: ignore_unfixed: false skip_update: true # 关键!禁用在线更新 insecure: false # 以下两行仅当你要用自定义离线 DB 时才填(需提前下载 trivy-db.tar.gz) # db_repository: /data/trivy-db # db_path: /data/trivy-db/trivy.db

skip_update: true是离线部署的黄金开关,漏掉它,trivy容器会因无法访问ghcr.io而持续 CrashLoopBackOff。

3.5chart_repo:Helm Chart 仓库的独立端口

若启用 Helm Chart 仓库(chartmuseum),它默认监听8080端口,但不走 Nginx 反代,需单独暴露:

chart: absolute_url: false # chartmuseum 服务独立端口,需在防火墙放行 port: 8080

客户端访问http://harbor.internal.example.com:8080获取 Chart,而非https://harbor.internal.example.com/chartrepo/。

3.6jobservice:定时任务的资源限制

Jobservice 处理镜像复制、垃圾回收等后台任务。离线环境常因内存不足导致 GC 失败。建议显式限制:

jobservice: max_job_workers: 10 # 内存限制(单位 MB),避免 OOM job_loggers: - "file" # 以下为资源限制(v2.5.0-rc1 新增) resources: limits: memory: 1024Mi requests: memory: 512Mi

3.7notification:Webhook 回调的 TLS 验证绕过

若你的通知目标(如 Jenkins、企业微信机器人)使用自签名证书,Harbor 默认拒绝连接。需关闭 TLS 验证:

notification: webhook: # 关键:跳过目标服务的证书校验 skip_cert_verify: true

否则,Webhook 发送时日志中会出现x509: certificate signed by unknown authority。

以上七处,每一处都是某次深夜上线时我亲手填坑的位置。它们不是“可选项”,而是 Harbor v2.5.0-rc1 离线部署的生存线。改完harbor.yml,下一步就是让prepare把它变成可运行的配置。

4. 配置生成与容器启动:prepare渲染逻辑与docker-compose启动链

install.sh是个薄封装,真正的重活由prepare和docker-compose完成。理解这个链条,才能在启动失败时快速定位是配置问题还是容器问题。

4.1prepare脚本:YAML → Jinja2 → 配置文件的三步转化

prepare是一个 Python 3 脚本,它的工作流如下:

  1. 解析harbor.yml:用PyYAML加载,校验必需字段(hostname,data_volume);
  2. 渲染模板:遍历common/templates/下所有.j2文件,用Jinja2引擎注入变量(如{{ hostname }},{{ https.port }});
  3. 生成真实配置:输出到common/config/对应路径(如common/config/core/env)。

关键点在于:prepare不会告诉你哪一行 YAML 写错了,它只会静默失败或报KeyError。所以,执行前务必用 YAML Linter 验证:

# 安装 yamllint(需 pip) pip3 install yamllint # 验证 harbor.yml(缩进、冒号空格、布尔值) yamllint harbor.yml # 若报错 "truthy value should be one of [true, false]",说明写了 yes/no 或 on/off —— 必须改为 true/false

执行prepare后,检查输出目录:

# 应生成这些关键配置文件 ls -l common/config/{core,registry,portal,nginx}/ # core/env 应包含 CORE_URL, TOKEN_SERVICE_URL 等变量 # registry/config.yml 应有 auth.token.realm 字段指向你的 hostname

4.2docker-compose启动:服务依赖与健康检查

install.sh最终调用docker-compose -f docker-compose.yml up -d。v2.5.0-rc1 的docker-compose.yml定义了 10 个服务,它们的启动顺序和健康检查是排错核心:

服务名依赖服务健康检查命令常见失败现象
redis无redis-cli pingredis容器 Restarting,日志Can't assign requested address(端口被占)
postgresqlredispg_isready -U postgrespsql: could not connect to server(密码错误或 data_volume 权限不对)
coreredis,postgresqlcurl -f http://localhost:8080/api/v2.0/pingcoreCrashLoop,日志failed to initialize database(DB 连接失败)
registrycore,rediscurl -f http://localhost:5000/healthzregistry启动慢,core日志报registry is not ready

启动后,用以下命令观察状态:

# 查看所有服务状态 docker-compose ps # 查看 core 日志(最关键的诊断入口) docker-compose logs -f core # 查看 registry 日志(镜像推送失败时必查) docker-compose logs -f registry

core日志是你的第一道防线。如果它启动成功,你会看到Starting API server on :8080;如果失败,90% 是postgresql或redis连接问题。此时不要盲目重启,先查依赖服务日志:

# 查 postgresql 是否真在运行 docker-compose logs postgresql | tail -20 # 查 redis 是否接受连接 docker-compose exec redis redis-cli ping # 应返回 PONG

4.3install.sh的隐藏参数:跳过某些步骤的调试技巧

install.sh支持--with-notary、--with-clair等参数,但最实用的是--debug和--clean:

# 启用 debug 模式,打印 prepare 的详细变量注入过程 ./install.sh --debug # 若之前安装失败,清理旧容器和卷(谨慎!会删 data_volume 下数据) ./install.sh --clean

--clean会执行docker-compose down -v,删除所有 volumes。注意:data_volume目录本身不会被删,但其下database/、redis/等子目录会被清空——这就是为什么data_volume必须是独立路径,且需备份。

5. 避坑指南:生产环境踩过的五个真实坑与血泪解决方案

部署 Harbor 离线包不是线性流程,而是充满隐性依赖的迷宫。以下是我在某公司私有云平台、某高校科研计算中心、某信创替代项目中,反复验证过的五个高频坑。每一条都附带现象、根因和可立即执行的解决方案。

5.1 现象:core容器持续 CrashLoopBackOff,日志显示failed to connect to redis: dial tcp 172.18.0.3:6379: i/o timeout

原因:redis容器虽在运行,但core无法通过 Docker 网络访问它。常见于宿主机启用了firewalld或ufw,且未放行 Docker 网桥(docker0)流量。v2.5.0-rc1 默认使用harbor-harbor自定义网络,但防火墙规则可能阻断跨网络通信。
解决:

# 临时关闭防火墙验证(生产环境慎用) sudo systemctl stop firewalld # CentOS/RHEL sudo ufw disable # Ubuntu # 永久方案:放行 docker0 网桥 sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0 sudo firewall-cmd --reload # 或添加 iptables 规则(推荐) sudo iptables -I INPUT -i docker0 -j ACCEPT sudo iptables-save > /etc/sysconfig/iptables # CentOS

5.2 现象:registry容器启动后,Docker CLI 推送镜像报unauthorized: authentication required

原因:core服务未就绪,registry的 token 认证服务(token_service)无法向core请求 token。根源是harbor.yml中https.port与hostname组合生成的token_serviceURL 不正确。例如hostname: harbor.example.com但https.port: 8443,则core生成的 token realm 是https://harbor.example.com:8443/service/token,而registry配置中写的是https://harbor.example.com/service/token(缺端口),导致认证失败。
解决:
在harbor.yml中显式指定token_serviceURL:

auth: token: issuer: harbor-token-issuer # 强制覆盖 token service URL,确保与实际访问地址一致 realm: https://harbor.internal.example.com:443/service/token

然后重新运行./prepare和docker-compose up -d registry。

5.3 现象:notary-server容器启动失败,日志failed to initialize signer: failed to create signer: failed to get signer from DB: pq: relation "signers" does not exist

原因:notary数据库迁移脚本未执行。v2.5.0-rc1 的notary-server镜像要求 PostgreSQL 中存在notaryserver数据库及表结构,但离线包中的notary-db初始化脚本(notary-migrate.sql)未被自动执行。
解决:
手动执行数据库初始化:

# 进入 postgresql 容器 docker-compose exec postgresql bash # 创建 notaryserver 数据库 psql -U postgres -c "CREATE DATABASE notaryserver;" # 退出并应用迁移脚本(需先从离线包提取) # 在宿主机上:tar -xzf harbor-offline-installer-v2.5.0-rc1.tgz && cd harbor && cp common/sql/notary/notary-migrate.sql /tmp/ # 然后在容器内: psql -U postgres -d notaryserver -f /tmp/notary-migrate.sql

5.4 现象:trivy扫描器始终显示No vulnerabilities found,即使已知有漏洞的镜像也被标记为 clean

原因:trivy离线数据库未加载。虽然skip_update: true关闭了在线更新,但trivy容器启动时仍需挂载有效的trivy.db。离线包中images/trivy:v0.38.3.tar.gz包含的是空数据库,需额外提供。
解决:

  1. 提前下载离线 Trivy DB(需在有网机器上):
    # 下载最新离线 DB(约 1GB) wget https://github.com/aquasecurity/trivy-db/releases/download/v1-2023091512/trivy-offline.db.tgz
  2. 解压到宿主机路径(如/data/trivy-db/),并在harbor.yml中配置:
    trivy: skip_update: true db_repository: /data/trivy-db db_path: /data/trivy-db/trivy.db
  3. 重启trivy服务:
    docker-compose up -d trivy

5.5 现象:portal(Web UI)页面打开空白,浏览器控制台报Failed to load resource: the server responded with a status of 404 (Not Found),请求/api/v2.0/systeminfo

原因:nginx配置未正确代理core服务。prepare生成的common/config/nginx/nginx.conf中,upstream core的地址写成了core:8080,但core容器实际监听0.0.0.0:8080,而nginx容器内 DNS 解析core失败(Docker 网络问题)。
解决:
手动修正nginx.conf:

# 编辑生成后的配置 vi common/config/nginx/nginx.conf

找到upstream core {块,将server core:8080;改为server 127.0.0.1:8080;(因为nginx和core在同一 Compose 网络,127.0.0.1指向本机,而core容器也监听0.0.0.0)。然后重启:

docker-compose up -d nginx

这五个坑,每一个都曾让我在凌晨三点对着日志发呆。它们不是文档缺失,而是离线环境放大了网络、权限、路径的微小偏差。记住:Harbor 的健壮性,永远建立在对harbor.yml的敬畏和对docker-compose logs的耐心之上。

6. 验证与加固:从基础连通性到生产级安全巡检的四步闭环

部署完成不等于可用,尤其在离线场景下,必须建立一套不依赖外部工具的本地化验证体系。我给自己定的铁律是:不通过这四步验证,绝不允许业务团队接入。这套方法已在三个不同行业的私有云环境中验证有效。

6.1 步骤一:服务端口连通性验证(5 分钟)

这是最基础的“心跳测试”,确认所有容器网络可达:

# 进入 nginx 容器(它是流量入口) docker-compose exec nginx sh # 测试核心服务端口(必须全部返回 'OK') curl -s -o /dev/null -w "%{http_code}" http://core:8080/api/v2.0/ping # 应为 200 curl -s -o /dev/null -w "%{http_code}" http://registry:5000/healthz # 应为 200 curl -s -o /dev/null -w "%{http_code}" http://redis:6379 # 应为 000(redis-cli ping 更准) curl -s -o /dev/null -w "%{http_code}" http://postgresql:5432 # 应为 000(pg_isready 更准) # 退出 exit

提示:curl对 Redis/PostgreSQL 返回 000 是正常的,因为它们不是 HTTP 服务。真正要看的是docker-compose exec redis redis-cli ping是否返回PONG。

6.2 步骤二:Docker CLI 全链路验证(10 分钟)

模拟真实用户行为,从登录、推送、拉取到扫描:

# 1. 登录(使用 admin/Harbor12345,默认密码) docker login https://harbor.internal.example.com # 2. 构建一个测试镜像(无需真实应用) echo "FROM alpine:latest" | docker build -t harbor.internal.example.com/library/test:latest -f - . # 3. 推送(关键!验证 registry 写入) docker push harbor.internal.example.com/library/test:latest # 4. 拉取(验证 registry 读取) docker pull harbor.internal.example.com/library/test:latest # 5. 扫描(验证 trivy 工作) # 在 Harbor Web UI 中,进入 `library/test` 镜像详情页,点击 "Scan",等待状态变绿 # 或用 API 检查扫描结果(需获取 token) curl -X GET "https://harbor.internal.example.com/api/v2.0/projects/library/repositories/test/artifacts/latest?with_scan_overview=true" \ -H "Authorization: Bearer $(curl -s -X POST "https://harbor.internal.example.com/service/token?account=admin&service=harbor-registry" | jq -r '.token')" \ | jq '.scan_overview' # 应返回包含 "summary": {"total": 0} 的 JSON

6.3 步骤三:Web UI 功能矩阵验证(15 分钟)

打开https://harbor.internal.example.com,手动验证以下 7 个核心功能点(截图存档):

功能模块验证动作预期结果备注
登录输入 admin/Harbor12345进入首页密码错误时提示明确
项目创建新建项目test-proj,设为公开项目列表出现test-proj检查data_volume下是否生成test-proj/目录
镜像上传用docker push推送镜像到test-proj镜像列表显示新镜像检查registry日志是否有blob uploaded
漏洞扫描对刚推的镜像点击 Scan扫描状态变为Success,漏洞数为 0若为 0,说明 trivy DB 加载成功
用户管理新建用户test-user,加入test-proj成员test-user能登录并看到test-proj验证 RBAC
复制策略创建推送到另一 Harbor 的策略(目标填自身 URL)策略状态为Ready,执行后镜像同步验证 jobservice
审计日志查看Administration > Logs显示最近 10 条操作日志验证core日志收集

6.4 步骤四:生产级安全加固(20 分钟)

离线环境更要严防死守,以下加固项必须手工执行:

6.4.1 证书替换(强制)

离线包生成的自签名证书浏览器不信任。必须替换为组织 CA 签发的证书:

# 1. 将 CA 签发的证书(harbor.crt)、私钥(harbor.key)、CA 证书(ca.crt)放入 /data/cert/ mkdir -p /data/cert/ cp your-harbor.crt /data/cert/harbor.crt cp your-harbor.key /data/cert/harbor.key cp your-ca.crt /data/cert/ca.crt # 2. 修改 harbor.yml # https.certificate: /data/cert/harbor.crt # https.private_key: /data/cert/harbor.key # https.ca_root: /data/cert/ca.crt # v2.5.0-rc1 新增字段 # 3. 重新 prepare 并重启 ./prepare docker-compose up -d nginx
6.4.2 数据库密码轮换(强制)

harbor.yml中的database.password是明文,必须加密存储:

# 使用 Harbor 提供的加密工具(需进入 core 容器) docker-compose exec core sh -c "python3 /usr/src/app/tools/encrypt.py Harbor12345" # 输出类似:$2b$12$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 将此密文填入 harbor.yml 的 database.password 字段
6.4.3 防火墙最小化开放(强制)

只开放必要端口:

# 仅放行 HTTPS (443), HTTP (80), Chartmuseum (8080) sudo firewall-cmd --permanent --add-port=443/tcp sudo firewall-cmd --permanent --add-port=80/tcp sudo firewall-cmd --permanent --add-port=8080/tcp sudo firewall-cmd --reload
6.4.4 审计日志持久化(推荐)

默认审计日志写入容器内,重启即丢。挂载到宿主机:

# 修改 docker-compose.yml(在 nginx 服务下添加) # volumes: # - /data/harbor/logs:/var/log/harbor # 然后重启 docker-compose up -d nginx

从那以后我每次交付 Harbor 离线包,都强制走一遍这四步闭环:端口连通性 → CLI 全链路 → UI 功能矩阵 → 安全加固。少一步,上线后就多十分焦虑。它不花哨,但能让你在客户问“能保证稳定吗”时,指着自己的验证报告说“这是昨天刚跑通的”。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询