陈奇网络工作室

如何将docker注册表中的映像迁移到harbor?四个具体的解决方案和想法分享

如何将docker注册表中的映像迁移到harbor?本文介绍四个具体的思路和想法,供大家参考。

登记处

docker分发Docker分发是第一个实现打包、发布、存储和镜像分发的工具,起到Docker注册表的作用。(目前,发行已捐赠给CNCF)。Docker发行版中的spec规范后来成为OCI发行版-spec规范。可以认为,Docker分发实现了OCI映像分发的大部分规范,两者也在很大程度上兼容。OCI的指导思想是先有行业惯例,再把这些惯例归纳成技术规范。因此,尽管OCI的distribution-spec规范尚未正式发布(当前版本为v1.0.0-rc1),但基于Docker分发版的镜像仓库已经成为广泛采用的方案,docker registry http api v2已经成为事实上的标准。Harborharbor还使用Docker Distribution(Docker registry)作为后端图像存储服务。在harbor 2.0之前,大部分与图片相关的功能都是由Docker发行版处理的,图片、OCI等产品的元数据都是由harbor组件从Docker注册表中提取的。harbor 2.0版本以后,图片等与OCI产品相关的元数据由harbor自己维护,在推送这些产品时,元数据会写入harbor的数据库。得益于此,harbor不再仅仅是一个存储和管理图像的服务,而是一个云原生仓库服务,可以存储和管理符合OCI规范的Helm Chart、CNAB、OPA Bundle等各种神器。Docker registry to harbor回到本文的主题:如何将Docker registry中的镜像迁移到harbor?

如果内网环境有两台机器,一台运行docker注册表,域名假设为registry.k8s.li另一台运行harbor,假设域名为harbor.k8s.li现在docker注册表中存储了5000张图片。Harbor刚部署,里面没有镜子。在磁盘和网络没有限制的情况下,如何高效地将docker注册表中的镜像迁移到harbor?

获取注册表中所有镜像的列表。

首先,我们需要在迁移前获取docker注册表中的图像列表,这样才能保证迁移后没有图像丢失。根据文章《深入浅出容器镜像的一生》中提到的注册表的存储目录结构。在注册表存储目录中,每个镜像的标签都被当前/index文件指向标签镜像的manifests文件,这样我们就可以通过遍历注册表存储目录中的当前/index文件得到所有镜像的标签,从而得到注册表中所有镜像的列表。注意只能获取有标签的图像,其他没有标签的图像无法获取。

可以通过以下命令在注册表存储目录下获取镜像列表:

港口创造项目

对于新部署的harbor,只会有一个默认的库项目,docker注册表中对应的项目需要在harbor上手动创建。docker注册表中的镜像项目是注册表存储目录中repositories下的目录名。

在获得镜像列表并在harbor上创建相应的项目之后,我们就可以进行正式的迁移了。根据不同的场景,可以使用以下方案:

选项1: docker重新标记

方案一可能是大多数人想到的第一种方式,也是最简单粗暴的方式。就是在一台机器上使用docker pull下的docker注册表中的所有图片,然后docker重新标记,然后docker push到harbor。

如果你之前看过我的书《深入浅出容器镜像的一生》和《镜像搬运工 skopeo 初体验》,并且在日常生活中使用过skopeo,你一定会觉得这不是一个聪明的解决方案,因为镜像层会在Docker Pull-Docker Tag-Docker Pull的过程中被解压。为了将图像从一个注册表复制到另一个注册表,这些docker在这些过程中做了许多无用的工作。详细原理可以参考以上两篇文章,此处不再赘述。

为了追求高效率,我们不使用docker重标记方案。让我们来看看第二个方案:

选项2: skopeo

在文章《镜像搬运工 skopeo 初体验》中介绍了skopeo copy可以用来将镜像的原始blobs直接从一个注册表复制到另一个注册表,在此过程中不会涉及镜像层的解压缩操作。在性能和时间消耗上,比使用docker要高效得多。

使用skopeo副本

使用skopeo sync。

