原作者 葛林@天云软件
Docker自从发布以来,短短不到2年的时间迅速成长为各家争先追捧的宠儿,各家企业都希望能够借助Docker来提升自己的产品、优化现有的研发流程。本文分享Docker在天云软件分布式服务研发过程中的应用与实践,主要介绍使用Docker、Compose构建分布式服务的CI/CD体系;容器技术的引入为天云软件的SkyForm CMP带来了哪些变化;围绕着CI/CD,如何使天云软件在日常研发活动中变得更加敏捷、高效。
SkyForm CMP是一款中立、包容的能够对多种异构资源实现统一管理的云系统软件。SkyForm CMP能够为用户提供简单、统一的管理平台,内置丰富的资源管理与交付功能,可以对原本静态的IT基础设施进行管理、调度和按需分配。
SkyForm CMP的核心子服务是由SkyForm Cloud Service Gateway、SkyForm Cloud API和各种功能组件、云平台驱动构成的SkyForm Multi-Cloud Engine。其中SkyForm Cloud Service Gateway对各种私有云、公有云进行统一的抽象并管理各种系统的不同能力, SkyForm Cloud API则对外提供抽象OpenStack兼容的API并提供特定功能的扩展。虚拟化平台(如VMware)、开源云OS平台(如CloudStack和OpenStack)、容器技术(如Docker)以及公有云(如AWS)通过Driver接入SkyForm CMP以满足多种应用场景的需求。SkyForm CMP的架构图如下所示。
SkyForm CMP包含的服务大体上可以分为9大块,各服务之间的交互关系,如下图所示。从图中可以看出,各服务之间的耦合度都比较高,有的服务之间还形成了回环,在这种情况下,不论是部署还是调试都很不便,虽然我们也通过一些方式,比如自动化安装脚本、自动构建工具来简化操作,提升效率,但是效果仍然不太明显。
由于SkyForm CMP组件繁多、配置复杂、打包部署繁琐等因素,使得研发与QA在日常的工作中都会觉得效率不高,QA每天要花费相当长的时间来搭建打包、搭建测试环境,研发在进行调试时,由于环境搭建比较耗费时间,配置复杂,往往不得已会想QA借用测试环境来进行调试,这样会使测试结果的有效性大打折扣。即便研发自行搭建一套环境,但还是会出现研发共用一套环境进行调试的情况。我们的研发和QA都希望:
Docker一经发布,就以它的轻量、敏捷、灵活等特点,迅速被大家接受和认可。成为大家关注的热点,也正是因为这些特点,使我意识到,Docker也许能够解决我们研发过程中遇到的问题,下面,就让我们来看看,当SkyForm CMP遇上Docker之后,SkyForm CMP会发生怎样的变化。
为了使SkyForm CMP容器化,我们做的第一件事就是服务拆分、微服务化,通过改造,我们将下图中标记黄色框的组件进行了容器化。
改造之后,SkyForm CMP里各服务组件的交互关系也变得清晰了很多,耦合度也降低了很多。拆分完成后,我们将各服务组件进行打包,送上了持续集成的流水线。
持续集成采取的方式与大家所熟知的方式没有太大的区别,采用Jenkins来实现。Jenkins每天定时从代码仓库中检出代码进行编译,编译成功后,将会自动进行镜像构建,并将构建好的镜像推送到Docker Registry中。同时会自动触发测试环境自动拉取镜像,运行容器。(感谢原图作者)
当实施这套CI/CD环境之后,大大节省了QA每日打包、安装部署的时间,从原来的每次构建、打包、安装需要40分钟,到现在的10几分钟。构建完成后,自动部署到测试环境,自动运行。QA可以更专注的进行功能验证与bug回归。
经过一段时间的试运行后,我发现效果不是很理想,经过了解得知,现有的这套使用方式仍然没有满足和解决研发和QA的实际需求和遇到的问题。主要体现在以下几个方面:
1、QA还是共用一套测试环境,存在资源冲突;
2、容器多,使用docker命令不方便;
3、容器中的文件如何替换;
4、新开发的功能如何使用这套环境来验证;
5、怎样debug。
为了满足研发和QA的需求和解决遇到的问题,我们采取了以下方式:
1、标准化,使用docker-compose来对容器进行编排,简化配置与使用。
2、模板化,将配置好的环境镜像部署云端.
3、测试敏捷化,随时发起构建、随时申请测试资源、一键搭建测试环境。
对于研发而言,他们最关注的是如何使用这套环境进行研发、调试,同时尽可能少或不改变日常的开发、
调试习惯。为此,我们采用了如下的方式:
1、研发环境搭建:提供常用研发环境的镜像,例如:mysql、rabbitmq、tomcat、nginx、keystone等。
2、环境统一:通过办公云环境申请资源,从Docker Registry拉取镜像。
3、文件替换:
单个文件:执行命令,将文件拷贝进容器目录
docker exec -i <container_id> bash -c 'cat > /path/to/container/file' < /path/to/host/file/
目录:使用卷,挂载到容器。
4、调试:IDE 远程debug。
虽然现行的这套方式可以满足和解决研发和QA的日常需求和使用中的问题,但还是存在一些不足之处,比如:仍然是单机运行模式,无法利用云环境中的计算资源。无法进行性能测试与压力测试。为了解决这些问题,我们引入了容器的集群化方案。
现阶段,可供选择的容器集群化方案有Mesos+Marathon、Kubernetes还有Docker自家的swarm。在经过详细比较后,结合产品的发展路线,我们决定采用Kubernetes作为集群方案。
在Kubernetes集群中,每一个服务作为一个Pod,各服务之间通过ServiceName+containerPort来进行访问,将Nginx所在的pod对外暴露NodePort,这样就可以通过NodeIp+NodePort来对skyForm CMP进行访问。Kubernetes集群方案的结构示意图如下:
采用Kubernetes集群方案后,除了可以分布式部署之外,还为SkyForm CMP提供了健康检查及HA的能力,此外,利用Kubernetes的特性,可以实现滚动升级、多版本部署,为研发和QA带来了极大的方便,同时也使得SkyForm CMP的性能及可靠性得到了进一步的提升。
Q:你好,我想请问下,用Jenkins持续集成过程中,如何对项目进行测试
A:在jenkins中进行测试,一般主要是已unit test 为主,除此之外,可以自己写测试脚本进行测试
Q:研发采用IDE远程调试这个地方我不是很清楚细节可否详细讲讲
A:我们使用的web 容器为tomcat,你只需在tomcat中开启远程调试端口,在IDE中进行配置即可。
Q:我们不采用marathon和swarm的原因是什么?谢谢!
A:swarm目前还不成熟,还在发展中,功能相对弱一些。Marathon的话还是看使用场景,如果还要跑例如hadoop的话可以选择。如果是纯容器,建议kubernetes。
Q:问下开发使用的目录挂载到容器是在宿主机还是共享存储上开辟存储空间,能否做到针对每个用户存储空间容量限制?
A:开发使用的宿主机在办公云中,使用的存储是宿主机的本地存储。
Q:测试和研发数据库用的是同样的一套吗?如果数据不一致,怎么处理呢
A:测试和研发使用的环境是一致的,包括使用的数据库脚本也一致,如果出现对同一个计算资源操作产生不同的数据,那就需要研发和测试一起来定位。采用同一套环境的一个好处是让研发不再有借口:“我的环境是好的,我本地无法复现”!