一种基于分布式存储的Docker镜像下载方法与流程

文档序号:12132511阅读:453来源:国知局
一种基于分布式存储的Docker镜像下载方法与流程

本发明涉及互联网领域中的虚拟化方法,特别是涉及通过分布式存储加速批量下载Docker镜像的方法。



背景技术:

Docker是一个开源的应用容器引擎,旨在提供一个可以运行应用程序的解决方案,做为目前最流行的轻量级虚拟化技术,因为资源利用率高及启动速度快,一度被认为是虚拟机的替代品。例如,可以在Linux系统上迅速创建一个容器container(轻量级虚拟机),部署和运行应用成许,并通过配置文件可以轻松实现应用程序的自动化安装,Docker可以虚拟出多个容器,容器之间可以互相独立。但发展到现在,Docker技术并没有虚拟机发成熟,虚拟机是一项高度发展、非常成熟的技术,可以运行最关键的业务工作负载,而Docker依旧在开发过程中,网络栈、安全性、命名空间隔离以及集群管理等依然有很多领域需要改进,同时如何加快Docker镜像的下载从而提升私有集群中多台机器启动相同容器时的速度也是亟待解决的问题。

Docker镜像作为容器运行环境的基石,彻底解放了Docker容器创建的生命力,开发者可以用一个标准的镜像构建一套容器,容器开发完成后可以直接使用这个容器部署代码,镜像下载过程中需要Docker架构中多个组件的协作。虽然每台运行Docker的机器上本身都保存着部分镜像,但Docker还有集中存储镜像的地方,Registry就是为集中管理、管理和分发Docker镜像而设计的项目,目前推荐使用的是Registry的第二个版本,即用golang语言实现的Distribution项目。Docker公司维护了一个类似于github的官方的镜像存储网站DocHub,所有Docker用户都可以申请帐号并从DocHub下载需要的镜像或者上传镜像供他人使用。同时,用户也可以通过在私有集群中部署Distribution来管理该集群中的镜像,本实施例中的方法主要是基于布有Distribution的私有集群中的镜像存储和下载提速方式。

目前关于Docker镜像如何在Distribution中存储的研究主要关注的是针对Docker镜像分层的特点,为Distribution开发可以加快镜像查找和下载速度的新的存储系统,或者为现有的文件系统开发驱动。

(1)为现有存储系统提供driver

为Docker Distribution提供的官方的后端存储系统编写driver,大体推荐选择的存储系统有这几个:Local Filesystem、S3、Swift、glance、Google gcs。Local Filesystem这个可能在镜像很少的情况下出于简单性会选择使用,主要问题显而易见,扩展性、可用性方面都受到很大的约束。Swift是一个Consistent Hash的拓扑结构,添加机器需要迁移一部分数据过来,分布式文件系统中文件的潜移导致带宽占用会比较大,影响线上服务。S3解决方案对很多不想自己开发文件系统,但同时希望镜像存储端有不错的扩展性及可用性方面的能力的企业来说也是一个可行的选择。

上述方法通过使用分布式存储系统增加了Distribution存储Docker镜像的扩展性和可用性,但由于这些通用的存储系统并非针对于Docker镜像分层并且每个层次大小差别很大的特点设计的,所以对于存储、检索和下载Docker镜像的效率并没有提高。

(2)设计新的Docker镜像存储系统

Speedy是京东公司开发的Docker镜像存储系统,存储上将多个小文件合并成一个大文件存储,减少元数据存储空间开销和性能开销,同时在原生文件系统上通过预分配空间方式,提供接近裸盘的读写性能,但兼具原生文件系统的易用性,针对大文件做优化,提供断点续传、失败重试等功能。

在上述方法中,京东虽然通过针对Docker镜像的特点编写了特定的存储系统,并通过使用专用的数据库来存储元数据等方式加快了镜像查找下载速度,使存储本身已经不是瓶颈。但Distribution所在节点网卡的性能成为了新的瓶颈,该结构并不能摆脱单点瓶颈问题。

