关注【云原生百宝箱】公众号,获取更多云原生消息
“Harbor ”这个名字本身就与容器镜像有关。Harbor 是容器镜像装卸的场所。而且,“Harbor ”简单易读、易记,是项目推广的有力选择。
历史
Harbor 是 CNCF 毕业项目,它提供合规性、性能和互操作性,帮助你跨 K8s 等云原生计算平台一致、安全地管理工件。
Harbor 是开源的,并且纯粹是云原生的。
由 VMware 创建,并于 2018 年 7 月 31 日加入 CNCF。它通过添加用户通常需要的功能(例如安全性、身份和管理)来扩展开源 Docker 发行版,并支持在镜像仓库之间复制映像。
经过多年的发展,Harbor 已成为一个完整的 OCI 兼容的云原生工件镜像仓库。这意味着Harbor现在支持OCI(开放容器计划)镜像和OCI镜像索引。
使用 Harbor v2.0,用户可以管理镜像、manifest 列表、Helm 图表、CNAB、OPA 等,这些都遵守 OCI 镜像规范。它还允许拉、推、删除、标记、复制和扫描此类工件。
为什么选择Harbor
你可能会问既然我们已经有了 Docker 镜像仓库为什么还需要 Harbor 呢?嗯,Harbor 是 Docker 镜像仓库的企业级扩展,用途更广泛。这些新的企业级功能包括:
- • 管理用户界面
- • 基于角色的访问控制
- • AD/LDAP 集成
- • 审计日志记录
另外,Harbor 是云原生的,它不仅存储镜像,还可以扫描其内容是否存在安全问题。Harbor 还允许开发人员使用个人密钥对推送到镜像仓库的镜像进行签名,从而将镜像标记为可信。
基于Helm部署Harbor
Harbor 的大部分组件现在都是无状态的。所以可以简单的增加 Pod 的副本,确保组件分布到多个 Worker 节点,并利用 K8S 的 Service 机制来保证 Pod 之间的连通性。
部署openebs 持久存储
harbor默认启用了数据持久化,依赖默认存储类提供pv卷,这里使用openebs:
helm repo add openebs https://openebs.github.io/charts helm repo update helm install openebs openebs/openebs --namespace openebs --create-namespace
安装完成后,你可以使用以下命令查看安装状态:
kubectl get pods -n openebs
这将显示在 openebs 命名空间中运行的所有 OpenEBS Pod。
设置openebs-hostpath
为默认storageclass
kubectl patch storageclass openebs-hostpath -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
部署ingress nginx 控制器
harbor 默认使用 ingress 方式暴露服务,依赖ingress控制器,这里使用ingress-nginx:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx --create-namespace \ --set controller.service.type=NodePort
获取ingress nginx 控制器的nodeport
$ kubectl -n ingress-nginx get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.105.128.206 <none> 80:31720/TCP,443:30649/TCP 64m ingress-nginx-controller-admission ClusterIP 10.97.5.201 <none> 443/TCP 150m
部署 Harbor 镜像仓库
添加harbor helm仓库
helm repo add harbor https://helm.goharbor.io
Ingress方式暴露服务
部署harbor仓库,ingress-nginx使用nodeport方式暴露自身,需要在externalURL中配置其 NodePort 端口号。
helm upgrade --install harbor harbor/harbor --namespace harbor --create-namespace \ --set expose.type=ingress \ --set expose.ingress.className=nginx \ --set expose.ingress.hosts.core=core.harbor.domain \ --set expose.ingress.hosts.notary=notary.harbor.domain \ --set externalURL=https://core.harbor.domain:30649 \ --set harborAdminPassword="Harbor12345"
浏览器访问harbor管理界面,如果没有DNS解析,注意将192.168.172.128 core.harbor.domain
加入本地hosts文件中,其中192.168.172.128 为kubernetes集群任意节点IP地址。
NodePort方式暴露服务
helm 部署harbor仓库,使用nodePort方式暴露服务,无需部署ingress-nginx控制器:
export node_ip=192.168.172.128 helm upgrade --install harbor harbor/harbor --namespace harbor --create-namespace \ --set expose.type=nodePort \ --set expose.tls.auto.commonName=$node_ip \ --set externalURL='https://$node_ip:30003'
说明:其中 192.168.172.128
为kubernetes集群任一节点IP地址。
Harbor的架构设计
Harbor的架构设计[1]主要包括了以下几个方面的内容:
架构图
下图是Harbor的架构图:
Harbor架构
如上图所示,Harbor 由以下 3 层组件组成:
数据访问层
kv存储:由Redis组成,提供数据缓存功能,支持作业服务临时持久化作业元数据。
数据存储:支持多种存储,作为镜像仓库和Chart的后端存储,实现数据持久化。
数据库:采用PostgreSQL。存储Harbor模型的相关元数据,如项目、用户、角色、复制策略、标签保留策略、扫描策略、Chart和镜像信息。
基础服务
Proxy:由Nginx Server形成的反向代理,提供API路由功能。Harbor的core,registry,web portal和token服务组件都在这个反向代理的背后。代理将来自浏览器和 Docker 客户端的请求转发到各种后端服务。
Core: Harbor的核心服务,主要提供以下功能:
- • API 服务器:接受 REST API 请求并响应这些请求的 HTTP 服务器依赖于其子模块,例如“身份验证和授权”、“中间件”和“API 处理程序”。
- • 请求受到身份验证服务的保护,该服务可以由本地数据库、AD/LDAP 或 OIDC 提供支持。
- • 启用RBAC机制来对相关操作进行授权,例如:pull/push镜像
- • 令牌服务旨在根据用户在项目中的角色为每个 docker 推/拉命令颁发令牌。如果 Docker 客户端发送的请求中没有令牌,Registry 会将请求重定向到令牌服务。
- • 认证与授权
- • 中间件:提前对一些请求进行预处理,以确定它们是否符合要求的条件,并可以传递给后端组件进行进一步处理。一些功能以中间件的形式实现,例如“配额管理”、“签名检查”、“漏洞严重性检查”和“机器人账户解析”等。
- • API Handlers:处理相应的REST API请求,主要负责解析和验证请求参数,在相关API控制器之上完成业务逻辑,并写回生成的响应。
- • 配置管理器:涵盖所有系统配置的管理,如身份验证类型设置、电子邮件设置和证书等。
- • 项目管理:管理项目的基础数据和相应的元数据,创建这些元数据是为了隔离托管工件。
- • 配额管理器:管理项目的配额设置并在新推送发生时执行配额验证。
- • Chart控制器:将Chart相关请求代理到后端
chartmuseum
,并提供多种扩展来改善Chart管理体验。 - • 保留管理器:管理标签保留策略并执行和监控标签保留流程
- • 内容信任:对后端Notary提供的信任能力进行扩展,以支持内容信任过程的顺利进行。目前仅支持容器镜像签名。
- • 复制控制器:管理复制策略和镜像仓库适配器,触发和监视并发复制过程。实现了许多镜像仓库适配。
- • Distribution (docker registry)
- • Docker Hub
- • Huawei SWR
- • Amazon ECR
- • Google GCR
- • Azure ACR
- • Ali ACR
- • Helm Hub
- • Quay
- • Artifactory
- • GitLab Registry
- • 镜像扫描管理器:管理由不同提供商改编的多个配置的扫描仪,并提供指定工件的扫描摘要和报告。
- • 支持Aqua Security 提供的
Trivy
扫描仪、Anchore提供的Anchore Engine
扫描仪、CentOS (Redhat) 赞助的Clair
扫描仪以及DoSec 提供的DoSec Scanner
扫描仪。 - • 目前,仅支持扫描容器镜像或bundles ,例如清单列表/OCI 索引或 CNAB bundles。
- • 通知管理器(webhook):Harbor中配置的一种机制,以便Harbor中的工件状态更改可以填充到Harbor中配置的Webhook端点。感兴趣的各方可以通过监听相关的webhook事件来触发一些后续操作。现在支持两种方式:
- • HTTP POST 请求
- • Slack channel
- • OCI Artifact Manager:管理整个 Harbor 镜像仓库中所有 OCI 工件生命周期的核心组件。它提供了 CRUD 操作来管理工件的元数据和相关附加内容,例如扫描报告、容器镜像和自述文件的构建历史、依赖关系以及 Helm Chart 的 value.yaml 等,还支持管理工件标签的功能和其他有用的操作。
- • 镜像仓库驱动程序:作为镜像仓库客户端 SDK 实现,用于与底层镜像仓库(目前为 docker 发行版)进行通信。“OCI Artifact Manager”依赖此驱动程序从清单中获取附加信息,甚至是位于底层镜像仓库中的指定工件的配置 JSON。
作业服务:通用作业执行队列服务,让其他组件/服务通过简单的 RESTful API 提交并发运行异步任务的请求
Log Collector:日志收集器,负责将其他模块的日志收集到一个地方。
GC 控制器:管理在线 GC 计划设置并启动和跟踪 GC 进度。
Chart Museum:第 3 方Chart存储库服务器,提供Chart管理和访问 API。
DockerRegistry:第3方镜像仓库服务器,负责存储Docker镜像并处理Dockerpush/pull命令。由于 Harbor 需要对镜像实施访问控制,Registry 将引导客户端访问令牌服务,为每个拉取或推送请求获取有效令牌。
Notary:第三方内容信任服务器,负责安全发布和验证内容。
消费者
作为一个标准的云原生工件注册中心,自然会支持相关的客户端,如 docker CLI、notary 客户端、OCI 兼容客户端(如 Oras 和 Helm)。除了这些客户端之外,Harbor 还提供了一个 Web 门户,供管理员轻松管理和监控所有工件。
Web Portal:图形用户界面,帮助用户管理镜像仓库上的镜像
Harbor组件
我们使用Helm机制部署Harbor高可用(Ingress形式)后,得到的服务有
Harbor组件
# 1. Helm 列表 $ helm list -A NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION # harbor harbor harbor 1 2023-10-31 00:14:00.454746411 +0800 CST deployed harbor-1.13.0 2.9.0 # 分布式存储 openebs openebs 1 2023-10-30 23:36:48.413658223 +0800 CST deployed openebs-3.9.0 3.9.0 # 2. Ingress $ kubectl get ingress -n harbor NAME CLASS HOSTS ADDRESS PORTS AGE harbor-ingress nginx core.harbor.domain 10.105.128.206 80, 443 22h $ kubectl describe ingress -n harbor harbor-ingress Name: harbor-ingress Namespace: harbor Address: 10.105.128.206 Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) TLS: harbor-ingress terminates core.harbor.domain Rules: Host Path Backends ---- ---- -------- core.harbor.domain /api/ harbor-core:80 (10.244.219.69:8080) /service/ harbor-core:80 (10.244.219.69:8080) /v2/ harbor-core:80 (10.244.219.69:8080) /chartrepo/ harbor-core:80 (10.244.219.69:8080) /c/ harbor-core:80 (10.244.219.69:8080) / harbor-portal:80 (10.244.219.75:8080) Annotations: ingress.kubernetes.io/proxy-body-size: 0 ingress.kubernetes.io/ssl-redirect: true meta.helm.sh/release-name: harbor meta.helm.sh/release-namespace: harbor nginx.ingress.kubernetes.io/proxy-body-size: 0 nginx.ingress.kubernetes.io/ssl-redirect: true # 3. Harbor组件服务 $ kubectl -n harbor get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE harbor-portal ClusterIP 10.107.162.71 <none> 80/TCP 91m harbor-core ClusterIP 10.109.31.137 <none> 80/TCP 91m harbor-jobservice ClusterIP 10.111.2.109 <none> 80/TCP 91m harbor-registry ClusterIP 10.110.228.204 <none> 5000/TCP,8080/TCP 91m harbor-trivy ClusterIP 10.98.232.46 <none> 8080/TCP 91m harbor-database ClusterIP 10.103.147.242 <none> 5432/TCP 91m harbor-redis ClusterIP 10.99.63.102 <none> 6379/TCP 91m # 4. 持久存储声明 $ kubectl get pvc -n harbor NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-harbor-redis-0 Bound pvc-a71789b8-a656-4d34-b046-9be4e666e50b 1Gi RWO openebs-hostpath 23h data-harbor-trivy-0 Bound pvc-41997997-bede-4ba8-8d52-e769f9bdd310 5Gi RWO openebs-hostpath 23h database-data-harbor-database-0 Bound pvc-ec5ed590-3013-49c7-a4cb-e6ad8c531765 1Gi RWO openebs-hostpath 23h harbor-jobservice Bound pvc-7f833724-956e-4e8a-9329-8b558bf245e8 1Gi RWO openebs-hostpath 23h harbor-registry Bound pvc-1c28f1a0-fc79-4e84-afd5-cda76fc48083 5Gi RWO openebs-hostpath 23h
通过上面我们可知
- • Ingress服务:
- •
harbor-ingress
是Harbor的访问入口,提供对harbor-core
和harbor-portal
服务的路由转发和负载均衡。
- • Harbor的功能组件
- • 作用:
harbor-trivy
是Harbor的漏洞扫描组件,它使用Trivy工具来扫描容器镜像以检测其中的漏洞。 - • 与其他组件的关系:
harbor-trivy
与harbor-core
协作,以触发漏洞扫描任务,并将扫描结果与镜像元数据相关联 - • 作用:
harbor-registry
是Docker Registry的扩展,用于存储容器镜像。它支持Docker镜像的推送、拉取和管理。 - • 与其他组件的关系:
harbor-registry
与harbor-core
协作,以确保存储在Harbor中的镜像受到访问控制和安全性的保护。 - • 作用:
harbor-jobservice
负责执行后台任务,如镜像复制、扫描和删除,以减轻主要服务的负担。 - • 与其他组件的关系:
harbor-jobservice
与harbor-core
和harbor-registry
协作,接受任务请求并执行任务。 - • 作用:
harbor-core
是Harbor的核心组件,负责处理镜像的元数据和权限管理,它维护Harbor中的用户、项目、镜像和仓库信息。 - • 与其他组件的关系:
harbor-core
与harbor-portal
和harbor-registry
通信,以响应用户请求,还与harbor-jobservice
协作来执行任务,如镜像复制和删除。 - • 作用:
harbor-portal
是Harbor的Web界面,提供用户友好的管理界面,用于浏览、搜索、上传和管理容器镜像。 - • 与其他组件的关系:
harbor-portal
与其他组件通信以获取信息和执行操作。它向harbor-core
提交请求,以管理镜像、项目和用户。
- 1.
harbor-portal
: - 2.
harbor-core
: - 3.
harbor-jobservice
: - 4.
harbor-registry
: - 5.
harbor-trivy
:
- • 数据持久化
- • 如:
openebs
(本文使用),其他还可使用NFS
,Minio
等。 - • 作用:Harbor支持多种存储,作为镜像仓库和Chart的后端存储,实现数据持久化。
- • 与其他组件的通信:Harbor的核心组件与持久化存储进行读写操作,以存储和检索容器镜像数据。
- • 数据存放位置:通过PVC持久化到本地或共享存储,高可用部署需要共享分布式存储。
- • Harbor组件的持久化数据(Helm 默认安装):这些数据卷用于确保数据的持久性和高可用性,并支持Harbor的正常运行和数据管理。
- • 存放Docker镜像的实际数据。这是Harbor的核心组件,它负责存储和管理容器镜像。这个数据卷将包含Harbor中的各种容器镜像。
- • Harbor的后台任务服务,可能会在内部使用一些临时数据或任务状态信息。
- • 存放Trivy容器的数据。Trivy是用于漏洞扫描的组件,这个数据卷可能包含Trivy的扫描结果和相关数据。
- • 如:
data-harbor-redis-0
- • 作用:Harbor使用Redis作为缓存,提供数据缓存功能,支持作业服务临时持久化作业元数据。保存会话信息。
- • 与其他组件的通信:Harbor的各个组件可以与Redis进行通信,以快速访问缓存数据。
- • 数据存放位置:通过PVC持久化到本地或共享存储,高可用部署需要共享分布式存储。
- • 如:
database-data-harbor-database-0
- • 作用:Harbor使用PostgreSQL数据库来存存储Harbor的相关元数据,如项目、用户、角色、复制策略、标签保留策略、扫描策略、Chart和镜像信息。
- • 与其他组件的通信:
harbor-core
和harbor-jobservice
需要访问此数据库以维护Harbor的状态和元数据。 - • 数据存放位置:通过PVC持久化到本地或共享存储,高可用部署需要共享分布式存储。
- • PostgreSQL (PG):
- • Redis:
- • 持久化存储:
- 1. data-harbor-trivy-0:
- 2. harbor-jobservice:
- 3. harbor-registry:
参考链接
[1]
Harbor的架构设计: https://github.com/goharbor/harbor/wiki/Architecture-Overview-of-Harbor
推荐阅读