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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 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


推荐阅读

相关实践学习
通过容器镜像仓库与容器服务快速部署spring-hello应用
本教程主要讲述如何将本地Java代码程序上传并在云端以容器化的构建、传输和运行。
Kubernetes极速入门
Kubernetes(K8S)是Google在2014年发布的一个开源项目,用于自动化容器化应用程序的部署、扩展和管理。Kubernetes通常结合docker容器工作,并且整合多个运行着docker容器的主机集群。 本课程从Kubernetes的简介、功能、架构,集群的概念、工具及部署等各个方面进行了详细的讲解及展示,通过对本课程的学习,可以对Kubernetes有一个较为全面的认识,并初步掌握Kubernetes相关的安装部署及使用技巧。本课程由黑马程序员提供。 &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
17天前
|
Docker 容器
将本地的应用程序打包成Docker镜像
将本地的应用程序打包成Docker镜像
|
1天前
|
NoSQL PHP MongoDB
docker push推送自己搭建的镜像
本文详细介绍了如何搭建和复盘两个Web安全挑战环境:人力资源管理系统和邮件管理系统。首先,通过Docker搭建MongoDB和PHP环境,模拟人力资源管理系统的漏洞,包括nosql注入和文件写入等。接着,复盘了如何利用这些漏洞获取flag。邮件管理系统部分,通过目录遍历、文件恢复和字符串比较等技术,逐步绕过验证并最终获取flag。文章提供了详细的步骤和代码示例,适合安全研究人员学习和实践。
16 3
docker push推送自己搭建的镜像
|
18天前
|
数据库 Docker 容器
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。Dockerfile定义了构建镜像所需的所有指令,包括基础镜像选择、软件安装、文件复制等,极大提高了开发和部署的灵活性与一致性。掌握Dockerfile的编写,对于提升软件开发效率和环境管理具有重要意义。
38 9
|
18天前
|
存储 缓存 运维
Docker镜像采用分层存储,每层代表镜像的一部分,如基础组件或应用依赖,多层叠加构成完整镜像
Docker镜像采用分层存储,每层代表镜像的一部分,如基础组件或应用依赖,多层叠加构成完整镜像。此机制减少存储占用,提高构建和传输效率。Docker还通过缓存机制提升构建和运行效率,减少重复工作。文章深入解析了Docker镜像分层存储与缓存机制,包括具体实现、管理优化及实际应用案例,帮助读者全面理解其优势与挑战。
40 4
|
1月前
|
存储 关系型数据库 Linux
【赵渝强老师】什么是Docker的镜像
Docker镜像是一个只读模板,包含应用程序及其运行所需的依赖环境。镜像采用分层文件系统,每次修改都会以读写层形式添加到原只读模板上。内核bootfs用于加载Linux内核,根镜像相当于操作系统,上方为应用层。镜像在物理存储上是一系列文件的集合,默认存储路径为“/var/lib/docker”。
|
1月前
|
缓存 JavaScript 安全
深入理解Docker镜像构建过程
深入理解Docker镜像构建过程
68 0
|
4月前
|
存储 安全 Ubuntu
Docker 镜像与 Docker 容器的区别
【8月更文挑战第27天】
371 5
|
4月前
|
存储 Ubuntu 应用服务中间件
在Docker中,怎么快速查看本地的镜像和容器?
在Docker中,怎么快速查看本地的镜像和容器?
|
5月前
|
Shell Linux Docker
docker常用命令大全(基础、镜像、容器、数据卷)
这些命令仅仅是 Docker 命令行工具的冰山一角,但对于日常操作来说已经非常全面。通过熟练地使用这些基础命令,用户可以有效地管理 Docker 的镜像、容器、数据卷和网络。随着用户对 Docker 的深入使用,更高级的命令和选项将会变得必需,但上面列出的命令已经为用户提供了一个坚实的起点。对于初学者来说,理解和掌握这些常用命令是深入学习 Docker 的基础。
524 5
docker常用命令大全(基础、镜像、容器、数据卷)