容器时代的DevOps部署-普元DevOps

作者:秦双春

本文目录:

一、企业应用的部署发展

      企业应用,指的是那些部署在企业的服务器上,为企业的生产与运作提供支撑的核心系统。随着IT技术的发展,企业应用的部署环境不断地发生着变化。最初,大家用的都是物理机,后来出现了虚拟机,再到IAAS平台的兴起,到现在,大家都在忙着往容器迁移。环境的变化,也促使部署模式发生着变化。部署环境,我们可以大概将它们分成三个时代:

     

      对于应用部署来说,物理机与独立虚拟机可以认为是一种环境,数量规模不大,使用传统的手工或脚本部署就可以满足需求。到了iaas大兴其道的时候,机器的数量发生了质的变化,这促进行了部署工具的发展,自动部署工具开始出现,各种手动部署平台也开始出现。

      而到了容器时代,需要部署的机器不但量更大,变化更剧烈,有的甚至需要根据条件自动升缩。为了满足企业敏捷的需求,持续部署也成了必须,此时持续部署平台也应运而生。部署模式的变更,也大概可以分为如下几个阶断:

     

      由早期手工的介质加部署文档,发展至主要依赖于脚本进行部署。后来随着各种配置管理与自动部署工具(如chef, puppet, saltstack, ansible等)出现,以及一些paas平台部署工具的出现(如cloudfoundry的bosh),企业应用的部署进入了平台阶段。

      而部署平台,根据其它自动化程度,我们可以再细分为两类。一类是在前期,为了减轻运维人员的工作而产生的手动平台,它可以将配置集中管理,依靠自动部署工具,可以帮助运维人员轻松将应用部署至众多的服务器,也可以帮助运维人员进行后期的批量维护。

     而第二类平台,除了拥有自动部署能力之外,它的主要特点是加入了应用持续集成与持续部署的能力,可以将应用新的代码新的能力源源不断地推向生产环境,缩短应用的开发与上线周期。第二类平台面向的就是不只是运维人员了,开发,测试,运维,QA等都可以参与进来。

二、普元容器云与DevOps的部署设计

      为了适应用户对容器部署的需求,普元于2015年也开始了自已的容器云建设,先后经历了三个版本的变迁。我们的平台使用nexus做为介质库,harbor做为镜像仓库,kubernetes做为底层调度管理平台进行搭建。

      不同于有些公司的使用应用的完整镜像进行部署,我们主要采用的是组装化的容器部署方案,应用的部署,是基础镜像+介质+配置最后组装成的容器环境。

     

      以示例应用PetStore为例,部署时,运行节点会先下载三个基础镜镜。然后根据依赖关系,会先启动mysql5.6的容器。接着启动Tomcat7-Jdk1.8这个容器。在启动这个容器的时候,我们使用了kubernetes的initContainer特性,它会在启动Tomcat7-Jdk1.8这个容器启动之前,先启动一个init的容器,即上图中的MediaDownloader。

     这个容器会根据提供的介质url的环境变量,将所需要的介质下载下来,并放至合适的目录,完成解压等操作。然后,这个init容器将退出结束,正式启动Tomcat7-Jdk1.8这个容器。由于介质已经下载到了指定位置,Tomcat容器只需要正常启动即可,这样就完成了整个部署。

      普元也于2015年开始了DevOps平台的构建。构建之初,我们的要求就是要支持多种部署环境,包括物理机,虚拟机与容器。虽然当前IAAS平台已经比较成数,容器也发展迅速,但相当长一段时间内,这三种部署环境在企业中是还会是共存的。

     

      如图,普元的DevOps先由构建引擎将应用从源码构建成介质,并上传至Nexus介质库。部署阶段,利用jenkins的pipeline组织部署过程,并由三种不同的pipeline来进行部署。

      物理机与虚拟机,中间通过ansible自动部署工具进行部署,容器则通过普元的容器云kunkka进行部署。虽然部署模式与部署环境有所不同,但使用的是相同的介质。

