用P2P方法快速分发Docker镜像

在部署较大的容器应用集群时,把应用镜像发布到所有节点常常需要大量时间。我们VMware的研发团队测试了P2P的方法,能够较好地解决大规模镜像分发的问题,为运维实践提供了很好的指引。

概述

在使用Docker运行容器化应用时,宿主机通常先要从Registry服务(如Docker Hub)下载相应的镜像(image)。这种镜像机制在开发环境中使用还是很有效的,团队成员之间可以很方便地共享同样的镜像。在实际的生产环境中,从效率和安全角度,往往会部署私有的Registry服务,专供产线机器集群使用。当大量主机需要同时从Registry下载镜像运行容器应用时(比如发布新版本,打补钉等情形),Registry 服务往往会成为镜像分发的瓶颈,应用镜像需要较长时间才能传送到所有主机上,使得应用发布的周期大大延长。不少用户采取了预先下载镜像的方法,让各节点事先分批获取镜像,然后在预定时刻统一启动应用。这种办法在一定程度上缓解了问题,但实质上并没有解决Registry分发的瓶颈。

为了解决这个问题,我们着手设计实现了一种利用Bit Torrent协议来加速镜像分发的系统(Decentralized Image Distribution,DID),其主要思路是允许在不同的host之间共享镜像,形成分布式的P2P下载网络,提高网络吞吐量。通过测试,我们验证了该系统在集群节点数目较多、镜像较大的情况下具有较大的性能优势。

架构

图1 DID系统架构

管理界面Admin Console

管理员可以通过Admin Console定义下发镜像的任务(如集群的大小、机器的IP地址、镜像URL等),并且可实时了解任务的完成情况。

控制器

控制器是DID系统的核心组件,控制镜像分发的整个过程。当接收到来自Admin Console的镜像分发任务之后,控制器完成镜像的准备工作,并将具体的镜像下载任务下发给各个节点的客户端代理。

客户端代理

客户端代理部署在集群的每个节点中,配合控制器的调度,完成整个镜像的分发过程。代理接收来自控制器的镜像下载任务,调用BT客户端下载镜像,并最终将镜像导入到Docker daemon中。

BT客户端

部署在集群节点的BT客户端和部署在控制器中的BT客户端以及Tracker共同组成了一个完整的P2P文件传输系统。在整个镜像的分发过程中,它们利用BT协议完成镜像下载。

BT Tracker

Tracker是BT系统的一部分,它存储了BT客户端下载过程中所需要的元数据信息,并协助各个BT客户端完成整个通信过程。

镜像分发原理

当用户通过Admin Console向DID系统提交一个镜像分发任务(Job)之后,控制器会进行以下处理:

? 通过本地的Docker Daemon REST API从Registry下载镜像到本地镜像仓库;

? 调用Docker Daemon API从镜像仓库导出(export)镜像文件(镜像tar文件);

? 从镜像tar文件中抽取出组成镜像的所有layer并进行压缩;

? 为每一个压缩后的layer制作BT种子文件;

? 启动BT客户端载入所有压缩后的layer和相应的种子文件,此时控制器所在节点的BT客户端将成为一个Seeder;

? 向各个客户端代理发送该镜像的下载任务。任务说明中包含了组成该镜像的所有layer的ID和其对应的种子文件的URL。

在客户端代理接收到来自控制器的镜像下载任务后会进行以下处理:

? 针对该镜像的每一个layer,通过调用检查其在本地是否已存在,把不存在的layer ID加入到待下载列表中;

? 对下载列表中的layer,下载对应的种子文件,并启动BT客户端完成layer文件的下载;

? 通过Docker daemon的API将下载完成的layer文件导入到Docker daemon中;

? 重复步骤2和步骤3直到所有待下载layer全部被导入到Docker daemon中。注:每个layer的下载过程是并发执行的。