docker和skopeo本质上都是通过registry的HTTP API下载和上传图片,这个过程中还是有大量的HTTP请求。如果你拿HTTPS来说,它还涉及到HTTPS加密和解密的过程,这是没有用的。那么有没有更好的办法呢?

选项3:迁移存储目录

文章开头提到harbor的后端镜像存储也使用docker注册表。只要一个注册中心使用Docker分布V2,它的后端存储目录结构就是完全一样的。那么为什么不直接打包、复制和解压harbor中registry的存储目录呢?这将确保所有映像都迁移到过去,不会留下任何映像。对于版本1。harbor的x,将docker注册表的存储目录直接迁移到harbor注册表的存储目录,然后删除harbor的redis数据(因为harbor的redis缓存了镜像的元数据信息),重启harbor后只要重启harbor 1.x,harbor就会调用后端注册表提取镜像的元数据信息并存储在redis中。这就完成了迁移工作。

备份docker注册表机器上的注册表存储目录。

备份完成后,SCP docker.tar到harbor machine,然后恢复harbor machine上的注册表存储目录。

这次迁移后,可能会遇到无法镜像到harbor push的问题。因为docker注册表容器中的注册表存储目录属于root,harbor注册表容器中的注册表存储目录属于10000:10000,两者的权限不同,会导致harbor无法推送镜像。因此,在迁移完成后,有必要修改harbor注册表目录的所有权和组。

方案4

对于harbor 2.x来说,因为harbor加强了工件的元数据管理能力,即元数据在推送或同步到harbor时要写入harbor自己的数据库。在harbor看来,只要数据库中没有这个工件的manifest信息或这个层的信息,harbor就会认为这个工件或层不存在,并返回404错误。根据第三种方案,将docker注册表存储目录直接提取到harbor的注册表存储目录是不可行的。因为镜像是解压到注册表存储中的,虽然看起来harbor的注册表容器中有镜像,但是harbor会认为没有镜像,因为harbor的数据库中没有镜像。所以现在看来只能用方案二里的skopeo把图像一张一张地推进港湾了。但是在某些特定场景下,你不可能像第二种方案一样有一个docker registry的HTTP服务,而只能有一个docker registry的压缩包。如何将docker registry的存储目录中的图像迁移到harbor 2.0?在《镜像搬运工 skopeo 初体验》中,提到了skopeo支持以下镜像格式:

需要注意的是,这几类形象的名称对应的是形象存在的方式,不同的存在方式对形象层的处理方式也不同。比如docker://这种方式存在于注册表中;Docker-daemon:存在于本地docker pull中;再比如docker-archive,是通过docker保存的镜像;和dir:图像保存为文件夹。同一个镜像有这些存在方式,就像水有气体、液体、固体一样。可以理解为都是表达同一个镜像,只是以不同的方式存在。

由于映像存储在注册表存储目录中,所以理论上以dir的形式直接从文件系统中读取映像更好。虽然skopeo支持dir格式的图片,但是skopeo目前还不支持直接使用registry的存储目录,所以还是要想办法把docker registry的存储目录中的每一张图片都转换成skopeo dir。

斯科佩奥方向

所以我们先来看看skopeo dir是什么样子的。为了方便测试方案的可行性,首先使用skopeo命令从docker hub中拉一张图片,保存为dir。该命令如下所示:

使用tree命令检查alpine文件夹的目录结构,如下所示:

从文件名和大小以及文件的自省,可以判断出清单文件对应的是镜像的清单文件;ASCII文本类型的文件是镜像映像配置文件,其中包含镜像的元数据信息。而另一个gzip压缩的数据文件只是gzip压缩的镜像层。看一下清单文件的内容也再次证实了这个结论:

镜像的配置字段对应于e50c909a8df2,文件类型为image.v1 json文本文件。

镜像的图层字段对应4c0d98bf9879,文件类型为. tar.gzipgzip压缩文件。

从注册表存储目录中获取图像。

接下来,我来到了这篇文章更精彩的地方。如何从注册表中“打捞”图像,并将其转换为skopeo支持的dir格式。

