Harbor介绍、架构及工作流程说明
Harbor 是一个用于存储、签名和扫描内容的企业级容器镜像注册表项目。由 VMware 开发并于 2016 年开源。Harbor 提供了一些关键特性,使其成为企业使用的理想选择。
1. Harbor 介绍
1.1 什么是 Harbor
Harbor 是一个开源的云原生容器镜像仓库项目,旨在为企业级用户提供安全、可扩展、灵活的容器镜像管理解决方案。Harbor 提供了对镜像的管理、访问控制、镜像签名、安全扫描等功能,并且支持多种身份验证方式,可以与企业的 LDAP/AD 集成。
1.2 Harbor 的主要功能
- 基于角色的访问控制:通过基于角色的访问控制(RBAC)机制,可以对用户进行精细化的权限管理,确保镜像安全。
- 镜像复制:支持多种注册表之间的镜像复制,可以在多个 Harbor 实例或者其他 Docker 注册表之间复制镜像。
- 镜像签名和安全扫描:集成了 Notary 项目,可以对镜像进行签名,并通过 Clair 项目进行镜像漏洞扫描,确保镜像安全。
- 多租户支持:通过项目机制支持多租户,便于组织内部分不同团队独立管理自己的镜像仓库。
- 用户认证:支持多种用户认证方式,包括 LDAP、OIDC 等,可以与企业的用户认证系统集成。
- 审计日志:提供详细的操作日志,便于管理员审计和追踪用户操作。
2. Harbor 架构
从2.0 版本开始,Harbor 已经演变为一个完全符合 OCI 标准的云原生制品注册表。
符合 OCI 标准的云原生制品注册表意味着它现在支持 OCI 镜像和 OCI 镜像索引(https://github.com/opencontainers/image-spec/blob/master/image-index.md)。OCI 镜像索引是一种更高级别的清单,指向一个镜像清单列表,适用于一个或多个平台。例如,Docker 清单列表就是 OCI 镜像索引的一个流行实现。这也意味着 Harbor 现在完全支持多架构镜像。
通过 Harbor V2.0,用户可以管理符合 OCI 镜像规范的镜像、清单列表、Helm charts、CNABs、OPAs 等等。它还允许拉取、推送、删除、标记、复制和扫描这些类型的制品。现在也可以对镜像和清单列表进行签名。
下图展示了Harbor的架构总览:
如上图所示,Harbor 包含以下组件,并分布在三个层级中:
2.1 数据访问层
-
K-V 存储:由 Redis 组成,提供数据缓存功能,并支持为作业服务临时持久化作业元数据。
-
数据存储:支持多种存储方式作为注册表(registry)和 ChartMuseum 的后端存储,实现数据持久化。有关详细信息,请参阅 Docker 网站上的驱动列表文档和 ChartMuseum 的 GitHub 仓库。
-
数据库:存储 Harbor 模型的相关元数据,如项目、用户、角色、复制策略、标签保留策略、扫描器、chart 和镜像。Harbor 采用 PostgreSQL 作为数据库。
2.2 基础服务
2.2.1 Proxy(代理)
由 Nginx 服务器组成的反向代理,提供 API 路由功能。Harbor 的组件(如核心服务、注册表、Web 门户和令牌服务等)都位于此反向代理之后。代理将来自浏览器和 Docker 客户端的请求转发到各种后端服务。
2.2.2 核心服务
Harbor 的核心服务,主要提供以下功能:
-
API 服务器:一个接受 REST API 请求的 HTTP 服务器,依赖于其子模块(如"认证与授权"、"中间件"和"API 处理程序")响应这些请求。
-
认证与授权:
- 请求由认证服务保护,认证服务可以由本地数据库、AD/LDAP 或 OIDC 提供。
- 启用 RBAC 机制,对相关操作执行授权,例如:拉取/推送镜像。
- 令牌服务旨在根据用户在项目中的角色,为每个 Docker 推送/拉取命令颁发令牌。如果从 Docker 客户端发送的请求中没有令牌,注册表将把请求重定向到令牌服务。
-
中间件:预处理某些请求,以确定它们是否符合要求并可以传递给后端组件进行进一步处理。某些功能作为中间件实现,如"配额管理"、"签名检查"、"漏洞严重性检查"和"机器人账户解析"等。
-
API 处理程序:处理相应的 REST API 请求,主要关注解析和验证请求参数,在相关 API 控制器上完成业务逻辑,并写回生成的响应。
-
-
配置管理器:涵盖所有系统配置的管理,如认证类型设置、邮件设置和证书等。
-
项目管理:管理项目的基础数据和相应的元数据,用于隔离管理的制品。
-
配额管理器:管理项目的配额设置,并在发生新的推送时执行配额验证。
-
Chart 控制器:将与 Chart 相关的请求代理到后端的 ChartMuseum,并提供若干扩展以改善 Chart 管理体验。
-
保留管理器:管理标签保留策略,执行并监控标签保留过程。
-
内容信任:在后端 Notary 提供的信任功能上添加扩展,以支持平滑的内容信任过程。目前仅支持容器镜像签名。
-
复制控制器:管理复制策略和注册表适配器,触发并监控并发复制过程。许多注册表适配器已经实现:
- Distribution (Docker 注册表)
- Docker Hub
- 华为 SWR
- 亚马逊 ECR
- 谷歌 GCR
- Azure ACR
- 阿里 ACR
- Helm Hub
- Quay
- Artifactory
- GitLab Registry
-
扫描管理器:管理由不同提供商适配的多个配置扫描器,还提供指定制品的扫描摘要和报告。目前支持的扫描器包括:
-
Aqua Security 提供的 Trivy 扫描器;Anchore 提供的 Anchore Engine 扫描器;由 CentOS (Redhat) 赞助的 Clair 扫描器;DoSec 提供的 DoSec 扫描器
-
目前,仅支持对基于镜像的容器镜像或 bundle(如清单列表/OCI 索引或 CNAB bundle)进行扫描。
-
-
通知管理器(Webhook):Harbor 中配置的一种机制,可以将 Harbor 中制品(artifact)状态的变化传播到在 Harbor 中配置的 Webhook 端点。第三方可以通过监听相关的 Webhook 事件来触发一些后续操作。目前支持两种方式:
- HTTP Post 请求
- Slack 频道
-
OCI 制品管理器:管理整个 Harbor 注册表中所有 OCI 制品生命周期的核心组件。它提供了管理制品元数据及相关附加内容(如扫描报告、容器镜像的构建历史和 readme、helm charts 的 dependencies 和 value.yaml 等)的 CRUD 操作,还支持管理制品标签和其他有用的操作。
-
注册表驱动:实现为注册表客户端 SDK,与底层注册表(目前为 Docker Distribution)进行通信。"OCI 制品管理器"依赖此驱动从位于底层注册表的指定制品中获取附加信息(如清单甚至配置 JSON)。
2.2.3 作业服务
通用作业执行队列服务,允许其他组件/服务通过简单的 RESTful API 提交并发执行异步任务的请求。
2.2.4 日志收集器
日志收集器,负责将其他模块的日志收集到一个地方。
2.2.5 GC 控制器
管理在线垃圾回收(GC)计划设置,并启动和跟踪 GC 进度。
2.2.6 Chart Museum
第三方 Chart 仓库服务器,提供 Chart 管理和访问 API。了解更多详细信息,请点击 这里。
2.2.7 Docker Registry
第三方注册表服务器,负责存储 Docker 镜像并处理 Docker 推送/拉取命令。由于 Harbor 需要对镜像强制执行访问控制,注册表会将客户端重定向到令牌服务,以获取每个拉取或推送请求的有效令牌。
2.2.8 Notary
第三方内容信任服务器,负责安全发布和验证内容。了解更多详细信息,请点击 这里。
2.3 消费者
作为一个标准的云原生制品注册表(artifact registry),相关的客户端自然会得到支持,例如 Docker CLI、Notary 客户端、兼容 OCI 的客户端(如 Oras)和 Helm。除了这些客户端,Harbor 还提供了一个 Web 门户,便于管理员轻松管理和监控所有制品。
Web 门户:一个图形用户界面,帮助用户管理注册表中的镜像。
3. 工作流程
3.1 docker登录过程
假设 Harbor 部署在 IP 为 192.168.1.10 的主机上。用户运行以下 Docker 命令向 Harbor 发送登录请求:
bash
docker login 192.168.1.10
用户输入所需的凭据后,Docker 客户端向地址"192.168.1.10/v2/"发送一个 HTTP GET 请求。Harbor 的不同容器将按照以下步骤处理该请求:
(a) 首先,代理容器(监听端口 80)接收到该请求。容器中的 Nginx 将请求转发到后端的 Registry 容器。
(b) Registry 容器已配置为基于令牌的认证,因此返回错误代码 401,通知 Docker 客户端从指定的 URL 获取有效的令牌。在 Harbor 中,该 URL 指向核心服务的令牌服务。
© 当 Docker 客户端接收到该错误代码后,它向令牌服务 URL 发送请求,将用户名和密码嵌入到请求头中,按照 HTTP 规范的基本认证进行操作。
(d) 该请求通过端口 80 发送到代理容器后,Nginx 根据预配置的规则再次将请求转发到 UI 容器。UI 容器中的令牌服务接收到请求,解码请求并获取用户名和密码。
(e) 获取到用户名和密码后,令牌服务检查数据库,并通过 MySQL 数据库中的数据进行用户认证。当令牌服务配置为 LDAP/AD 认证时,它会对外部 LDAP/AD 服务器进行认证。认证成功后,令牌服务返回一个表示成功的 HTTP 代码。HTTP 响应体中包含由私钥生成的令牌。
此时,一个 Docker 登录过程已完成。Docker 客户端将步骤 © 中的经过编码的用户名/密码保存到本地的一个隐藏文件中。
3.2 docker推送镜像过程
(我们省略了代理转发步骤。上图展示了 Docker 推送过程中文件各组件之间的通信。)
用户成功登录后,Docker 镜像通过 Docker Push 命令发送到 Harbor:
bash
docker push 192.168.1.10/library/hello-world
(a) 首先,Docker 客户端通过向注册表(registry)发送请求,重复类似于登录的过程,然后获取令牌服务的 URL;
(b) 随后,当联系令牌服务时,Docker 客户端提供额外的信息以申请推送操作镜像(library/hello-world)的令牌;
(c) 在接收到 Nginx 转发的请求后,令牌服务查询数据库以查找用户的角色和推送镜像的权限。如果用户具有适当的权限,令牌服务会对推送操作的信息进行编码,并使用私钥对其签名,生成令牌返回给 Docker 客户端;
(d) Docker 客户端获取到令牌后,发送带有令牌的推送请求到注册表。注册表接收到请求后,使用公钥解码令牌并验证其内容。公钥与令牌服务的私钥相对应。如果注册表发现令牌对推送镜像有效,则开始镜像传输过程。