由于Docker的镜像是按照layer存储的,不同的镜像可共享layer,这种机制不仅减少了对存储的消耗,而且下载镜像时只需要下载缺少的layer即可,从而也就减少了镜像的下载时间。在上述DID的镜像分发过程中,我们将镜像拆分为多个layer利用BT协议进行传输。另外,由于BT协议原本是为因特网上的文件分发而设计的,有部分设计并不适用于局域网镜像集中分发的场景。比如,在BT下载过程中,每个客户端都会维护一个参与下载该文件的peer列表,默认情况下每隔1800秒BT客户端才会与Tracker进行一次通信来更新。在DID的设计中将这一时间修改为了1秒,以便各个节点的BT客户端可更快地获取其他peer的信息。

实验环境及结果

由于测试环境的限制,我们搭建了一个由10台物理机组成,每台物理机上又部署了10台虚拟机的实验环境来模拟拥有100个节点的集群场景。10台物理机连接在1Gbps的以太网交换机上。每台虚拟机都配置了2个vCPU、4GB内存和一块500GB的硬盘。

第一组实验用来比较在节点数目一定(如100个节点)的集群中,不同镜像大小对下载过程的影响。实验结果如图2所示,图中纵轴的Propagation Time是从整个集群开始下载镜像到所有节点将镜像导入所用的时间:

图2 Docker、DID镜像分发时间对比

从测试结果可以看出两点规律。一是Docker和DID的下载时间都随着镜像的增大而增大,但是DID的增长斜率较小。而且随着镜像的增大,DID的优势表现得越来越明显,例如,在镜像超过500MB后,DID所需的时间不到Docker的一半。二是存在这样的一个平衡点,当镜像小于该值时,Docker的下载速度会更快,这是由于Docker的直接下载方式在此时并未造成太多的网络拥堵。另外在用BT协议下载的过程中,BT客户端同Tracker之间以及客户端之间需要不断的进行通信,本身控制流量也有一定程度的消耗。上图中,当镜像增大到130MB以上时,BT协议带来的额外开销可以通过网络的节省来弥补,因而总体性能提升。

既然两种方式各有利弊,我们做了第二组实验来研究Docker和DID之间性能的平衡点。当Docker和DID在同一个集群中分发相同镜像所消耗的时间相等时,此时的集群节点数和镜像大小即称为一个平衡点。实验结果如图3所示:

图3 Docker和DID的平衡点

从实验结果中可以看出,随着集群节点数目的不断增大,达到平衡点所需要的镜像大小是在不断降低的。也就是说DID在集群节点数目较大、镜像较大的场景中性能优势最为明显。

我们所设计和实现的DID镜像发布机制,利用了BT协议完成镜像的分发过程,相对于Docker自身的下载方式而言,在大负荷的场景下具有较为明显的优势。原生的BT协议并不完全适应于镜像分发的使用场景,DID已经对其进行了部分优化。但是,我们相信可以调整的地方还有很多,优化之后性能应该还会有一定程度的提高。

关于镜像P2P的传输是个热门话题,目前这方面的测试数据很少。我们的测试结果可作为今后研发类似系统的基础。例如,在我们团队已经开源的企业级Registry项目Harbor中,不仅提供了完整的用户权限控制(RBAC)和友好的用户管理界面,还计划使用P2P的传输方式来增强镜像发布效率,为生产环境中快速发布容器应用提供有力的支持。欢迎大家关注和使用Harbor开源Registry项目:

https://github.com/vmware/harbor

时间: 2024-12-25 11:16:50

用P2P方法快速分发Docker镜像的相关文章

Docker快速入门——Docker镜像制作

Docker快速入门--Docker镜像制作 一.Dockerfile脚本 1.Dockerfile脚本简介 Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容就是描述该层应当如何构建.Dockerfile文件示例如下: ## Dockerfile文件格式 # This dockerfile uses the ubuntu image # VERSION 2 - EDITION 1 # Author: docker_us

Docker 镜像及Docker仓库配置 [四]

Docker 镜像及Docker仓库配置 [四] Docker 时间:2016年11月8日15:45:20 一.Docker 镜像介绍 Docker镜像构建分为两种,一种是手动构建,另一种是Dockerfile(自动构建) Docker镜像手动构建案例: 我们基于centos镜像进行构建,制作nginx镜像 [[email protected] ~]# docker run --name abcdocker -it centos[[email protected] /]# yum install

