Harbor: 跨数据中心复制Docker镜像的开源实现

容器镜像复制和发布一直缺乏良好的工具,是实际开发和运维中的一大痛点。开源Harbor Registry提供强大的镜像复制/同步能力,成为众多用户喜好的杀手级功能。本文介绍了镜像复制功能的工做原理,做者为Harbor项目核心工程师姜坦、尹文开。git

VMware公司3月份开源了企业级Registry项目Harbor,由VMware中国研发的团队负责开发。Harbor可帮助用户迅速搭建企业级的registry 服务。它提供了管理图形界面, 基于角色的访问控制RBAC,镜像远程复制(同步),AD/LDAP集成、以及审计日志等企业用户需求的功能,同时还原生支持中文,深受中国用户的喜好。该项目推出4多个月以来,在GitHub 得到了超过900多个点赞星星和200多个 forks,Github地址:github

https://github.com/vmware/harbor数据库

在最近发布的版本中,Harbor新增了基于策略的Docker镜像复制功能,可在不一样的数据中心、不一样的运行环境之间同步镜像,并提供友好的管理界面,大大简化了实际运维中的镜像管理工做,已经有用户部署了远程镜像双向复制的案例。本文将对该功能的实现原理作详细介绍。服务器

Harbor镜像复制的管理界面微信

功能简介网络

在功能设计方面,Harbor仍然以“项目”为中心, 经过对项目配置“复制策略”,标明须要复制的项目以及镜像。管理员在复制策略中指明目标实例,即复制的“目的地”,并对它的地址和链接时使用的用户名密码进行设置。当复制策略被激活时,源项目下的全部镜像,都会被复制到目标实例;此外,当源项目下的镜像被添加或删除(push或delete), 只要策略还在激活状态,镜像的变化都会同步到目标实例上去, 以下图所示:并发

 

在较大的容器集群中,每每须要多个Registry服务器作负载均衡,能够采用主从发布模式,镜像只须要发布一次,就能够推送到多个Registry实例中。同时还支持双主复制和层次型的多级镜像发布,以下图所示: 负载均衡

设计与实现运维

在不一样的Registry实例之间复制镜像是十分广泛的需求,过去常见的作法是经过拷贝镜像数据,好比按期经过rsync同步文件系统中镜像的数据,或者,对于部署在IaaS服务上的状况,经过对IaaS存储服务一层进行配置实现对象复制,这些方法每每是根据registry使用的存储而采用不一样工具。然而对于Harbor来讲,咱们但愿下降这种依赖,并提升灵活性, 好比用户可能有一个开发用的registry使用文件系统做为存储,并但愿把镜像同步到基于S3存储的远端发布用的registry上。考虑到这种状况,咱们选择经过调用registry自己的API下载并传输镜像,从而作到了与下层存储无关。工具

在控制方面,咱们引入了一个新的组件,Job Service,用来对镜像复制任务进行管理。当以项目为单位进行复制时,会以镜像为单位生成一系列任务(job)由Job Service 调度管理,Job Service在执行任务的过程当中将每一个任务的状态更新到数据库中, 以便用户经过UI查看。大致结构以下图所示:

下面介绍一下Job Service 的实现,从外部看它也是经过REST API接收请求调度并执行任务,面临的问题主要有两点,首先,接收到大量复制请求时须要进行限流以避免消耗过多IO资源;其次,复制策略有可能在任务执行过程当中改变,好比失效,这就须要一种机制能从外界对运行中的任务进行干预。

咱们经过任务队列,分发器(dispatcher)和worker pool实现了生产者消费者模型,利用Go语言内置的channel,每一个任务会经过scheduler放到channel里,dispatcher 经过channel得到任务,同时,worker在工做结束后会被放入另外一个channel, dispatcher 经过这个channel与worker配对,因而,空闲的worker经过dispatcher得到任务id并执行任务,这样能够很方便地经过worker pool中 worker数量来控制并发数:

 

对于另外一个问题,每个 worker内部是一个抽象的状态机(state machine),经过给不一样状态注册处理器(handler)完成具体工做,同时,状态机能够受到干预,能够中途取消(cancel)任务,或在任务执行发生异常时将任务置为错误(error)状态丢弃或交给调度器(scheduler)重试。 另外因为状态机的状态是可定制的,这样就很方便扩展和调整。对于一个抽象的任务来讲,它的状态转移以下图所示: 

而对于具体远程同步镜像的任务来讲,Running 状态会被进一步细分红多个子状态,以下图所示:

首先, 从源Harbor实例下载相应tag的manifest,分析其所包含的blob,针对每个blob,检查其在目标实例中是否已经存在,若是不存在,则同步此blob。最后,检查manifest在目标实例中是否已存在,若是不存在,则上传manifest。检查blob的存在性,能够有效减小没必要要的网络流量;而因为manifest的上传有可能会触发镜像的同步,因此对manifest存在性的检查,则能够避免当同步的多个Harbor造成环路时进入不断同步的死循环状态。对同一个镜像中的每个tag重复以上过程,就能够完成整个镜像的同步工做。

总结与展望

本文介绍了Harbor新版本中远程镜像复制功能的设计与实现。从此咱们将对此功能进行扩展,好比在策略(policy)中加入更加丰富的控制和过滤条件方便用户选择须要复制的镜像,以及控制复制的发生时间等。也但愿读者和用户们在多向咱们提供反馈意见。Harbor项目网址:

https://github.com/vmware/harbor

为便于交流,微信用户可申请加入“Harbor开源项目群”,请先扫描下面二维码关注“亨利笔记”公众号,并在公众号后台发送"入群"信息便可。 

相关文章
相关标签/搜索