综上,无论是为现有存储系统写驱动还是针对Docker镜像编写新的存储系统,在现有Distribution架构下,都不能避免Distribution节点的网络瓶颈问题。



技术实现要素:

本发明针对现有技术的不足,结合Distribution和分布式文件系统设计新的镜像分发架构,利用分布式文件系统将镜像分片存储,Docker节点(这里的节点指的是物理计算机节点,下文中类似术语皆指物理节点)向Distribution节点发送请求时只传送元数据,真正的数据去实际的分布式存储节点中去取,从而真正缓解Distribution节点的网络瓶颈。

为了解决上述技术问题,本发明提供一种基于分布式存储的Docker镜像下载方法,其步骤如下:

步骤S101:将分布式文件系统挂在Registry节点存储镜像的目录,并且集群中所有节点都要创建与Registry节点存储镜像目录相同的目录并挂载分布式文件系统;

步骤S102:集群中的Docker节点向Registry节点请求下载镜像;

步骤S103:Registry节点根据Docker节点的请求确定镜像层数据在分布式文件系统中的存储位置,并将获得的镜像元数据返回给Docker节点;

步骤S104:Docker节点根据从Registry节点接收到的元数据确定镜像数据的存储位置,并直接到存储节点提取镜像数据。

步骤S101进一步包括:Registry节点在启动时会指定一个yml文件作为参数,在该文件中设置Registry节点存储Docker镜像的目录、所用的缓存、提供服务的端口以及后端存储的驱动等内容。在与Docker节点建立连接前,Registry节点先要进行初始化,在初始化的过程中确定要使用的后端存储,并加载相应的驱动。

步骤S102进一步包括:集群中的运行Docker的节点向运行Registry的节点请求下载需要的镜像,集群中运行着Docker的机器启动要使用的容器,如果这些要启动容器的节点上没有对应的镜像,Docker节点根据Registry所在节点的IP地址和提供服务的端口号等参数,向Registry节点请求下载镜像,这些请求被发送至Registry节点。

步骤S103进一步包括:Registry节点查找是否存在要下载的镜像,如果不存在则返回无相应镜像标识;若存在则Registry会从分布式文件系统读取Docker镜像的manifest并传递给Docker节点,其中manifest包含镜像所含所有层的哈希值。Registry根据解析manifest得到的镜像包含的所有层的哈希值及各层之间的依赖关系,获取镜像层的存储目录位置,根据获取的所述存储目录位置读取出镜像层文件存储的目录、文件名、大小等元数据,之后将这些元数据传递给Docker节点。

进一步的,其中所述所有层的哈希值是使用安全散列算法SHA-256对镜像层数据进行运算,得出的256位长的消息摘要。

步骤S104进一步包括:Docker节点将从Registry节点接收到的镜像层的存储目录和文件名作为输入,通过一致性哈希算法计算出哈希值,确定镜像层在分布式文件系统中的实际存储位置,并通过通用的posix标准接口读取镜像数据,通过哈希校验镜像数据完整性并启动容器。

进一步地,哈希校验具体是:Docker节点从分布式存储系统读取完镜像层数据后,对读取的镜像层数据用SHA-256算法做运算,如果得出的256位的哈希值和manifest中存储的对应的哈希值相等,则说明读取的数据是完整,否则说明读取数据的过程出错。

采用本发明可以达到以下技术效果:

当集群中运行有Docker的大量机器同时向运行有Distribution的节点请求下载Docker镜像时,避免了原始架构中Distribution节点容易成为网络瓶颈的弊端,将数据下载流量均匀分散到分布式存储系统所处的机器上,从而加速了镜像分发过程。

附图说明

图1为本发明基于分布式存储的Docker镜像批量下载方法的流程图;

图2为本发明基于分布式存储系统Glusterfs为例的分布式存储的Docker镜像批量下载方法的简化架构示意图;

图3为本发明基于分布式存储的Docker镜像批量下载方法的详细操作流程图;

图4为本发明基于分布式存储的Docker镜像批量下载技术的数据流图。

具体实施方式

为了使本申请中的技术方案被更好地理解,下面将结合本申请实施例中的附图和具体实施方式,对本申请进行清楚、详细的描述。

