才云CEO张鑫:生产环境中使用Docker的运维实践

7月18日,"云用户生态发展论坛暨第三届中国云计算用户大会"在北京国家会议中心召开。在下午的会议中,才云CEO张鑫带来主题为“生产环境中使用Docker的运维实践”的精彩演讲,以下是他的演讲实录:

张鑫:先跟大家聊两句,因为我们是一个创业公司,所以可能对在座的很多人相对比较陌生。我先自我介绍一下,我叫张鑫,是创始人兼CEO。先简单介绍一下我的这个背景。之前我在美国读博士期间主要研究方向就是分布式系统和云计算。CMU毕业在美国Google一个研发中心作为技术带头人,主要就是参与并且主导了一些基于容器技术,怎么样管理Google内部有超过80多个数据中心,超过100万台服务器,怎么样用容器,全部用容器,完全不用虚拟化,从2013年开始,这是我们在Google做的事情。

大概从2014年开始,看到AWS的成功和利润,那时候我们觉得有容器的秘密武器,所以我们要把它作为一个产品,也作为公有云的一个形态去推。所以,2014年以后我参与了Google几款云产品的研发,也做了一些市场工作。从去年开始,我们就在杭州成立了一家创业公司,叫做才云科技,这家公司其实我们的初衷就是想把Google内部我们所用的容器集群的技术作为产品提供给国内的企业。所以,我们主要的对象是私有云。就在上个月,我们也成为Google和美国有一个机构,叫做云原生(音译)委员会,我们受邀成为中国区唯一的一个技术合作伙伴。

我今天主要想聊聊Docker。我今天主要做一些布道的工作,顺便总结一下我们在落地过程中所落地最佳实践,因为时间有限,这个最佳实践说起来几天几夜都说不完,我今天主要抛砖引玉,给大家讲一些相对来说通俗易懂的。

先说一下容器主要解决什么问题,或者说我们在国内落地企业当中所发现的企业的一些痛点。简单来说,就是我们的企业IT面临着多、快、稳、省的挑战。大概就是业务越来越多,用户越来越多,对我们的开发的敏捷性和响应的速度的要求也越来越高,同时怎么样在这个快和多的同时做到快而不乱,多而不乱,使用更少的成本。这是总体来讲。

下面我总结了十个具体的痛点,可能是我们企业用私有云,我们用OpenStack也好,用虚拟化也好,其实还会面临一些痛点。

第一,系统成本偏高,物理资源利用率低下。造成这个的原因是多方面的,一方面虚拟机的技术,我们所熟悉的这些对驱动虚拟化带来的一些损耗。另一方面,我不同的业务和底层的服务器之间的映射其实存在一个一个孤岛,我们有一个大数据业务,买了几十台很牛的机器,专门跑大数据,另外一些机器跑会员管理业务。但是,大家知道大数据机器非常耗资源,可能平时CPU在70%到80%以上,但是对于一些服务器大家晚上都睡觉了,利用率就降下来了,这样我们系统怎么做动态调度和弹性优化,这样导致系统成本偏高,资源利用率低。

第二,线上业务稳定性、可靠性较低。不知道在座企业是否有跑在单机说,一旦机器挂了,这时候就造成业务的宕机。另外,这个机器挂了,没有一种自动的恢复,甚至自动的检查的一种机制,这都造成业务稳定性和可靠性的偏低。

第三,互联网时代我们什么都讲究高并发,高可用。

第四,我们怎么样应对这么高的流量,怎么样在每秒应付几百万,甚至千万的并发,今年6.18京东动用了10万个Docker实现高可用和高并发这样一种性能。

第五,目前很多传统企业和应用所谓的架构是巨石行的,这样带来很多弊端。这个造成很多流程上的僵化。

第六,开发、测试、生产环境不一致,软件系统难迁。就是怎么保证不同环境之间可以无缝的迁移,这里头我讲的环境是软件环境。作为程序员来讲,大家可能都说过一句话,这个程序在我的机器上是好用的,为什么跑到你这块不好用了,这涉及到不同的同开发端到测试端到生产端不同的测试环境的控制。

第七,交付流程复杂,新版本上线缺风险把控。大家有没有想过怎么样做自动化测试,怎么样每个代码有更新,可以自动化的去对它进行构建测试,测试的结果能够通过邮件等等方式自动化的通知给我们,包括最终往生产上发布的时候怎么降低风险,采用灰度发布也好,这些都是在国内的企业很多所没有去实践的,而在Google内部一直在使用这样一些最佳的实践。

第八,环境配置呈指数级增长,系统难以维护和调优。我们现在都讲究,大家可能采用微服务架构,但是微服务架构也带来一个问题,原来一个程序就能搞定,现在换成很多模块,不同模块总能找到对方,怎么找?IP端口,十个模块,相互之间都要写配置。除此以外,不同的环境中间可能有一些配置文件,复杂度逐渐增加。

