如何理解Harbor新版本中远程镜像复制功能的设计与实现

18次阅读
没有评论

如何理解 Harbor 新版本中远程镜像复制功能的设计与实现,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

容器镜像复制和发布一直缺少良好的工具,是实际开发和运维中的一大痛点。开源 Harbor Registry 提供强大的镜像复制 / 同步能力,成为众多用户喜爱的杀手级功能。

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

如何理解 Harbor 新版本中远程镜像复制功能的设计与实现

Harbor 镜像复制的管理界面

功能简介

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

 如何理解 Harbor 新版本中远程镜像复制功能的设计与实现

在较大的容器集群中,往往需要多个 Registry 服务器做负载均衡,可以采用主从发布模式,镜像只需要发布一次,就可以推送到多个 Registry 实例中。同时还支持双主复制和层次型的多级镜像发布,如下图所示: 如何理解 Harbor 新版本中远程镜像复制功能的设计与实现

如何理解 Harbor 新版本中远程镜像复制功能的设计与实现

设计与实现

在不同的 Registry 实例之间复制镜像是十分普遍的需求,过去常见的做法是通过拷贝镜像数据,比如定期通过 rsync 同步文件系统中镜像的数据,或者,对于部署在 IaaS 服务上的情况,通过对 IaaS 存储服务一层进行配置实现对象复制,这些方法往往是根据 registry 使用的存储而采用不同工具。然而对于 Harbor 来说,我们希望降低这种依赖,并提高灵活性,比如用户可能有一个开发用的 registry 使用文件系统作为存储,并希望把镜像同步到基于 S3 存储的远端发布用的 registry 上。考虑到这种情况,我们选择通过调用 registry 本身的 API 下载并传输镜像,从而做到了与下层存储无关。

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

如何理解 Harbor 新版本中远程镜像复制功能的设计与实现如何理解 Harbor 新版本中远程镜像复制功能的设计与实现

下面介绍一下 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 数量来控制并发数:

 如何理解 Harbor 新版本中远程镜像复制功能的设计与实现如何理解 Harbor 新版本中远程镜像复制功能的设计与实现

对于另一个问题,每一个 worker 内部是一个抽象的状态机(state machine),通过给不同状态注册处理器(handler)完成具体工作,同时,状态机可以受到干预,可以中途取消(cancel)任务,或在任务执行发生异常时将任务置为错误(error)状态丢弃或交给调度器(scheduler)重试。另外由于状态机的状态是可定制的,这样就很方便扩展和调整。对于一个抽象的任务来说,它的状态转移如下图所示: 如何理解 Harbor 新版本中远程镜像复制功能的设计与实现如何理解 Harbor 新版本中远程镜像复制功能的设计与实现

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

如何理解 Harbor 新版本中远程镜像复制功能的设计与实现如何理解 Harbor 新版本中远程镜像复制功能的设计与实现

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

关于如何理解 Harbor 新版本中远程镜像复制功能的设计与实现问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注丸趣 TV 行业资讯频道了解更多相关知识。