首先对本发明涉及的术语及逻辑关系定义如下:

Docker是一个开源的应用容器引擎,它经常被用于和虚拟机相对比;与虚拟机启动镜像类似,Docker也需要基于具体的镜像来启动,Docker将镜像启动后就形成一个容器;与虚拟机镜像不同,为了减少存储空间并减少分发镜像时的数据下载量,Docker镜像被设计成分层(layer)的,同一个镜像的layers通过union mount的方式连接成一个完整的镜像,同时,当两个不同的Docker镜像含有相同的layer时,只需要存储一次,节省了存储空间;为了便于管理镜像,Docker设计了manifest结构,该结构定义了Docker镜像包含了哪些layer和这些layer之间的依赖关系;同时,为了统一的存储、管理和分发Docker镜像,Docker公司还牵头开发了Registry项目,集群中运行Docker的机器可以向Registry上传镜像供他人使用,也可以下载镜像,目前Registry已经出现了使用较广的第二代版本,即Distribution项目。另外,在本文中节点指的是Docker、Distribution或者分布式存储系统所在的物理机器;集群指的是运行着Docker,并且包含运行着Distribution的节点的私有计算机集群。本文方案可统一在Registry下实现,而不仅限于Distribution项目。

参见图1,该图示出了本申请的基于分布式存储的Docker镜像批量下载方法的流程。该实施例包括:

1、步骤S101,将分布式文件系统挂载在Registry节点存储镜像的目录,并且集群中所有节点都要创建与Registry节点存储镜像目录相同的目录并挂载分布式文件系统。

更具体地,包括:确定Registry节点存储Docker镜像的目录,在该运行Registry的节点上将要使用的后端存储系统挂载到该存储Docker镜像的目录,同时在集群中的所有节点上创建与Registry节点的镜像存储目录相同的目录,并将使用的分布式文件系统挂载到目录上。

很多分布式存储系统的挂载方式已经做的非常简单,比如Glusterfs、Ceph可以用linux下载mount命令直接挂载存储目录,此处所说的集群是实体计算机集合,节点是一台计算机。

2、步骤S102,集群中的运行Docker的节点向运行Registry的节点请求下载需要的镜像,集群中运行着Docker的机器启动要使用的容器,如果这些要启动容器的节点上没有对应的镜像,那么Docker节点会向Registry节点请求下载镜像,即会从运行Registry程序的节点下载镜像。

Docker在通过run命令启动容器而Docker宿主机并不含有运行该容器对应的镜像或者Docker通过pull命令直接下载镜像时,如果在集群中已经运行了Registry,并且Docker运行命令run或者pull命令时添加了Registry所在节点的IP地址和提供服务的端口号等参数,这些请求就会被发送至Registry节点。

3、步骤S103,Registry节点根据Docker节点的请求中所带有的具体参数确定要下载的Docker镜像数据在分布式文件系统中的存储位置等数据,并将获得的数据返回给Docker节点。由于镜像由许多层构成,镜像数据实际就是镜像层的数据。这里首先说明Registry存储镜像层目录的特点,在Registry中,镜像层存储位置的前面几级目录是固定的,最后一级目录是以镜像层为输入通过安全散列算法SHA-256计算出的哈希值。

进一步地,其中包括将Docker镜像的manifest传递给Registry,manifest是描述整个镜像组成的一个数据结构,其中包含镜像所含所有层的哈希值,这个哈希值是使用安全散列算法SHA-256对镜像层数据进行运算,得出的256位长的消息摘要。Registry通过解析manifest得到镜像包含的所有层的哈希值获取镜像层的存储目录位置。一旦获取了镜像层的存储位置,Registry就可以读取镜像层的目录、文件名、大小等元数据,并将这些数据传递给Docker节点。

Registry解析镜像的manifest获取出SHA哈希值。Docker在上传镜像时会上传镜像对应的manifest,里面已经含有了每层SHA哈希值,如果不含有,那么在上传过程中会运行SHA-256算法,计算出该值并填入manifest,所以在registry只需要从manifest读取就可以。

