1. 理论部分

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

在这里插入图片描述

在不同的Registry实例之间复制镜像是十分普遍的需求,过去常见的做法是通过拷贝镜像数据,比如定期通过rsync同步文件系统中镜像的数据,使用harbor,我们可以降低这种依赖,并提高灵活性

在控制方面,我们引入了一个新的组件,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配对(放在这个channel上的work都是没事干的,空闲的,dispatcher与这些空闲的work联系,分配任务),于是,空闲的worker通过dispatcher获得任务id并执行任务,这样可以很方便地通过worker pool(其实就是下边的channel中为worker提供的位置总和)中 worker数量来控制并发数:

在这里插入图片描述
对于另一个问题,每一个 worker内部是一个抽象的状态机(state machine),通过给不同状态注册处理器(handler)完成具体工作,同时,状态机可以受到干预,可以中途取消(cancel)任务,或在任务执行发生异常时将任务置为错误(error)状态丢弃或交给调度器(scheduler)重试。 另外由于状态机的状态是可定制的,这样就很方便扩展和调整。这里再说的直白一点,就是说worker可以给任务反馈不同的状态,针对上边说的第二个问题,如果复制策略失效了,这个时候worker就可以给这个任务一个pending的状态或者retry的状态,而不是直接丢弃,这样就可以解决复制策略变化带俩的负面影响。对于一个抽象的任务来说,它的状态转移如下图所示:
在这里插入图片描述
而对于具体远程同步镜像的任务来说,Running 状态会被进一步细分成多个子状态(这里展示的是pull的running的状态分析,其实就是作为接收同步镜像的一方,对于这一方来说,细分的过程如下),如下图所示:
在这里插入图片描述
首先, 从源Harbor实例下载相应tag的manifest,分析其所包含的blob,针对每一个blob,检查其在目标实例中是否已经存在,如果不存在,则同步此blob。最后,检查manifest在目标实例中是否已存在,如果不存在,则上传manifest。检查blob的存在性,可以有效减少不必要的网络流量。对同一个镜像中的每一个tag重复以上过程,就可以完成整个镜像的同步工作。

上图不太合适,应该把"has tag"去掉

关于manifest和blob的说明在docker部分“04-docker镜像仓库”中有详细说明,此处不做赘述

2. 操作部分

现在已经具备了两个安装好的harbor和一个docker客户端,主机及ip情况如下所示

主机ip角色
host1192.168.20.120docker
host2192.168.20.121harbor1
host3192.168.20.122harbor2

在harbor1上创建项目kgc
在这里插入图片描述

在harbor1上设置复制目标
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在harbor1上创建复制规则
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

现在我们去客户端配置的docker、登陆harbor,并上传镜像到kgc项目

[root@localhost ~]# vim /usr/lib/systemd/system/docker.service 
 14 ExecStart=/usr/bin/dockerd --insecure-registry 192.168.20.121
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# docker login -u admin -p Harbor12345 192.168.20.121
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[root@localhost ~]# docker tag centos 192.168.20.121/kgc/centos:latest
[root@localhost ~]# docker push 192.168.20.121/kgc/centos
The push refers to repository [192.168.20.121/kgc/centos]
d69483a6face: Pushed 
latest: digest: sha256:ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66 size: 529

去harbor1上查看镜像是否上传
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由上图可以看出,harbor1的镜像复制到了harbor2上,下面我们登陆harbor2进行查看验证

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

OK,大功告成,此处发现harbor2已具备镜像,主从复制成功

GitHub 加速计划 / ha / harbor
23.24 K
4.68 K
下载
Harbor 是一个开源的容器镜像仓库,用于存储和管理 Docker 镜像和其他容器镜像。 * 容器镜像仓库、存储和管理 Docker 镜像和其他容器镜像 * 有什么特点:支持多种镜像格式、易于使用、安全性和访问控制
最近提交(Master分支:2 个月前 )
9e55afbb pull image from registry.goharbor.io instead of dockerhub Update testcase to support Docker Image Can Be Pulled With Credential Change gitlab project name when user changed. Update permissions count and permission count total Change webhook_endpoint_ui Signed-off-by: stonezdj <stone.zhang@broadcom.com> Co-authored-by: Wang Yan <wangyan@vmware.com> 7 天前
3dbfd422 Signed-off-by: wang yan <wangyan@vmware.com> 8 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