三、面向微服务的部署设计

      微服务也是近两年来越来越热的概念。一直以来,IT界就有一个梦想,希望软件能像工业产品那样彻底地模块化,最终能够通过简单装配出所需要的产品。于是有了各种插件系统,有了soa,到现在的微服务。

      系统应用将由多个微服务构成,一个微服就是一个拥有独立输入与输出的应用组件,各微服务之间通过接口互相联系,构成一个整体。普元DevOps在设计部署这块的模型的时候,就有考虑过对微服务模式的切合。

     

      如上图,我们先来看一下我们DevOps平台关于部署与集成这块的概念模型。持续集成部分,通过构建任务,将代码最终构建成也组件的介质。部署时,我们有环境资源,对应各种环境,如虚拟机,物理机或者容器云。部署组件是部署的最基本单元,它可以代表一个介质如war包,jar包,也可以代表个中间件,如tomcat, jdk等,也可以代表一个系统os,安全组等。

     部署容器则将部署组件组织成一个可最终转换成运行环境的整体。部署装配则将多个部署容器组织在一起,组成一个相互依赖的系统架构。部署装配,部署容器通过部署环境与具体的环境建立关联。部署容器通过部署配置,定义在环境中需要使用到的变量,环境变量等。最终,通过执行计划,将部署容器转化成部署实例,部署组件转换成一个个组件实例,并最终部署。光说概念可能不是很好理解,那我们下面以示例来说明一下:

     

      如上图所示为例。在部署装配中,定义了5个部署容器。每个部署独立部署,通过他们之间的依赖关系定义最终的部署顺序。右边是springboot的部署容器的组件关系图,其中的springboot-1, jdk-1等都是部署组件。

      可以看出,springboot类型的组件这里有两个,说明这个部署容器里,最终会启动两个springboot的进程。组件之间的关系,也会决定他们的最终部署顺序。

      在部署设计时,我们可以将部署装配对应为整个微服务系统,部署容器则对应整个微服务系统中的单个微服务。当然,也可整个部署装配只对应一个微服务,粒度取决于设计者。

     

整个应用部署过程,我们将它分成了四个阶段。

      第一阶段为资源申请,先需要为项目创建可供部署的环境,环境为物理机,虚拟机或者容器云均可。同时,环境还根据用途,必须选择一个类型,Dev, SIT 或者 UAT等。

      第二阶段进行部署设计,为应用创建部署装配,部署容器等。

      第三阶段进行部署转换,将部署装配与部署容器绑定环境,并添加部署配置,定义部署模式,单节点或双节点等。然后,创建部署计划并执行,完成部署

      第四阶段则是组件的运维了,可以对部署容器实例进行启动停止,重启或者卸载。 

这里我们假设架构师将整个系统应用设计成了一个部署装配,而应用内的微服务设计成了部署容器。哪些地方可以为微服务模式助力呢?主要有以下几点:

      依赖关系可视化 在部署装配的系统关系中可以清楚看到系统应用各个微服务之间的部署依赖关系

      架构演进版本化 部署装配有历史, 可以记录整个系统应用部署架构的演进过程

      服务独立演进与构建 每个部署容器(代表一个微服务)可以独立地演进,单独地构建。

      服务独立运维 部署容器实例(微服务实例)可以单独停止或重启, 或者缩容与扩容

      支持多环境混部 支持多环境混部, 某些资源占用大的部署容器(微服务),可以部署在资源充足的物理机或虚拟上, 其它的则可以部署在容器中

四、容器组装化部署

      前面我们说到了容器组装化部署,那么什么是容器组装化部署呢?容器组装化部署, 是指应用所需的系统,中间件,介质以及配置等并不完全事先打包在一起,而是在最终容器运行的时候,再通过组装的方式来搭建最终的运行容器的一种部署模式。

      另一种方式,则是容器整体化部署,它是指将应用运行所需要的系统,中间件, 以及介质, 配置等完整地打包成一个镜像,部署的时候整体地进行下载与启动的部署方式。两种方式最终结果是应用都运行在容器中,但中间过程却有些不同。

      那么,两种方式各有什么优劣呢?为什么我们要选择主要使用组装化部署呢?下面,我们先看两个我们一些客户碰到过的真实场景。

     

      场景一:某家银行上海与广州两个数据中心,两个数据中心使用专线相连。由于业务发展需要,公司构建了容器云,应用使用容器整体化部署。两地之间,通过镜像库的能力每晚进行镜像同步。运行一段时间之后,产生了大量的镜像,镜像同步的数据量越来越大,每晚花的时间也越来越多。现在,每晚进行镜像同步的时候,几乎占满了两地之间专线的带宽。而且,这个情况只会愈演愈烈。

     

      场景二:某家国企也自建了容器云,并采用整体化部署。由于管理比较宽松,容器云中出现了各种来源的镜像。某一天,linux突然爆出了一个严重影响安全的漏洞,上级要求对所有的应用系统都打上补丁。运维人员面对云中成千上万各种来源的镜像,陷入了深深的绝望之中...

      上面都是使用的容器整体化部署。那里我们使用组装化部署方式会怎么样呢?

    

     如果使用组装部署方式,镜像同步问题,因为只使用了少量的基础镜像,镜像库之间的压力很小。当然还有应用介质也需要同步,但是介质相比镜像的分层数据,同步的可选方式就多了,可以压缩,也可以合并等。

     如果数据量实在太大,采用组装式部署方式,也只能部分缓解压力,而不能解决根本问题,这种情况我们建议可以通过代码库同步,两地搭建构建平台来解决问题,当然,这只是可选方案之一。安全补丁问题,使用基础镜像加介质的方式,则会效果明显,而且这样做也有利于镜像的规范化。

