天天看点

从Docker Hub和docker-registry看优秀的后端服务设计实现从Docker Hub和docker-registry看优秀的后端服务设计实现

【编者的话】 本文通过研究docker hub和docker-registry的架构,介绍了在服务端docker镜像的存储、管理、安全的架构设计,并给出了一次简单的docker客户端服务端交互的过程。对于部署实现一个大规模、企业级的镜像库需要做的工作做了初步的探讨,汇总了需要准备的前期知识等。推荐想要搭建一个私有docker镜像库的同学阅读。

<a target="_blank"></a>

最近因为工作需要,我开始研究docker-registry的实现和服务搭建。docker-registry是docker的镜像存储服务端。或者这么说,docker干的事情就是把整个应用、操作系统、配置打包成一个静态的镜像,这个镜像可以快速的启动和停止。但这种能力对单个人是没有多大意义的,我们需要有个地方把镜像存下来,然后用一个url分享给其他人。

如果是你,你会怎么设计?开一个公共的ftp让大家存镜像然后分享?这是个好主意,不过……docker的镜像有这么一个设定,就是一个镜像是由多层组成的,如果每次传输全量文件,对客户端、服务端、用户启动都造成时间和流量的浪费。

从Docker Hub和docker-registry看优秀的后端服务设计实现从Docker Hub和docker-registry看优秀的后端服务设计实现

095141_pgk8_224285.jpg

于是……

上传和下载需要智能的识别对面有没有这层,如果两边的层的uuid一致,已经有的话,就不传了。

简单的根据名字上传下载,对日常使用来说还不够方便,我们还需要一个web界面,以支持登录、搜索、区分公共的镜像和私有的镜像等需求,这是用户的需求,不是客户端程序的需求。

从Docker Hub和docker-registry看优秀的后端服务设计实现从Docker Hub和docker-registry看优秀的后端服务设计实现

103423_tffg_224285.png

每个镜像层一般都有几十兆到几百兆的大小,可以想象,当很多用户都往一个地方上传时,单个服务器的存储容量是绝对支撑不住的,需要可以水平扩展的集群,但web界面不能分开,客户端程序也不应该很麻烦的自己找去哪里下载。

从Docker Hub和docker-registry看优秀的后端服务设计实现从Docker Hub和docker-registry看优秀的后端服务设计实现

113601_lixf_224285.png

docker hub和docker-registry的分工如下:

docker hub负责管理集中的信息访问,包括:

用户账户

镜像的效验码

公共和私人镜像仓库的区分

docker hub有几个组件:

web ui

meta-data 元数据存储(附注、星级、公共库清单)

访问认证

token管理

dokcer-registry有如下几个特性:

存储镜像、以及镜像层的家族谱系

没有用户账户数据

不知道用户的账户和安全性

把安全和认证委托给docker-hub来做,用token来保证传递安全

不需要重新发明轮子,支持多种存储后端

没有本地数据库

从Docker Hub和docker-registry看优秀的后端服务设计实现从Docker Hub和docker-registry看优秀的后端服务设计实现
从Docker Hub和docker-registry看优秀的后端服务设计实现从Docker Hub和docker-registry看优秀的后端服务设计实现

这两个图里面的index就是hub,可以看到每次客户端都要先访问index,决定镜像文件从哪个registry上传或下载,然后去相应的registry操作。从阅读源码中可以看出,在registry上,每个镜像的层都是以tar.gz格式存储的。

142853_vfja_224285.png

搜索,这块我还没涉及,后续再看……

最近在研究用docker实现paas,欢迎大家有想法找我交流:-)

解耦合

docker hub是web-ui、用户认证、镜像元数据的集合,在这个方面,不同的组织有不同的做法,所以需要独立出来。docker-registry是所有组织可以复用的部分,单纯用于镜像存储服务。

不重复造轮子

docker-registry自己去实现一套对象存储了吗?没有,因为在对象存储这个领域,已经有很多优秀的实现。所以docker-registry是一个http接口的服务,仅仅是在对象存储上包了一层镜像的家族谱系,而且底层支持多种对象存储。

水平扩展性

在简单使用场景下,docker-registry也支持本地文件系统存储,可以说是all-in-one的设计,开箱即用。而当把这个场景扩展,用于大规模企业级的应用时,docker hub和docker-registry是1:n的关系,registry本身是一个无状态的服务,可以非常容易的水平扩展。这也是设计者的狡猾之处,他把有状态的部分都抽离了,把存储这个最大的状态机制做成可以放在其他的对象存储上,这样在大规模使用场景下就不会有性能的问题,也不会有单点问题。任何一个registry挂掉都是可以忍受的,可以被轻易的恢复而没有副作用。

原文发布时间:2015-01-21

本文来自云栖合作伙伴“linux中国”