架构演进
初试:Docker Machine
去年微博刚启动混合云项目时,我们首先尝试的是Docker Machine——一个官方出品的Docker环境构建工具。当时这个工具才刚推出不久,还不能直接创建阿里云ECS,也无法对CentOS进行构建,于是我们自行开发了对这两者的支持。它是一个命令行工具,原生支持创建Swarm集群,使用起来构建环境只需要简单几步:
●docker-machine create
●配置自定义的系统环境
●部署服务
对于个人使用者而言,Docker Machine非常方便,但是对于混合云项目的需求,有几点它都难以满足:
●Docker启动参数无法完全自定义,当时只能配置少数几个参数,如--insecure-registry。
●命令行对应的几个函数都是不可导出的,因此无法通过API调用,只能进行二进制依赖。
●官方宣布不支持CentOS 6.x及之前的版本,而微博内部还有一小部分CentOS 6.5的服务器。
●Docker的安装使用的官方脚本,超时问题比较严重。
●不够稳定,当时还处于开发阶段,版本迭代过于频繁。
其实在初步尝试过程中,前4点都通过修改源码解决了,但那就没办法再合入官方的代码,不是长久之计。因此放弃了Docker Machine,使用了自己设计的另一套方案。
改进:VM Image & Ansible
前面提到,我们将所有的模块分为不可变和可变两个部分,其实就分别对应了这个方案中的虚拟机镜像和配置管理。利用阿里云ECS提供的功能,把耗时长、变更很少的模块直接打到虚机镜像中,而可能变化的模块使用Ansible进行管理,能够随时执行。两部分共同构成了一套版本化的环境。如果变更的部分需要被长期使用,通过Ansible即时下发后也能够同步到镜像,保证下次构建环境时直接生效。整体设计如图3所示。
图3
我们在阿里云API的基础上,提供了一个快捷制作镜像的服务,它使用了Ansible,用户只需要编写yml描述文件,即可生成相应的ECS镜像。类似于Dockerfile,环境描述文件也支持FROM语法,对应的值就是上层镜像的名字和版本号,再加上INCLUDE和ROLE,分别定义需要执行的playbook和role,例如:
001 pFROM weibo_plat_init:1.0 002 INCLUDE user.yml 003 INCLUDE config.yml 004 ROLE hongbao
在使用ECS镜像的过程中,有两点也是需要注意的:
●使用镜像创建ECS后,ntpd的配置会恢复为阿里云默认值,如果使用自定义的需要再次修改。
●如果在构建镜像时挂载了数据盘,生成镜像前需要删除/etc/fstab中自动挂载的配置,否则该镜像将由于找不到第二块硬盘的分区而无法启动。
另外我们选用Ansible作为配置管理工具,主要因为它架构简单、依赖少,只要有SSH便可以工作;学习曲线平滑,上手比较容易;模块也足够丰富,能够满足需求。它被广泛诟病的是性能问题,我们对此进行了一些优化:
●开启SSH参数,pipelining和ControlPersist;
●优化playbook,除去非必要模块,减少远程依赖;
●callback模块异步化,Ansible自身会等callback结束才执行后续命令,这点可以大大降低高并发时的耗时;
●将需要网络传输的操作,如安装软件包、拉取Docker镜像等,内置到ECS镜像中。
最后,从阿里云ECS启动完成到初始化结束的用时被缩短到1分钟之内。