第九,系统管理使用众多脚本和工具,学习成本高,难使用。后面这两点可能大家都有这种痛点,包括虚拟化技术。

第十,缺乏快速调试,自动监测工具,故障修复时间过长。当系统出现问题以后,我们怎么样可以快速的调试。有的一个一个查看日志,最后定位。怎么样采用更系统的工具化的方法去做,这就是一个难题。

做这么多铺垫,现在回到主题,就是容器这个东西。有听过容器技术的,也有没听过的。所以,我现在按照我们就低不就高,按照小白的讲法简单的总结一下。首先,容器这个技术,之所以2003年在Google就开始被使用,一直到2013年有了Docker这个产品以后,这个产品在全球开始风靡,其实有它的本质原因,归根到底就是成本降低,速度提升。刚才我们一直说,后头加一个零,减一个零,至少我们用了这个东西以后,先把成本后面减掉一个零。由于成本的美好,所以我们看一下它实际在美国落地的情况。我的数据来源是两方面,第一方面是美国Docker公司官方的4月份所做的一个调研和统计。这个数字很多字也很小,大概讲几个关键的数字。

2015年截止到2016年4月份,有90%的美国企业至少在开发中使用了Docker这个技术,然后同时根据另外一个美国比较老牌的云计算公司经常发布一些调研,已经有76%的企业不光开发中用Docker,甚至用在生产当中,每年基本上翻番。如果看Google内部,从2003年开始使用,完全取代虚拟化。在中国去年浙江移动“双11”采用基于容器的数据中心操作系统技术承载“双11”的流量。还有京东在6.18大促几天时间之内动用十万Docker度过这么一个高峰期。

刚才一直在说容器,容器其实在中国落地中遇到了哪些困难。为什么今天肯定我估计在座各位并不是所有人都已经使用了容器。其中一大部分原因,就是作为任何一个新技术都带来潜在的这样一种风险和一种学习的成本,以及对已有系统的一些颠覆。这里最简单的例子,我们之前虽然知道出了问题以后,我们要SSH,很马上,但是至少我们知道怎么做,但是现在全都装到容器里,大家傻眼了,这就是对传统运维系统的一个颠覆。

除此以外,刚才提到像很多大数据的应用,本身这个应用自己就是集群化,但是容器有点和虚拟机类似,只是一个一个的单元。当我面对复杂的应用系统,跨主机的时候怎么全局的进行容器化,怎么样进行分布式,跨主机的互联,以及容器多了以后,怎么样去管理。还有就是包括我开发者的时候,它开发的时候我原来代码写好直接提交代码库就好了,现在有Docker,怎么把Docker潜逃进去,我认为这些是Docker真正落地需要面临的核心问题,我们需要解决的地方。

再给大家打个比喻,容器大家用了Docker都知道,最经典的比喻就是一个集装箱。所以我们可以把它想象成一个虚拟机,虽然理论上有很大差别,但是可以把它想象成一个虚拟机。把应用装进去,环境装进去,放在一个箱子里,一次封装,处处运行。但是,当我们这样做了以后,发现一个问题,我们系统里有无数多个这样的集装箱,全都是新鲜的物种,以前从来没有见过,这样我们面临的就是一整个码头,怎么去管理这么多的箱子,具体包括哪些集装箱放在哪艘船上,怎么摆更有效,大家坐过飞机,坐飞机起飞之前有人工检查,这个我们怎么自动检查每一艘船,就是每个服务器是不是健康,以及出了事,怎么把一艘船上的箱子全都动态的迁移到不同的地方,这些都是Docker运行过程中遇到的一些阻碍。后面以点盖面,抛砖引玉介绍一些我们解决集群管理这样一些问题所遇到的,或者所采用的一些常见的方法。

第一,先看开发者。我们所有系统的萌芽都是从一个一个代码开始,所以我们首先要解决在开发端怎么把这个Docker融入进来。这时候我们要构建一个大家可能熟悉的持续集成,持续发布的一个流水线,后面我会讲到,在CICD以外我们有更多的事情要做。

这个流水线它的设计模式大致是这样的。首先是代码库,可以是SDN,可以是本地的Internet。有了代码库以后,有这种外扩,每当我有一个代码,提交以后我们要构建一个自动化的一个构建的流程,用过Docker的朋友大家都知道,其实就是跑一个Docker  View(音译),然后我们会自动把它存到所谓的静相仓库,然后再根据策略把它发布到目标的机器上,这个策略两个字怎么理解?第一,发在哪个环境,真正的系统里肯定不可能只有一个环境,肯定有开发,首先我们要配置策略,以什么样的频率发布在哪一个环境上,比如对开发环境,我们以前的做法每天晚上做一个构建和发布,对于生产环境则是需要人工的手动的去触发,去进行发布。