因为在Registry中,为了节约存储空间,一个Docker镜像包含的镜像层并不集中存储到一块儿,各镜像层分开存储,其存储的前面几级目录都是确定的,只有最后一级目录是该层在manifest中对应的哈希值。这样,Registry在解析了manifest并得到各层对应的哈希值和依赖关系后,便可以拼接出镜像层存储位置的目录。在原来的架构中,这里会继续读取镜像层内容并传给Docker节点。

在原始的架构中,Registry在接收到镜像下载请求时,通过解析manifest得到标识镜像层的哈希值并拼接出镜像层的具体存储目录后,会继续去Registry的存储后端提取镜像数据返回给Docker节点,当存储后端并不是Registry所在节点的本地文件系统后,则会首先将镜像数据从存储后端所在的机器读取到Registry节点然后再传送到请求镜像的Docker所在节点,即整个镜像数据都要通过Registry节点,Docker接收到镜像的所有层的内容后,可以通过解析的依赖关系拼接成整个镜像。这种松耦合的存储结构有效避免了镜像层的重复存储;而在我们发明的架构中,Registry在解析出镜像层的存储位置目录后,会继续根据获取的位置信息读取出镜像层文件存储的目录、文件名、大小等信息,之后将这些镜像层数据的目录名、文件名、大小等元数据传递给Docker节点。

4、步骤S104,Docker节点根据从Registry节点接收到的数据得到镜像数据的存储位置,并直接到分布式存储节点提取镜像数据:Docker在执行run命令运行特定镜像对应的容器或者执行pull命令直接下载镜像时,该Docker所在的机器中不再是直接从Registry所在节点提取镜像数据了,而是根据Registry返回的元数据信息直接去分布式存储节点提取数据,通过一致性哈希算法计算出哈希值,确定镜像层的实际存储位置,并通过通用的posix标准接口读取镜像数据,这样大大缓解了Registry所在节点的网络压力。

这里所用的一致性哈希算法与上面manifest中存的计算镜像层的哈希算法是不同的,计算镜像层哈希值用的是安全散列算法SHA-256,是为了用一个固定的256位长度的字符串指代镜像层,该算法产生的哈希值会根据输入的镜像层内容不同而改变,且重复的概率几乎为零;而一致性哈希算法,是一种分布式哈希实现算法,在这里解决的是文件的定位问题。具体的实现方式是,一致性哈希算法将输入的文件目录和文件名,经过哈希计算后散列到一个环上,之后将运行有分布式文件系统的机器也通过该算法映射到环上,这样文件对象和机器位于同一个哈希空间中,就能快速定位对象位于的机器了。

接收到数据后再通过做哈希校验数据完整性。这里哈希校验的目的是为了确保Docker根据Registry返回的元数据而从分布式文件系统读取的数据的完整性,具体校验方法是,前面我们说过manifest中存储着镜像包括的所有层的哈希值,这个值是通过以镜像层数据为数据通过SHA-256算法计算出的可以唯一标识对应镜像层的256位长的字符串,这里在Docker节点从分布式存储系统读取完镜像数据后,如果这个数据是完整的,那么再对这个读取的镜像层数据用SHA-256算法做运算,得出的256位的哈希值应该是和manifest中存储的对应的哈希值是相等的。如果不相等,说明读取数据的过程出了错。

步骤S101中已经将分布式文件系统挂载在Registry节点存储镜像的目录,并且集群中所有Docker节点都已经创建了与Registry节点存储镜像目录相同的目录并挂载分布式文件系统,根据分布式文件系统比如Glusterfs、Ceph的原有特性,在Docker节点上访问挂载的目录下的文件其实和在Registry节点上访问挂在目录下相同文件最后访问到的其实是同一个数据。另外,Registry节点在存储镜像层数据时,是以镜像层数据存储的目录和文件名为输入,通过一致性哈希算法计算得出这些数据在分布式文件系统中的实际存储位置的。又因为,Docker节点上在相同目录同样挂在了存储镜像的文件系统,所以在Docker接收到Registry传递来的包含镜像层存储目录、文件名、大小等信息时,可以依然以存储目录和文件名为输入再次通过一致性哈希算法计算得出镜像在分布式文件系统中的具体存储位置,从而可以绕过Registry节点直接到分布式文件系统去读取数据。