首先,您需要获得镜像的清单文件,从中您可以获得镜像的所有blob文件。例如,对于注册表存储目录中的library/alpine:latest图像,它存储在注册表中的方式如下:

1.通过repositories/library/alpine/_ manifests/tags/latest/current/link的文件获取alpine mirror lasts的manifests文件的sha256值,然后根据这个sha256值去blobs找到镜像的manifests文件;

2.根据当前/link文件中的sha256值,在blobs目录中找到对应的文件,blobs目录中对应的manifests文件为blobs/sha 256/39/39 EDA 93d 1586957 feae 28 fc 5 ADB 545276 a 64147445 c 6492 ef 69804 DBF 01/data;

3.使用正则匹配,过滤出清单文件中的所有sha256值,这些值对应于blobs目录中的图像配置文件和图像层文件;

4.根据manifests文件,您可以将所有的层和映像配置文件镜像到blobs目录中,然后将这些文件合并到一个dir格式的映像中,在该映像中,使用cp从注册表存储目录中复制映像。流程如下:

最终的图像格式如下:

与上面skopeo copy的dir文件夹相比,除了一个不相关的版本文件之外,一切都完全相同。

5.再次优化,将步骤4中的cp操作改为硬链接操作,可以大大减少磁盘的IO操作。注意:硬链接文件不能跨分区,因此它们必须与注册表存储目录在同一个分区中。

然后使用skopeo copy或skopeo sync将钓到的图像推送到harbor。

使用skopeo副本

需要注意的是,使用skopeo sync的方式是同步项目级别,镜像的名称和标签对应目录的名称。

实现脚本

其实修改skopeo的源代码也应该无缝支持注册表存储目录。

对比

对比总结以上方案:

方案一:入门成本低,适合镜像数量比较多,不需要安装skopeo的情况。缺点是性能差;

方案二:适用于两个注册中心之间同时复制图片,比如将docker hub中的一些公共图片复制到公司内网的图片仓库中。

方案三:适用于镜像仓库之间的迁移,性能是所有方案中最好的。需要特别注意的是,如果目的镜像仓库是harbor 2.x,则不能使用这种方法。

方案4:是方案3的折中版本。为了适应harbor 2.0,性能比方案3差,因为图像需要重新推送到harbor。

参考资料:《harbor权威指南》 《深入浅出容器镜像的一生》:https://blog.k8s.li/Exploring-container-image.html 《镜像搬运工 skopeo 初体验》:https://blog.k8s.li/.斯科佩奥. htmlHarbor 2.0在扩展受支持的工件方面实现了巨大的飞跃https://goharbor.io/blog/harbor-2.0/OCI

西部数码代理(chenqinet.cn)是工信部、ICANN、CNNIC认证的全球顶级域名注册服务机构,中国五星级域名注册商!超过2000万个域名通过西部数码代理注册和管理,超过100万个网站托管在西部数码代理云服务器虚拟主机。西部数码代理支持数十个顶级域名的注册和管理,支持批量查询、批量注册、批量分析、智能分析、批量迁移等便捷易用的功能,使用体验非常好。

目前西部数码代理域名注册在售,最低只要1元!

更多详情,请见http://zhuji.chenqinet.cn/services/domain/.

西部数码代理域名抢占预订,支持各类高价值老域名抢占,支持“网站历史、百度收录、百度权重、历史外链、百度评价、搜狗反链接”等综合搜索功能,共计26项!可以快速准确的定位到你想要定位的各类精品域名!同时,西部数码代理域名抢注整合了全球多家抢注厂商(将陆续增加近200家抢注厂商),梳理出13个抢注渠道,从根本上提高抢注成功率!

其中第一关成功率高达99%。每天西部数码代理预发布功能也会发布一些优质的过期域名,可以直接注册拍卖。

预定你最喜欢的域名:http://zhuji.chenqinet.cn/services/grab/index.asp.

后台-系统设置-扩展变量-手机广告位-内容页底部广告位3