Docker镜像管理:为什么Harbor是首选

关注【云原生百宝箱】公众号,获取更多云原生消息


图片

“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-coreharbor-portal服务的路由转发和负载均衡。

  • • Harbor的功能组件

    • • 作用:harbor-trivy是Harbor的漏洞扫描组件,它使用Trivy工具来扫描容器镜像以检测其中的漏洞。

    • • 与其他组件的关系:harbor-trivyharbor-core协作,以触发漏洞扫描任务,并将扫描结果与镜像元数据相关联

    • • 作用:harbor-registry是Docker Registry的扩展,用于存储容器镜像。它支持Docker镜像的推送、拉取和管理。

    • • 与其他组件的关系:harbor-registryharbor-core协作,以确保存储在Harbor中的镜像受到访问控制和安全性的保护。

    • • 作用:harbor-jobservice负责执行后台任务,如镜像复制、扫描和删除,以减轻主要服务的负担。

    • • 与其他组件的关系:harbor-jobserviceharbor-coreharbor-registry协作,接受任务请求并执行任务。

    • • 作用:harbor-core是Harbor的核心组件,负责处理镜像的元数据和权限管理,它维护Harbor中的用户、项目、镜像和仓库信息。

    • • 与其他组件的关系:harbor-coreharbor-portalharbor-registry通信,以响应用户请求,还与harbor-jobservice协作来执行任务,如镜像复制和删除。

    • • 作用:harbor-portal是Harbor的Web界面,提供用户友好的管理界面,用于浏览、搜索、上传和管理容器镜像。

    • • 与其他组件的关系:harbor-portal与其他组件通信以获取信息和执行操作。它向harbor-core提交请求,以管理镜像、项目和用户。

    1. 1. harbor-portal

    2. 2. harbor-core

    3. 3. harbor-jobservice

    4. 4. harbor-registry

    5. 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-coreharbor-jobservice需要访问此数据库以维护Harbor的状态和元数据。

    • • 数据存放位置:通过PVC持久化到本地或共享存储,高可用部署需要共享分布式存储。

    • • PostgreSQL (PG):

    • • Redis:

    • • 持久化存储

    1. 1. data-harbor-trivy-0:

    2. 2. harbor-jobservice:

    3. 3. harbor-registry:

参考链接

[1] Harbor的架构设计: https://github.com/goharbor/harbor/wiki/Architecture-Overview-of-Harbor


推荐阅读

猜你喜欢

转载自blog.csdn.net/fly910905/article/details/134418929
今日推荐