作者简介
李斌
阿里巴巴 高级技术专家
现在阿里云负责容器服务的开发,在加入阿里之前在 IBM 工作多年,主要从事企业应用以及云计算的研发和运维。
前言
本文分享会有三个方面的内容:
1、单体应用和微服务
1.1 什么是单体应用
谈到微服务,相对应的就是单体应用,单体应用的抽象示例大家可以看这个照片。
单体应用把所有的东西放在一起,内部通过模块调用完成所有的工作。好处就是上手非常快,上手快的好处就是变现也特别快,流量上的也非常快。
慢慢你发现单体应用架构上的问题就出来了,这些问题最大的情况就是自己内部依赖特别强的情况下,升级维护都有很多的麻烦。这也是微服务需要解决的问题,这背后的原因是什么,大家可能讨论了很多。
大家也许听说过康维定律这个概念,系统的架构上和组织架构是一一映射的,你可以想象程序做得越好,公司发展越快,内部组织架构也会变化的很快,慢慢就会发生组织架构和应用架构不匹配的情况。
这种情况会引起很多麻烦。康维定律并不是有好有坏,只是一个现实,存在即合理,如果真的是想解决这个问题,就是要专业人做专业的事情。
1.2 什么是微服务
有一篇文章讨论微服务相关的概念,把一个 Java 的应用当成像一个 Unix 程序一样,每个程序只做一件事情,做到最好。大的系统通过多个程序组合而成。这篇文章探讨了一个在实际项目当中怎样把一个 Java 应用做到这一点。
我的理解单体应用就是把所有的鸡蛋放在一个篮子里头,这里一个篮子就是一个进程。微服务就是把所有的鸡蛋放在所有的篮子里头,在这种情况下,微服务的好处直接解决了单体应用的问题,升级部署都会好很多。
但是问题就马上出来了,我们可以想像如果是你原来只有一个应用要维护,你的维护成本和你如果有一千个服务,一万个服务,维护的工作量差异会非常大,复杂性也非常大。
1.3 微服务神器Docker
Docker 能解决很多问题,有应用分发的一致性,保证应用在中心各个环节里头可是可以都使用的。
第二个解决了隔离性的问题,如果你一个环节里头很多个应用,出现各种依赖的问题以后很难解决,你维护的恶梦就开始了,采用 Docker 技术后,一个节点可以跑多个容器,容器之间是隔离的。
容器镜像作为一个标准打包格式,能够分发,作为一种服务部署和分发模式会非常好,我们可以用 Docker 做微服务。
1.4 理想与现实
这张图,我们想象的微服务像一个战队一样,星战重点描述的是驾驶员的勇气,后面有一个支撑平台,如果没有这个支撑平台,英雄就变成了无头苍蝇的一堆陨石飞来飞去。
我们在微服务的实践当中碰到了非常多的问题,怎么解决。我今天的题目就是用一个CaaS平台解决微服务在做的过程当中都有哪些事情。
1.5 微服务和Docker
有人问 Docker 到底做什么,本身 Docker 是一种打包的镜像模式,并且是一种运行的方式,能够让镜像以一种标准方式在各个环节里跑,这是国外的调查,有很多公司把 Docker 作为自己云战略的核心。
另外一个就是做微服务, Docker 和微服务之间有一些千丝万缕的联系,最后一个是 Devops,如果一旦有了容器了,把交付标准化了,就相当于集装箱标准化以后把物流标准化一样,这就是如果咱们要用 Docker。
2、容器即服务CaaS
这是一个 CaaS 图,如果大家自己使用过 Docker 的话,可能很多人觉得这个东西上手太容易了,我们用它来解决业务问题就非常容易。
在自己的笔记本电脑上装一个 Docker 引擎,镜像拉起来应用就跑起来了,如果做一个简单的应用镜像,上手也非常容易。这会给大家造成一个很大的错觉,就是 Docker 用在生产环境里头是很容易的事情。
好多文章说 Docker 遍地都是坑遍地都是雷,不是那么容易的事情。比如说容器的调度、控制、监控、服务发现、日志管理,甚至高可用,很多事情都要做,这实际上不是一个软件分发的机制就能解决的了。
所以 CaaS 平台出来的目标就是,CaaS 平台会让用户摆脱自己重新搭建这么一个平台的难度,让你专注于应用本身,专注于应用的发布和运行。所以这张图只是告诉大家如果一个 CaaS 平台大概会做什么事情,CaaS 平台最好的解释也是在网上大家可以看到的,就是构建,然后发布和运行。
2.1 实现Caas能提供哪些开发和运维的支持
在微服务的实践当中,这个 CaaS 到底能帮助做什么?
原来的时候应用之间互相调用的话可以用一个IP地址来互相链接,但是在云上,容器启动会非常快,也会消失迁移之类的,这是一个特性,不能假定IP地址永远在那,也不能假定这个服务的实例就某个特定的实例。
在这种情况下,最重要的就是服务发现机制,服务发现包括注册的机制和服务的路由。一个请求,到底是让哪个服务的实例来实现,有两类,一类是内部的请求,一类是外面的请求进来了,怎么路由到内部的服务。
服务管控和SLA等下会介绍,这是不完全的列表,不是说微服务当中只有这些问题,也不是说 CaaS 平台只解决这些问题,只不过拿这个平台做一个例子,如果一个 CaaS 平台对微服务进行支持,到底会支持成什么样。
2.2 Routing Mesh
首先介绍服务发现服务路由以及相关的东西。在 Docker1.12,新出了一个很有意思的概念叫做 Routing Mesh,routing 就是路由,Mesh 就是人人为我我为人人的意思。
一个请求进来以后会在每个节点上都会有一个类似路由器这样一个东西,这个路由器的东西可以把请求分发到集群里面任何一个其他的节点上,这样的好处就是不是一个集中式的东西,这有点像负载均衡,也有点像全员参与的负载平衡。如果 CaaS 平台已经用了 Docker1.12 天生就有这个能力了。
2.3 服务发现与负载均衡
如果有人说现在还没到 Docker1.12,那么可以通过一个内部的负载均衡和服务发现结合起来,完成两件事情。一个是服务发现一个是负载均衡,外面的请求进来以后,怎么定位后面的服务实例,请求是由谁来完成的,这是发现服务,可以理解为一个数据库。
后面所有的实例启动以后都会向发现服务报告一下我在这儿。我的IP地址等各种信息,路由器根据的负载把请求传送到一个具体的服务实例上面,这本质上讲是负载均衡,实际上完成了服务发现的功能,这是一个比较容易理解的架构。
我们不喜欢用户写一段脚本自己编排运维这些东西,所以我们说在部署模板描述文件里能不能把这种东西描述出来。
举例,如果接触过 Docker 的会知道这是一个 Docker 的部署模版,描述了一个服务,这是镜像,这些服务之间什么关系,如果没有接触过 Docker,你就可以理解成这就是一个部署模板。
在部署模板中大家都知道是声明式的,而不是编程式的,怎么样用声明式的方式描述刚才我说的这些关系,这些关系就是说现在已经有了的这些基础架构。
首先用户写的这个服务,我对外的80端口被声明成一个;其次就是自动伸缩的能力,右边两个绿色的,我们真正用户提交上来的服务,启动的时候部署的时候直接起两个实例。
还有就是 probe url,让系统平台怎么知道容器里的应用是活着的,这里很简单直接访问80端口根目录,只要是200我就是活着的,如果测试80端口没反应,说明应用就死掉了,以后的流量就别往这儿来了。
我们不需要用户自己写一段脚本做配置,也不需要在服务上挂一个钩子的东西,只需要一个声明的方式表达我想要的结果。解决了在外面我服务发现的问题,这个服务请求一旦进来以后,我就到了后面就是一个负载均衡,从这个页面可以看出一个很也意思的概念—架构即代码。
说明:架构即代码—就是说我描述的不是过程,我要描述的是最终结果,最终结果可以像代码一样被管理起来,这里就反映出这样的一些概念。
2.4 日志集中和分析
刚才是服务发现和服务路由的情况,如果用了 Docker 如果做了微服务以后,日志管理和监控这件事情怎么做。原来如果有五台十台服务的时候,出了问题自己上服务器上拉日志。自己也可以搭建一个 ELK,主要解决的是集中的问题。
作为容器服务平台,就要替用户解决日志集中的问题,把集中的的日志文件通过一个管道送给分析服务,如果容器里应用直接往标准输出写日志,系统会自动把这些日志集中起来。
如果应用把日志写到文件目录里,这个能不能抓去呢?也可以,只要声明一个日志目录的一个标签,说明日志在某某路径之下,那么容器服务也会自动把这些日志收集起来。
日志收集好了,还要分析。日志的集中和分析方案非常多,假定用户在应用已经有了自己的日志和监控,是不是必须放弃掉原来的用系统的这个呢?不是, Docker 很重要的一点是生态,有很多这样的一些开源工具也可以完成这样的任务,都是可以和系统接起来的。
2.5 监控与弹性伸缩
弹性伸缩这件事情实际上听起来很高大上,但是实际上真正运行起来有非常多的复杂性,这里展现的就是如何弹性伸缩,监控系统会把所有的这些指标都监控起来,包括容器的、虚拟机的、网络的,还有其他的服务都监控起来。
定义一个策略,一旦某种情况发生以后需要做什么事情,也是用声明的方式。上面第一句话的意思是平滑后的CPU利用率超过的70%后,可以按照按两个容器的步长增加的速度来扩展。这里没有指定下限,所以这个策略只涨不跌。
我们看这个图,对请求处理上是分布在两个不同的节点上的。云监控发现CPU指标达到了设定的阈值后会通知集群,集群的控制节点会起两个容器。这两个容器是平台调度的,会选择最合适的负载能力的节点去做,这个图里面有两个节点,都有资源,所以这两个新的容器就会被平均分配在这上面。
3、CaaS在微服务运维开发中的作用
3.1 SLA保证
下面这块对大家的影响平常显示不出来,如果出现问题有巨大的作用,这就是 SLA 的保证。 SLA 的意思就是作为一个服务提供商,怎么保证实现我说的要做的一些业务指标承诺,比如实现高可用。
自定义命令/HTTP等健康检查
再比如说自定义的 HTTP 命令,定义负载均衡的时候,可以指定一个URL,表明容器里的服务是不是健康的。
没有这个功能的时候,系统只知道 Docker 这个容器是不是正常在跑,没办法判断 Docker 里面的应用是不是真的是活着的。自定义命令和 HTTP 这种方式是在 从Docker1.12 开始引入的。在这之前,阿里云的容器服务已经实现了这个功能。
按照资源约束的调度和再平衡。
资源约束的意思是这个应用需要多少资源,根据资源约束来部署运行容器。
节点故障自动重调度
我们经常碰到的一个问题是容器是没有状态的,容器挂掉了,或者容器所在的节点挂掉了,另外一个容器起的时候要保证当初挂的那些存储要跟着迁移过去。
有的服务天生就喜欢和有的服务在一块,比如说一个 Web 应用就喜欢和数据库服务待在一个节点上。有些服务天生不喜欢在一块,假定做了一个数据库主备别把它们放在一个节点上。
跨可用区调度意思是,假定我的应用必须是高可用的,实例要分配在多个可用区中。这些要求也可以通过声明的方式来描述,不用写脚本。
3.2 微服务上线发布策略
最后一个是服务的发布策略,做 Devops,关注自动化从头到尾只是解决了第一步,第二步是部署,部署和上线发布的策略问题。
我们知道新服务的第一次部署可能在公司创建的第一天就完成了,随后每天都是在升级都是在发布,发布如果解决不好了,Devops 做的就是比较华而不实了。
现在业界有很多讨论,我们到底有哪些发布策略,这是网上的一些图:
有蓝绿发布,老服务在这运行着,部署新的服务,我们称之蓝色服务,服务起来了以后,不把流量切换到蓝色服务上,验证蓝色服务,如果没问题了再切换过去,把绿色服务删掉。
在这个过程当中只有短暂的一个流量切换的过程,这是蓝绿发布,意思就是两个集群的流量从零到百分之百,要么是零要么是百分之百。下面这个图大家可能看不太清楚,跟这个很类似,这是老的这是新的服务,这里面流量不是百分之百,应该是5%或者是95%,意思是逐步切换,。
还有一种模式是金丝雀发布模式,正常老的服务都是粉色的,金丝雀是新版,叫金丝雀是因为在矿井里面,金丝雀对瓦斯特别敏感,稍微有点危险信号就死掉了,我们先放一个金丝雀,如果代码没有问题,就可以慢慢把所有的服务升级上去。
最后一个图是AB测试,实际上是一种验证措施,假定新上线的页面,我们需要检验它的作用,可以把流量分成两半,对于用户来讲看到的是同一个页面,但是后面左右两个不同的服务,通过一段时间的观察,看看同样的流量情况下面,运行的效果是不是都有变化。
所有的这些发布模式,在网上都有很多讨论,也都有很多实践,如果自己完全都是从头搭也可以。但是如果里用了 CaaS 服务,平台应该提供这些能力,你不用再自己搭了。所以说在容器服务里面,Devops 最后环节里面最后这一公里给你解决了。
小结
这里我说微服务是冰山一角,冰山下面实际是最大的一砣,分布式系统部署运维,服务治理,还有一个我们刚才没说的应用服务化改造。
这里总结一点,我们看微服务冰山一角是非常亮的,但是底层的支持东西是非常重要也是非常大的,这是我们运维人员要做的事情,也是一个 CaaS 平台想为运维人员所能提供的一点帮助,这个帮助就是我刚才提到的六个方向。
近期好文:
《15个私有云上的 DevOps 开源工具》
《腾讯:大型实时对战手游的毫秒级网络优化》
《一篇文章全面了解监控知识体系》
《京东15万容器:多快好省大规模弹性云集群之道》
《携程:我们是如何利用容器实现快速弹性伸缩的?》
《支付平台架构师谈大规模高并发服务化系统设计经验》
《重塑中小企业运维价值》
《中小企业如何优雅的管理多机房服务器账号》
GOPS2017 · 北京站,运维大会新篇章
还没听说过哪个大会可以持续5天的
GOPS敢想更敢干!
会议地点:北京朝阳区悠唐皇冠假日酒店
会议时间:2017年7月28日-29日
点击“阅读原文”,享受“早鸟价”优惠