总结一下,我们认为容器组装化部署有以下的优点:

      基础镜像可由专人维护,有利于镜像的规范化

      减轻同步时的网络压力

      利于镜像的安全维护

      缩短应用构建过程(不需要打包镜像),缓解构建系统压力

      更易于与其它系统进行集成

当然也有缺点:

      部署复杂度升高 原来的复制粘贴模式,又变成了带部署过程的方式,复杂度稳定性又有了变化。

      每次部署都必须下载介质包

当然,不同的模式有利就会有弊。DevOps横跨开发,测试与运维,开发与测试时变动频繁,可以考虑使用组装化部署。如果真实上生产,较为简单的或介质较小的也可以使用组装化部署。部署复杂,介质大,稳定性要求高的应用,也可以考虑使用整体化部署模式。

五、容器云集成之路

      DevOps平台要支持容器部署,必然需要集成容器云平台,可能还不只一个容器云平台。那集成容器云平台需要做些什么呢?

     

      首先我们来思考一下,集成容器云的核心需求是什么。很明显,应用部署和应用运维。运维首先需要有部署好的应用,应用部署又需要哪些资源呢? 我们认为至少需要四个元素:用户,环境,介质以及部署规格。应用部署前,我们需要先完成这四样资源的对接。

      用户

     容器云一般是一套完整的系统,它有用户,需要鉴权。用户如何对接呢?一般有两种方式:

      1. 单用户全局映射 体现在devops系统中,就是集成容器云的时候,提供单个普通用户信息。然后后面所有的操作都通过此用户来进行,在容器云中部署的应用不存在用户的隔离

      2. 多用户一一映射 集成时提供容器云管理员信息,然后为每个普通用户在容器云中创建对应的用户,或绑定对应的用户信息。以后普通用户的操作通过对应的容器云用户或用户信息来进行。用户信息可以是用户名/密码,也可以是token。如果DevOps需要租户级的隔离,则集成的时候,可以通过使用第二种用户映射方式,使用不同的租户管理员添加多次容器云来实现。

     环境

     环境的集成,主要通过对接企业的CMDB(配置管理数据库)来实现。CMDB存储与管理企业IT架构中设备的各种配置信息,DevOps平台需要与它打通,然后从CMDB中获取环境信息。如果没有CMDB,开源的CmdbBuild风评还可以,其它还有oneCMDB, itop CMDB等可以选择。当然其实基础的CMDB并不复杂,oneCMDB甚至以四个表就完成了数据建模,自建也是一种选择。如果没有CMDB,DevOps平台还需要支持环境的手工录入。

     介质

      介质的话,主要是镜像与应用介质。需要同各种镜像或介质库做集成。推荐在开发与部署阶段使用组装化容器部署方案,这样的话基础镜像比较少,可以降低甚至消除与镜像仓库的耦合。在预发与生产阶段,可以考虑部分采用整体化部署。

      部署规格

      应用的部署规格,就是对应用部署所需参数的定义。不同的容器云,可能部署规格输入的方式不一样。对于docker swarm, 可能是一个compose.yaml,定义着它的部署编排。

      对于kubernetes,可能就是service与deployment的yaml,而对于普元容器云kunkka,则是一个我们规定格式的json字符串。对于不同的容器云,只能通过定制不同的模板,根据参数生成最终的部署规格。

      当然,真正要对接一个容器云平台,要考虑的远远不止上面这一些,部署完成之后的运维,监控也是非常重要的。

六、结语

      本文我从企业应用的部署发展开始,介绍了普元容器云与DevOps平台的部署设计,以及贴近微服务模式的助力点。然后我们介绍了一下当前容器部署的两种主要模式,结合了两个场景介绍了它们之间的优缺点。最后,结合我们自身DevOps平台与容器云的集成过程,总结了一下集成的注意点。

      新思想新技术的出现,也必然带来新的机遇,新的挑战。我们和很多公司一样,在DevOps与容器云建设这条路上也是摸索前进,很多想法与实现未必就是最好的。通过公司的InsideOut计划,我们愿意与大家一起分享我们的这些想法与实践。也欢迎大家可以分享自已的心得,一起促进整个行业的发展。

猜你喜欢

转载自blog.csdn.net/bigdabao1/article/details/88052281