Docker的镜像下载包括集群中的多台机器,涉及Registry节点、Docker节点和分布式存储系统所在的节点。

步骤S101中,集群中节点,即物理机,在分布式存储节点上要预先装上要用的文件系统,其他节点上装上该文件系统的客户端。Registry在启动时会指定一个yml文件作为参数,在该文件中设置Registry存储Docker镜像的目录、所用的缓存、提供服务的端口以及后端存储的驱动等内容。这里,不同的后端分布式文件系统需要不同的驱动,现在也有很多机构为Registry针对不同的存储系统编写不同的驱动。但是,在本发明中作为Registry后端存储,并不是简单地为Registry针对要使用的分布式文件系统写一个驱动,而是使该文件系统可以无缝的存储镜像。

如图2示例所示,结合Docker镜像下载过程,以分布式文件系统Glusterfs为例,改变从Registry下载镜像的架构实现Docke与Registry交换元数据,而从分布式文件系统接收实际镜像数据。这种实现,对Registry和Docker两端的源码都进行了更改。

在具体介绍图2代表的流程之前,首先对该图中的模块做简要说明,该图中右侧标记有Docker的模块指的是运行有Docker程序的物理机器,其左侧标有Docker Registry和Glusterfs Client的模块指代的是运行有Registry程序的机器,为了实现发明中描述的功能,在此机器上还安装了分布式文件系统Glusterfs的客户端,下面三个标有Glusterfs Server的模块指代的是安装有分布式文件系统的机器,途中的连线指的数据传输过程。

在改变架构之前所有数据都是通过图2中的虚线所示的通道传递的,Docker会首先向Registry发出下载镜像的请求,之后Registry会根据Docker请求的镜像以及在与Docker交互的过程中得到的要下载的镜像的manifest,Registry根据解析manifest得到的镜像包含的层的哈希值以及层之间的依赖关系等数据等直接定位镜像数据的存储目录,这个哈希值是以镜像层数据为输入,通过SHA-256算法计算出的可以唯一标识对应镜像层的256位长字符串;然后再以镜像层的存储目录和文件名为输入,通过一致性哈希算法定位镜像数据在分布式文件系统中的具体存储位置并读取镜像数据,之后经过Registry节点传递到请求下载镜像的Docker节点,可见整个过程都要经过Registry节点,从而Registry节点成为瓶颈。

本发明改变架构之后,只有镜像的元数据以及Registry和Docker间的控制流的交互是通过图2中的虚线指示的通道传递的,而真正的镜像数据的传输则是通过图2中实线所指的通道实现的。本发明中结合已经在Registry节点、Docker节点和分布式存储结点挂载的目录更改Docker在下载镜像时的代码和Registry在接收到Docker发送来的镜像下载请求时的处理方式的代码,Registry中屏蔽了原来接收到Docker发送请求时的处理函数,新增了接收到Docker发送层下载请求时确定该数据存储目录以及文件名、文件大小的函数,并通过HTTP发送给Docker;Docker端新增加了接收到从Registry端接收到数据存储目录、文件名数据时的处理函数,此时Docker节点会以得到的镜像层存储目录和文件名为输入,通过一致性哈希算法计算,确定镜像层在分布式文件系统中的实际存储位置,直接去提取。

在与Docker建立连接前,Registry先要进行初始化,在初始化的过程中确定要使用的后端存储,并加载相应的驱动。

步骤S102中,本发明虽然改变了Registry与Docker交换实际镜像的方式,将原始的交换数据必须经过Registry节点的架构改变为了交换实际镜像数据时Docker会绕过Registry节点之间从分布式文件系统所部署的机器上提取的方式,但是并没有破坏Docker原本的使用方式,只要做好了本发明系统所有的准备工作,集群中的机器在启动大量容器时只需像之前一样运行run命令就可以,Docker会正常通过本发明中的数据传输流程下载镜像并做好hash校验后存储到本地,并基于通过本发明系统下载好的镜像运行容器。

