2. Harbor 架构概览:核心组件与请求链路分析
在构建制品误差预算台账之前,必须深入理解 Harbor 的内部架构。Harbor 并非一个单体服务,而是由多个独立组件协同工作的分布式系统。本章将拆解其核心组件,并追踪一条完整的镜像拉取请求链路,为后续的延迟分析和门禁优化奠定基础。
2.1 核心组件全景
Harbor 2.x 版本由以下六大核心组件构成,每个组件承担明确的职责边界:
| 组件名称 | 核心职责 | 关键端口/协议 | 状态依赖 |
|---|---|---|---|
| Core | API 网关、认证鉴权、项目管理、Webhook、审计日志 | 8080 (HTTP), 8443 (HTTPS) | 依赖 DB、Redis、Registry |
| Registry | 镜像 Blob 与 Manifest 的存储与分发(Docker Distribution) | 5000 (HTTP) | 依赖存储后端(S3/NFS/MinIO) |
| Jobservice | 异步任务调度:GC、复制、扫描、回收、Webhook 投递 | 8080 (内部 RPC) | 依赖 Redis、Core |
| ChartMuseum | Helm Chart 的存储与版本管理(可选组件) | 9999 (HTTP) | 依赖存储后端 |
| Trivy / Clair | 镜像漏洞扫描引擎(Adapter 模式) | 8080 (gRPC/HTTP) | 依赖 Jobservice 调度 |
| Nginx / Proxy | 统一入口、TLS 终止、路由分发、限流 | 443 (HTTPS), 80 (HTTP) | 前置所有组件 |
架构要点:Core 是 Harbor 的"大脑",所有管理面请求(UI、CLI、API)都必须经过 Core。Registry 是"肌肉",负责数据面的吞吐。Jobservice 是"神经中枢",处理所有后台异步任务。理解这三者的关系是优化延迟的关键。
2.2 组件交互架构图
下图展示了 Harbor 各组件的逻辑分层与核心交互路径。注意 Proxy 作为统一入口,将管理面请求(/api/、/c/)路由至 Core,将数据面请求(/v2/)路由至 Registry。
2.3 镜像拉取请求链路深度分析
一次完整的 docker pull 操作,在 Harbor 内部会经历以下 7 个关键阶段。每个阶段都可能成为延迟瓶颈,也是我们建立误差预算台账的监控点。
- TLS 握手与路由分发:客户端向 Nginx Proxy 发起 HTTPS 请求,Proxy 根据请求路径前缀(
/v2/)将流量转发至 Registry。 - 认证(Bearer ):Registry 返回
401 Unauthorized,携带Www-Authenticate头指向 Core 的 服务。客户端向 Core 请求 ,Core 验证用户凭证并签发短期 。 - Manifest 拉取:客户端使用 向 Registry 请求镜像 Manifest(
GET /v2/<name>/manifests/<ref>)。Registry 从存储后端读取 Manifest 并返回。 - Blob 层列表解析:客户端解析 Manifest,获取所有 Layer Blob 的 Digest 列表。
- Blob 并发拉取:客户端并发向 Registry 发起
GET /v2/<name>/blobs/<digest>请求。Registry 从存储后端读取 Blob 数据流。 - 存储后端 I/O:Registry 与后端存储(S3、NFS、MinIO)交互,读取实际数据。此阶段是延迟的主要来源。
- 数据流返回:Registry 将 Blob 数据流式传输回客户端,客户端逐层解压并写入本地文件系统。
延迟关键洞察:在误差预算台账中,我们重点关注 阶段 5(Blob 并发拉取) 和 阶段 6(存储后端 I/O)。这两个阶段占据了总拉取延迟的 80% 以上。Registry 的
GET BLOB 响应时间(P99)是核心 SLO 指标。
2.4 请求链路时序图
下图以时序方式展示镜像拉取请求在 Harbor 组件间的完整交互过程,帮助理解每个步骤的依赖关系和延迟贡献。
2.5 质量门禁的架构切入点
基于上述架构和请求链路,我们可以识别出以下关键的质量门禁控制点:
| 门禁控制点 | 所在组件 | 拦截时机 | 典型策略 |
|---|---|---|---|
| 认证与授权 | Core ( 服务) | 步骤 ③-⑤ | RBAC、项目级别权限、机器人账户 |
| 漏洞扫描门禁 | Core + Jobservice + Trivy | Push 后 / Pull 前 | 阻断高危漏洞镜像的拉取或部署 |
| 签名验证门禁 | Core (Notation/Cosign) | Pull 时 | 仅允许拉取已签名的可信镜像 |
| 拉取速率限制 | Nginx Proxy / Registry | 步骤 ①-② | 基于 IP 或项目的 QPS 限流 |
| 制品保留策略 | Jobservice (GC) | 定时触发 | 按 tag 数量、时间、正则规则自动清理 |
架构陷阱提醒:不要将质量门禁逻辑全部塞入 Registry 组件。Registry 是纯数据面组件,应保持轻量和稳定。所有策略判断(认证、扫描、签名)应前置到 Core 或通过 Proxy 层拦截,避免增加 Registry 的请求处理延迟。
2.6 组件依赖与高可用设计
在生产环境中,Harbor 各组件的依赖关系决定了部署架构的容错能力:
- Core 无状态:可水平扩展,前端通过 Proxy 做负载均衡。所有会话状态存储在 Redis 中。
- Registry 无状态:可水平扩展,但需要共享同一存储后端。注意并发写入时的锁机制(S3 的强一致性 vs NFS 的 close-to-open 语义)。
- Jobservice 无状态:任务状态存储在 Redis 和 PostgreSQL 中,支持多副本部署。
- PostgreSQL 与 Redis:有状态组件,需要主从复制或集群模式保障高可用。这是 Harbor 架构中最脆弱的环节。
- 存储后端:有状态组件,建议使用 S3 兼容对象存储(MinIO、Ceph RGW)以获得更好的可用性和性能。
误差预算台账启示:在建立 SLO 时,需要为每个组件定义独立的延迟和错误率指标。例如:Core 的 签发延迟(P99 < 200ms)、Registry 的 Blob 读取延迟(P99 < 500ms)、存储后端的 I/O 延迟(P99 < 100ms)。组件级指标是定位故障根因的基础。