##需求html
最近由于工做须要,开始研究docker-registry的实现和服务搭建。docker-registry是啥呢?就是目前很火的容器docker的镜像存储服务端。python
或者这么说把,docker干的事情就是把整个应用、操做系统、配置打包成一个静态的镜像,这个镜像能够快速的启动关闭为一个动态的运行容器。但这种能力对单我的是没有很大意义的,咱们须要有个地方把镜像存下来,而后用一个url或者连接分享给其余人。git
若是是你,你会怎么设计?开一个公共的FTP让你们存镜像而后分享?这是个好主意,不过……docker的镜像有这么一个设定,就是一个镜像是由多层组成的,若是每次传输全量文件,对客户端、服务端、用户启动都形成时间和流量的浪费。github
因而……web
需求一:远程存储服务,上传和下载须要智能的识别对面有没有这层,若是两边的层的uuid一致,已经有的话,就不传了。spring
简单的根据名字上传下载,对人平常使用来讲还不不够方便,还须要一个web界面,让人能够登录、搜索、区分公共的镜像和私有的镜像,等等,这是人的需求,不是客户端程序的需求。sql
需求二:web界面,支持搜索docker
每一个镜像层的大小约为几十M到几百M之间,能够想象,当不少人都往一个地方上传时,单个服务器的存储容量是绝对支撑不住的,须要能够水平扩展的集群,但web界面不能分开,客户端程序也不该该很麻烦的本身找去哪里下载。数据库
需求三:支持水平扩展的集群存储flask
docker-hub和docker-registry的分工以下:
##docker-hub
负责保存集中的信息访问,关于
docker-hub有几个组件:
有这么几个特性
这两个图里面index就是hub,能够看到每次客户端都要先访问index,决定镜像文件从哪一个registry上传或下载,而后去相应的registry操做。从阅读源码中能够看出,在registry上,每一个镜像的层都是以tar.gz格式存储的。
既然是私服,一样须要考虑用户、安全认证、搜索等问题,能够说,docker的开发者在设计镜像服务时就考虑了这些问题,把Web这块留给每一个私服的开发者本身去实现,把后端存储抽象成接口来调用。docker-registry的源代码放在这里 。为了保证后续的正常开发使用,我决定先阅读一下这个源码,不过碰上了很多问题:
docker-registry是用python实现的,我对python的了解仅仅限于简单的脚本,对python的包、模块、类都不大懂,因此我学习了python
docker-registry使用了egg打包发布,gunicorn做为应用服务器(相似tomcat),flask做为mvc框架(相似spring),后面还有sqlalchemy做为搜索后端。这些技术都须要作简单的了解,在须要的时候深刻学习。
后端存储,由于镜像最终是以tar.gz的方式静态存储在服务端,不须要实时read或write,因此适用于对象存储而不是块存储,因而问题就转化成找一个或写一个私有的存储驱动,官方支持的驱动有亚马逊AWS S三、ceph-s三、Google gcs、OpenStack swift,glance等等,国内的七牛也写了本身的驱动 ,后面在个人环境须要本身写一个驱动。
搜索,这块我还没涉及,后续再看……
Web UI的实现,如今github上已经有好几个项目了,例如docker-registry-web ,docker-registry-frontend,后续再看……
最近在研究用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挂掉都是能够忍受的,能够被轻易的恢复而没有反作用。