步骤S103和S104描述了从Registry接收镜像下载请求到Docker接收到镜像数据的全过程,流程如图3所示,具体如下:

Docker节点通过下载镜像或者运行容器的命令向Registry节点请求要下载的镜像;

Registry节点和Docker节点间相互认证建立安全连接;

Registry节点接收请求并根据初始化时注册的Handler提供服务,其中Handler包含的是Registry节点在接收到Docker节点发送来的请求时的处理函数。本发明实现的结合后端分布式存储系统从而仅通过Registry传递元数据,具体镜像数据绕过Registry节点,其中就改变了Handler中了部分代码,并新添加了向Docker返回文件存储目录数据信息的函数,相应的也在Docker的源码中添加了向分布式文件系统中读取镜像数据的函数。本发明中元数据的传输并没有绕过Registry节点,因为元数据原本就很小,不会占用太多流量,假如绕过Registry在判断完整性方面反而会有延迟。所以,本发明中,Registry会根据在初始化时注册的存储驱动以及在步骤S101中挂载的文件系统,去查找是否存在要下载的镜像,如果不存在返回无相应镜像标识,若存在则首先从文件系统中读取镜像的manifest到Registry节点,之后返回给Docker节点;

前面已经解释过每个镜像对应的manifest结构包含了该镜像所包含的所有layers(镜像层)的名称、大小、依赖关系等数据。Docker接收到从Registry返回的manifest后会读取manifest中包含的镜像层并与本地存储的镜像层做对比,找出本地不存在的层返回给Registry节点;

接下来,按照原来的架构Registry会继续从后端存储系统中读取实际镜像数据,然后经过Registry节点中转最后传递给Docker节点;

本发明中,这次Registry接收到请求后,并不会直接去分布式存储中读取镜像层数据,而是根据接收到的层的名称确定该层对应的存储目录以及对应文件大小等元数据,之后Registry节点将这些元数据传递给Docker节点;

Docker节点由于在准备阶段也创建了与Registry节点指定的存储镜像的目录相同的目录,并也在目录上与Registry节点挂载了同样文件系统并做了相应配置,故Docker节点可以将从Registry节点接收到的镜像层的存储目录和文件名作为数据,根据分布式文件系统使用的通过对镜像层存储的目录以及文件名计算分布式hash值,确定镜像层的实际存储位置,具体可以得出镜像存储位置的原因已经在前面有过描述,并通过通用的posix标准接口读取镜像层的数据,即镜像层数据。

具体的数据流如图4所示,这里首先对图中包括的模块做简要解释,图中右侧标有Docker的模块指的是运行有Docker程序的物理机器;左侧标有Distribution FrontEnd的比较大的模块指的是运行有第二代版本的Registry,即Distribution的物理机器,其中,Configuration模块是用来Distribution启动时注册所使用的后端存储驱动、服务端口号等数据的,App中做得是将Configuration中读取到的配置数据加载到具体的对象并运行对象对外提供服务,Http Server做的是监听Docker连接和请求、并把处理结果返回给Docker,Router是一个分发器,根据接收到的请求的不同分发到不同的Handler,Handler就是接收到请求后使用的具体处理函数了;下方标有Distribution BackEnd的模块指代的是安装有分布式文件系统的物理机器,因为其要存储位于Distribution中的Docker镜像,这里将其命名为Distribution BackEnd;其通过linux中的mount命令挂载到Distribution节点,即图中Mount模块。其中步骤①指的是Docker发送镜像下载请求,步骤②是指Registry从后端分布式存储提取manifest数据并返回给Docker,因为每个Docker镜像都对应一个manifest,manifest中记录了镜像包含的镜像层(layer),前面说过layer存储的前面几级目录都是固定的,只有最后一级目录是通过计算layer的hash值得到的,而且manifest中记录了layer的hash值,所以这里根据拼接起的目录读取manifest并不困难,步骤③是指Docker通过接收到的manifest计算得出本地不存在的镜像layer并就需要下载的层再次发送请求到Registry,步骤④指的就是Registry去后端存储提取实际镜像数据的元数据并传送给Docker,这里所说的元数据主要是指镜像层的存储目录、文件名以及大小等,将这些数据传递给Docker,让Docker可以据此计算出镜像层的实际存储位置,与上面所述类似,因为镜像层的存储目录有规律,所以这部读取元数据并不困难,步骤⑤便是Docker根据从Registry接收到的镜像元数据信息直接去后端存储中去读取实际镜像数据。