另外一个层面,这个策略还包括我们发布的时候是采取滚动更新,还是全部重建,还是灰度测试,这三者的区别解决最简单的是全部重建。就是先把已有的服务,旧的版本1.0全部拿下来,再把2.0搞上去,这是全部重建。滚动中心,就是先把2.0跑起来,确保没有问题,再往1.0上。

第三,AB测试两者同时并存,但是控制不同的比例,5%达到2.0%,然后验证没有问题,5%提到10%,这些我们要支持不同的策略配置。

当我们有一套流水线以后,我们发现对于开发者而言,它完全没有感觉到流程的任何改变,因为它所做的还仅仅是将代码发布到代码库,所有后面的构建、打包、上传、发布,全是由流水线做的。

但是这个时候我们也带来一个新的问题,因为我们如果大家可能做这个发布,如果比较规范,我们应该知道每次发布,从代码库,代码级别应该打一个分支,这个时候多次发布以后,在代码库就有不同的分支,1.0、2.0、3.0,但是用过Docker的朋友知道,每次发布的时候怎么保证这个静项版本和代码版本一一对应。

另外一个新问题,大家可能知道这个容器或者Docker这个东西非常天然的支持所谓微服务的架构,刚才提到原来的一个模块拆分成十个甚至更多,这个对发布来说带来很大的问题。原来至少发布一个二进制就好了,下来每次发布的时候十个模块,而且关键是它模块之间还不是独立的,可能有一个后端模块提供API服务,前端模块去调用它,这个时候当后端模块更新以后,前端也必须同时更新。所以,我们发布的时候大家还要怎么样做到多模块的联合发布,理解不同模块之间的依赖关系和发布时候的时间顺序,这些都是我们需要注意或者需要解决的地方。

正好讲的微服务。其实我们做的时候很多企业问我们,都知道微服务很好,但是我们大家应该切分到什么力度?很直观的想象,为了最大化的发挥它的价值,应该切分的比较细。但是,管理的系统很大,因为这个Docker和容器讲的一个容器里就干一件事情,微服务,不要干太多,这个时候怎么管理?这个时候我们采用一个容器组的概念。容器可以理解为一个虚拟机,不同容器之间完全格力,可以想象每个容器有自己独立的批,有自己独立的网络空间,相互之间也看不到彼此的进程和文件系统,隔离性非常好。 但是容器组是基于这个容器以上,又做了一层封装,多个容器可以被放到一个容器组,然后一个容器组里面的文件系统也可以共享,所以等于在上面多做了封装。为什么要讲容器组的概念,这是我们原来做私有云的好处,它有几大好处,它很好的解决了微服务切分的粗还是细的问题。我们在做代码库的时候,可以切的粒度很细,这样保证独立的发布和管理。但是,运行时,当我把这些东西都跑起来的时候,又可以把联系很紧密的一些模块定义到同一个容器组,后面管理的时候,我去做健康检查的时候又是在容器组这么一个层面。所以,既给了大家在开发时候的独立性,同时又给了大家当东西真正跑起来的时候,管理的时候又提供了一层抽象。

时间不多了,后面我快速的过一下。另外一个就是当我们系统内部的组件多了以后,我们管理的时候怎么样按照逻辑关系,按照树型关系去管理,这个最传统的做法就是把资源建立一个等级,但是实践证明等级这个东西不够灵活,所以我们推荐使用标签系统。

再快速的说几个东西,我一开始提到我们可能潜在面对单点失效,面对稳定性不够,吞吐量不够的问题。基于容器做大规模管理的时候,我们一定要采取面向管理的方法,当不同模块之间相互应用的时候,不要连具体某一个实例的IP,我们需要在实例的前面建一个虚拟的入口,我们把它叫做服务的对象。这个服务的对象同时它会提供一个自动的服务注册的一个机制。什么叫服务注册?有点类似于DNS的系统,当把这个应用跑起来,会自动在DNS里把我的名称注册进去。比如我有一个Redis,这样的好处就是当别的组件想要访问这个缓冲服务的时候,可以简单通过Redis这个名字进行自动的服务的解析,这个过程叫做服务发现。

还有两个好处,第一方面评比了底层IP的变化,可以达到不同环境之间的切换,不需要改配置IP。另外,当服务对象后端真正的实力,这些副本进行弹性伸缩的时候,或者出了故障进行自动恢复,自动转移的时候不会影响系统的稳定性,因为所有的连接都不是直接在具体的实力上进行的。这里当然还包括构建弹性伸缩,健康检查等等。时间关系,我这边就不赘述了。

所以,今天就是一个抛砖引玉,给大家介绍一下我们在生产过程中,在国内的企业中使用这种容器和容器集群所达到的一个效果,简单的可以说一个数字。就是我们在某个运营商和IBM做了一个联合的公测,每秒做到36个CPU,时间关系介绍到这里,有兴趣的可以关注我们,跟我们一起讨论,谢谢大家!