本文由“GO开源说”第七期 《Harbor助你玩转云原生》直播内容修改整理而成,视频内容较长,本文内容有所删减和重构。
云原生技术的兴起为企业数字化转型带来新的可能。作为云原生的要素之一,带来更为轻量级虚拟化的容器技术具有举足轻重的推动作用。其实很早之前,容器技术已经有所应用,而Docker的出现和兴起彻底带火了容器。其关键因素是Docker提供了使用容器的完整工具链,使得容器的上手和使用变得非常简单。工具链中的一个关键,就是定义了新的软件打包格式-容器镜像。镜像包含了软件运行所需要的包含基础OS在内的所有依赖,推送至运行时可直接启动。从镜像构建环境到运行环境,镜像的快速分发成为硬需求。同时,大量构建以及依赖的镜像的出现,也给镜像的维护管理带来挑战。镜像仓库的出现成为必然。
图1 镜像仓库
镜像构建之后可以推送至仓库储存和管理,运行时环境在有应用运行需求时,从仓库拉取特定的应用镜像来运行。镜像仓库作为镜像的分发媒介,可以实现特定的管理和访问控制机制。仓库作为镜像传输流动的主要媒介,成为云原生应用平台运转的核心要件。Docker开源了其registry实现, 目前已经成为CNCF的沙箱项目Distribution。不过,Distribution项目仅仅实现了对镜像存储的支持,对企业级的一些管理诉求并无法提供支持。
为了实现企业级镜像仓库的支持,Harbor项目应运而生。
Harbor Registry(又称Harbor云原生制品仓库或Harbor镜像仓库)由VMware公司中国研发中心云原生实验室原创,并于2016年3月开源。Harbor在Docker Distribution的基础上增加了企业用户必需的权限控制、镜像签名、安全漏洞扫描和远程复制等重要功能,还提供了图形管理界面及面向国内用户的中文支持,开源后迅速在中国开发者和用户社区流行,成为中国云原生用户的主流容器镜像仓库。
2018年7月,VMware捐赠Harbor给CNCF,使Harbor成为社区共同维护的开源项目,也是首个源自中国的CNCF项目。在加入CNCF之后,Harbor融合到全球的云原生社区中,众多的合作伙伴、用户和开发者都参与了Harbor项目的贡献,数以千计的用户在生产系统中部署和使用Harbor,Harbor每个月的下载量超过3万次。2020年6月,Harbor成为首个中国原创的CNCF毕业项目。目前Harbor主项目已经在GitHub上已经获得了1万3千多颗星。Harbor项目目前有来自于全球多家公司的14名维护者,200多名核心提交者,以及50多个贡献公司。Harbor社区依然在蓬勃发展,欢迎更多的贡献者加入!
Harbor是为满足企业安全合规的需求而设计的,旨在提供安全和可信的云原生制品管理,支持镜像签名和内容扫描,确保制品管理的合规性、高效性和互操作性。Harbor的功能主要包括四大类:多用户的管控(基于角色访问控制和项目隔离)、镜像管理策略(存储配额、制品保留、漏洞扫描、来源签名、不可变制品、垃圾回收等)、安全与合规(身份认证、扫描和CVE例外规则等)和互操作性(Webhook、内容远程复制、可插拔扫描器、REST API、机器人账号等)。
Harbor提供了多种途径来帮助用户快速搭建Harbor镜像仓库服务,包括:
-
离线安装包:通过docker-compose编排运行。安装包除了包含相关的安装脚本外,还包含了所有安装所需要的Harbor组件镜像,可以在离线环境下安装使用。
-
在线安装包:与离线安装包类似,唯一的区别就是不包含harbor组件镜像,安装时镜像需要从网络上的仓库服务拉取。
- Helm Chart:
通过Helm的方式将Harbor部署到目标的Kubernetes集群中。
目前仅覆盖Harbor自身组件的部署安装,其所依赖的诸如数据库、Redis缓存以及可能的存储服务需要用户自己负责。
- Kubernetes Operator:
基于Kubernetes Operator框架编排部署,重点关注all-in-one的HA部署模式的支持。
目前还处于开发中,很快就会发布。
接下来,我们深入了解一下Harbor所提供的核心功能。
首先就是Harbor的资源隔离与多租户体系,如下图所示。
Harbor实现了以项目为单位的资源逻辑隔离体系,基于项目实现RBAC访问控制和配额管理。用户对项目资源的访问是基于其在此项目中所被指派的角色。目前Harbor提供了多个预定义的角色,访客、开发者、维护者,项目管理员以及系统管理员,权限从低到高逐级递进,具体详情可参见:角色权限集合(https://goharbor.io/docs/2.2.0/administration/managing-users/user-permissions-by-role/)。另外,需要特别提到的是,因为是逻辑隔离,在后端实际存储中还是共享空间的,这样避免镜像的数据层重复存储,有效降低存储空间大小。
Harbor也支持多种用户系统,默认支持内嵌的数据库用户系统,同时也支持对接AD/LDAP系统以及通过一致的OIDC机制对接其它用户系统提供商,社区验证过的提供商可以参考 OIDC adapters(https://goharbor.io/docs/2.2.0/install-config/harbor-compatibility-list/)。同时,考虑到CI/CD场景,也提供了项目层面的机器人账号,方便CI/CD中的集成使用。
在刚发布不久的Harbor 2.2版本中,对机器人账号也做了很大的增强。
提供了新的系统级别的机器人账号以支持通过一组授权来覆盖多个项目。同时,支持更多类型的权限来授权不同的操作和API调用。另外,相对于之前的jwt令牌方式,新的方式带来更大的灵活性(即使授权范围或者过期时间发生变化,密码依然有效)。更多详情可以参考系 统级机器人账号的设计提议(https://github.com/goharbor/community/pull/148)。
镜像仓库的一个关键功能就是实现镜像的分发。Harbor在镜像分发方面,除了常规的镜像推送和拉取能力外,还提供了多种有效的机制和方法供用户来应对不同的场景需要。
基于策略的镜像复制机制,可以帮助用户实现将源仓库中的特定镜像集合在指定的条件下复制到目标镜像仓库中。在复制策略中,除了指定源仓库或者目标仓库之外,可以指定多种过滤器(镜像库、tag和标签)与多种触发模式(手动,基于时间以及定时)且实现对推送(将镜像从源仓库推送至目标仓库)和拉取(将目标仓库的镜像拉取到当前仓库)两种模式的支持。首次复制为全量复制,之后会实现增量复制以提升效率。目前Harbor的复制功能已经支持包含Docker Hub、Quay、GCR、ECR等在内的十多种第三方镜像仓库,具体列表可参考 Replicaiton adpaters(https://goharbor.io/docs/2.2.0/install-config/harbor-compatibility-list/)。
基于复制功能,可有构建主从或者中心-边缘的多层分发体系,以实现镜像内容的高效和稳定的分发。如下图所示。镜像推送至中心Harbor仓库,然后复制到其它地理位置上的边缘仓库,容器运行时可从就近的边缘仓库拉取。
复制可以解决非实时的复制能力,对于实时场景,Harbor实现项目级别的缓存机制。在创建项目时,可以启用项目的缓存机制。这样在拉取镜像时,如果项目中不存在,则由适配器将请求代理到项目所配置的上游仓库中来响应此次拉取的请求,同时将镜像缓存到项目中,下次再请求此镜像时,则可直接响应请求。缓存到项目的镜像制品与“本地”镜像制品没有差异,相关的管理策略可以应用到缓存的镜像上,比如配额、扫描等。目前支持的缓存代理的上游仓库除了其它Harbor之外,还支持Docker Hub、GCR、ECR以及quay,未来会根据需求来验证更多第三方仓库支持(缓存代理与内容复制共享相同的适配器)。在创建项目时选择启用缓存功能则新建项目为缓存项目,不可推送;以创建的普通项目无法直接转为缓存项目。另外,使用缓存镜像的路径有特定的模式,docker pull <harbor-host>/[cache_project_name]/<repository_path>(docker pull goharbor.io/my_cache_pro/library/nginx:latest)。
在进行大量部署的时候,对仓库的镜像拉取请求会产生井喷,进而造成比较重的负担。而这其中可能有很多重复的镜像请求,这样也就造成更多的不必要的资源和流量浪费。P2P网络可以加速内容的分发,自然也可以加速镜像的分发。因为P2P的特质,内容可来源于其它peer节点,这样可以有效地减少对上游仓库的请求。Harbor是镜像仓库,本身不支持P2P协议。但是可以与其它P2P提供者实现集成,进而利用P2P vendor能力实现镜像的加速。这就是Harbor的镜像预热功能。用户通过在特定项目中创建特定的预热策略,使用过滤器(repository和tag)来确定哪些镜像满足什么样的条件(是否签名,持有特定标签或者满足特定的漏洞状态)需要预热,在什么时候(就有事件或者基于定时)触发预热,将所选镜像提前从Harbor仓库传输到特定P2P引擎的缓存中,在有拉取请求时,P2P可以直接开始工作,不需要从上游仓库获取首份镜像内容。目前已经支持的P2P引擎包括CNCF的Dragonfly和Uber的Kraken。
安全已经成为云原生关注的要点之一,同时也是平台的第一要务。Harbor作为镜像制品仓库,也提供了与镜像相关联的多种安全机制,这也是Harbor很重要的特点之一。
Harbor通过引入开源的Notary框架实现了与DTR兼容的镜像制品签名机制。用户只要在Docker客户端设置以下环境变量,就可开启签名流程:
$ export DOCKER_CONTENT_TRUST=1
$ export DOCKER_CONTENT_TRUST_SERVER=https://<harbor主机地址>:4443
之后在拉取使用镜像时,会对内容进行校验。
镜像制品是否被签名,也可以设置成为镜像安全策略之一,这样可以保证只有签名过的镜像制品才可以被拉取。
Harbor对旧式的Helm V2 chart的支持是通过chartmuseum来实现的,其签名机制保持了和Helm社区一致的形式,即通过GPG key的模式。在打包chart时,添加--sign和--key来生成包含有签名内容的prov文件,之后通过Harbor的web界面或者helm V2的push 插件随chart的tgz包一同上传到Harbor。Harbor会识别文件以展示chart是否被签过名。之后在使用时,可以对内容进行校验。
Harbor支持对镜像制品进行漏洞扫描。考虑到用户对扫描引擎有不同的偏好或者已经投入了特定的扫描引擎,Harbor通过插件式的方式可以对接多种不同的扫描引擎来实现对其所管理的镜像制品的漏洞扫描能力。目前已经支持的扫描引擎包括 Clair、Trivy、Aqua CSP、Anchore、Sisdig、小佑DoSec以及探真扫描器等,具体列表可以参考Scanner adapters。未来会支持更多诸如恶意软件,非法配置以及BOM等形式的扫描。
Harbor基于上述插件式的扫描机制,可向用户提供特定镜像的漏洞报告总汇和漏洞详情列表,便于用户及时掌握镜像的漏洞状态。另外,基于这些漏洞状态信息,设置与扫描有关的安全策略,即只允许包含某级别以下的镜像被拉取,大大提升了运行时端的安全可靠性。
Harbor也考虑到了在特定情况下,某些镜像tag具有一定的稳定性要求,不能被误覆盖,实现了不可变tag的安全机制。用户通过设置不可变tag的规则,使得满足这个规则的tag都进入不可变更的状态。
作为资源的管理储存平台,资源的清理和垃圾回收自然也不能缺席。结合镜像的管理模型和存储模型,Harbor提供了tag保留机制和垃圾回收两种能力。
Tag保留机制基于用户设置的规则计算出需要保留的镜像tag,而不在保留列表里的tag则会被清除。用户可以设置最多15条规则,每条规则可以独立定义过滤器和诸如“保留最近拉取的#个镜像”或者“保留最近#天内被拉取的镜像”的附件条件。这里需要提到的是,之前提到的不可变镜像tag是不会被清理的。另外,每次清理或者保留的tag列表会在每次规则执行的文本日志里保留。Tag的清理不会释放存储资源,但是会释放配额。
清理后端的无用存储数据则需要GC垃圾回收机制。Harbor支持在线垃圾回收,用户可通过Harbor的管理界面来触发或者设置定时循环触发。每次GC执行的具体信息会被记录在执行记录的文本日志里,这些信息包含总共分析了多少数据,释放了多少数据。在2.1版本之前,GC的运行时阻塞式的,即GC运行时系统处于只读状态,不允许任何写操作进行。2.1之后实现非阻塞式GC模式,GC过程依然支持推送新镜像到Harbor。
要使用Harbor搭建高可用的镜像仓库服务,无论是那种部署模式,基本可以从基于Harbor的镜像复制功能或者使用共享服务/存储两个角度考虑。具体内容可以参阅《Harbor权威指南》这本书的相关章节。
Harbor自身也具有很强的扩展能力,可以支持不同场景下的集成需求。这些扩展能力可以总结为以下几点:
-
基于Swagger的完善Rest API,很容易构建API客户端来实现API的集成。
-
支持AD/LDAP/OIDC,可以实现用户系统的对接。
-
插件化的漏洞扫描机制,扫描引擎vendor可以基于扫描器API规范实现与Harbor的集成。
-
P2P提供商可以通过实现特定的接口规范来完成与Harbor的集成。
- 第三方镜像仓库可以通过实现特定的复制适配器接口规范来实现与Harbor的互操作。
对于符合OCI规范的制品,可以通过预先定义的OCI annotation来实现元数据的扩展识别,进而使得Harbor API和web界面支持对特定元数据的识别和渲染。
Harbor从版本2.2开始开放了相关的系统和业务监控参数,可以方便的实现特定监控平台对Harbor的接入和监控,方便日常运维工作。
-
之后的版本,Harbor会重点关注:
- 发布针对Kubernetes平台部署的harbor operator
-
支持更多组件的监控参数暴露
-
组建性能工作组来不断解决Harbor中遇到的性能问题并实现持续改进
-
IPV6网络的支持
-
更强大的安全扫描与审查机制
-
组建多架构工作组以实现在非X86 CPU架构平台上(ARM、AMD和龙芯)构建运行Harbor服务
- 响应更多其他来自于用户和社区的需求
Harbor一致致力于构建开放、透明和活跃的社区,欢迎大家积极参与到社区中,共同努力并推动Harbor项目不断向前发展。大家可以通过多种途径联系社区和参与进来:
-
CNCF workspace下的slack channel:#harbor与#harbor-dev
-
公开邮件组:lists.cncf.io/g/harbor-users 和lists.cncf.io/g/harbor-dev
-
Twitter:@project_harbor
-
双周社区例会:双周周三晚21:00点 zoom https://zoom.us/j/734959521拨入。会议邀请会发送到slack channel和邮件组。
- Demo环境: demo.goharbor.io, 自助注册账户进入。
有疑问加站长微信联系(非本文作者)