国内docker镜像

ustc是老牌的linux镜像服务提供者了,还在遥远的ubuntu 5.04版本的时候就在用.之前在blog里有提到可以用ustc的docker仓库镜像,使用方法参考ustc docker 镜像使用帮助,你要是懒得看,可以两条命令搞定(ubuntu亲测): $ sudo echo "DOCKER_OPTS=\"--registry-mirror=https://docker.mirrors.ustc.edu.cn\"" >> /etc/default/d

docker(三)docker镜像和镜像发布方法

一.从公网docker hub 拉取image ~ # 搜索docker search centos~ ? docker pull centos [email protected]2 Using default tag: latest latest: Pulling from library/centos 469cfcc7a4b3: Downloading 12.28MB/73.17MB 或者:把之前下载好的image镜像导入image docker load -i /root/centos.x

Docker 镜像创建方法

Docker 镜像创建方法 Docker镜像创建方法 创建镜像的方法有三种,分别是基于已有的镜像创建.基于本地模板创建.基于Dockerfile 创建,下面着重介绍这三种创建镜像的方法. 一.基于已有镜像创建 首先将镜像加载到容器,将容器里面运行的程序及运行环境打包起来生成新的镜像,需要记住该容器的ID号.命令格式: docker commit [选项] 容器ID/名称 仓库名称:[标签] 常用选项: -m:说明信息 ?-a:作者信息 ?-p:生成过程中停止容器的运行 例子: docker cr

docker镜像的制作和容器的运行

docker镜像的制作以及容器的运行 前言:docker安装对Linux的内核要求3.8以上版本,可以通过uname -r查询linux内核另一个要求必须运行在64位的操作系统上:现在的docker可以运行在windows系统和Linux系统实现跨平台. 介绍docker: Docker的英文本意是"搬运工",在程序员的世界里,Docker搬运的是集装箱(Container),集装箱里装的是任意类型的App,开发者通过Docker可以将App变成一种标准化的.可移植的.自管理的组件,可

快速掌握Docker必备基础知识

快速掌握Docker必备基础知识 Docker是时下热门的容器技术,相信作为一名开发人员,你一定听说过或者使用过,很多人会把Docker理解为一个轻量级虚拟机,但其实Docker与虚拟机(VM)是两种不同的计算机虚拟化技术,也有很多人会觉得,有了虚拟机,那为什么还要使用Docker呢? 带着心里的一点点疑问,让我们一起来学习Docker吧. 没有虚拟化技术的原始年代 我们仔细想想,在没有计算虚拟化技术的“远古”年代,如果我们要部署一个应用程序(Application),一般的步骤是怎么样的? 第

如何交互式地创建一个Docker镜像

今天我们来学习如何使用一个docker镜像交互式地创建一个Docker镜像.当我们从镜像中启动一个Docker进程,Docker就会获取该镜像及其父镜像,并重复这个过程,直到到达基础镜像.然后联合文件系统(UFS)会在其顶层添加一个读写层.读写层被称之为容器,它包含了一些关于父镜像信息及一些其他的信息,如唯一ID,网络配置和资源限制等.容器是有状态的,其状态可以从 运行态 切换到 退出态.一个处于 运行态的容器包含了在CPU上面运行的进程树,于其它在该主机上运行的进程相隔离,而退出态是指文件系统

Docker源码分析(九):Docker镜像

1.前言 回首过去的2014年,大家可以看到Docker在全球刮起了一阵又一阵的“容器风”,工业界对Docker的探索与实践更是一波高过一波.在如今的2015年以及未来,Docker似乎并不会像其他昙花一现的技术一样,在历史的舞台上热潮褪去,反而在工业界实践与评估之后,显现了前所未有的发展潜力. 究其本质,“Docker提供容器服务”这句话,相信很少有人会有异议.那么,既然Docker提供的服务属于“容器”技术,那么反观“容器”技术的本质与历史,我们又可以发现什么呢?正如前文所提到的,Docke