本发明目的是为了通过用分布式文件系统做为Registry存储后端并绕过Registry直接传递镜像数据到Docker节点,从而减轻Registry节点的网络压力。所以,如何让容器镜像数据均匀的分布到存储节点从而让Docker节点可以同时从尽可能多的节点下载数据成为关注点之一。经过大量尝试和实验,本发明指出分布式文件系统中的分片最能实现该目的,通过分片的方式可以将一个比较大的layer分成几乎大小相等的数据片,从而均匀的分散到分布式文件系统所处的机器上,继而分散了网络流量,比如Glusterfs中的stripe卷。在Glusterfs中只需确定存储系统所使用的机器,在挂载到镜像存储目录时加上stripe参数便指定为了分片的存储方式,同时在挂载时还可以在参数中指定分片的大小,分片太大或者太小效果都不会太明显,太大了超过了一些镜像layer的总大小会使镜像在文件系统中的分布不均匀,太小了导致元数据操作太频繁,经测试3M-4M这个区间比较合适,在五台存储节点以及由10台机器构成的Docker集群的基础上测试镜像下载速度已经提升了3倍以上,随着集群规模的增大,这个速度的提升将更加明显。

Docker节点从分布式存储中读取完数据后要做的就是对从各存储节点读取来的数据进行合并,之前提到过在运行Docker的机器上也挂在了Glusterfs的客户端,这一步就是Glusterfs客户端完成的,合并完成后做hash完整性校验,在确定了镜像完整性后就可以在此基础上启动容器了。

本发明不仅仅是对镜像的下载过程做了优化,同时也改变了镜像的上传流程。

Docker节点在保存对镜像的更改后,如果想上传到Registry并分享给集群中其他节点使用时,像未改动之前一样,可以直接将要分享的镜像作为参数通过docker push命令本上传到Registry,本发明未对镜像处理的命令做任何改动,这也是该实施例的一个优点。

同下载流程相似,在本发明中,在完整准备工作并做好初始化后,依旧是仅仅通过Registry传递镜像元数据,而需要上传的实际数据则绕过Registry直接写入到分布式文件系统,这是本发明的另一个实施例。

Docker镜像在执行上传时,首先会向Registry发送请求并发送要上传的镜像层元数据,但是并不会直接将镜像数据上传,Registry接收到元数据后经处理会返回给Docker端一个目录,由于所有节点在准备阶段已经做好分布式存储系统的挂载等初始化工作,Docker可以根据接收到的目录绕过Registry直接通过通用的posix接口向分布式存储系统写数据。每上传一层,Docker都会在镜像对应的manifest中填写该layer层的元数据消息。通过循环的方式将镜像各layer的数据上传完后,便完成了整个镜像manifest的组织,然后将该manifest传递给Registry。之后,Registry就可以根据此来通过hash方法校验写入到存储系统中的数据的完整性了。上述流程完成后,镜像便组织到Registry中,集群中其他机器又可以下载使用该上传的镜像了。

通过本发明方案的处理,可以分散镜像下载时流过Registry节点的数据量,避免了Registry成为整个系统的瓶颈,从而提高了分发镜像的速度。本发明已经对该方法进行了实现和测试,经测试在含有五台分布式存储节点、一台运行Distribution的节点和十台运行Docker的节点中,镜像下载速度提升了将近三倍以上,当集群规模增大时,还会有更大的提升。

最后所应说明的是,以上实施例仅用以说明本发明的技术方案而非限制,尽管参照较佳实施例对本发明进行了详细说明,本领域的普通技术人员应当理解,可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明技术方案的精神和范围。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1