EasyStack参加第七届数据技术嘉年华并发表主题演讲

Posted on 2018年05月14日

微信图片_20171120133850


踏着最后一抹秋色,第七届数据技术嘉年华如约而至,11月17-18日在北京丽都皇冠假日酒店盛大召开,EasyStack副总裁周崇毅受邀出席大会并分享了主题演讲。以下为“Kubernetes与OpenStack融合支撑企业级微服务架构”演讲主要内容:


大家关注最新的Docker新闻会发现一个动态,Docker宣布在它的下一版本中将内置K8S的发行版,代表容器编排领域三条技术路线的竞争也就宣告到了尾声,基本上大家一致认定选择Kubernetes作为容器编排管理平台。在去年、前年参加容器的Meetup的时候,很多时候还要给大家解释为什么要用K8S,K8S和其他技术路线的比较,而到了今年,大家更多的是关注如何用好K8S,有了K8S平台之后怎么支撑上层的应用场景。前面一位讲师分享到,K8S的应用场景很多,比如微服务,用K8S做DevOps,还有TF这样的AI框架,还有区块链等等,这些都是K8S典型的应用场景。Kubernetes和IaaS平台不一样,它是面向应用的,搭建平台只是第一步,更关键的是怎么用这个平台。


微信图片_20171120115407

EasyStack 副总裁 周崇毅


我今天希望从微服务的角度讲讲我们怎么把K8S平台用好。我们公司是提供私有云解决方案的,最早我们提供基于OpenStack的云平台解决方案,从去年下半年开始基于K8S开发自己的容器云平台。相比于其他提供容器云平台的厂商,我们的特点是将Kubernetes和OpenStack进行融合,以支撑更广泛的应用场景,希望在今天的分享中给大家介绍这方面的工作。


我今天的分享分三部分:一是微服务架构的基本概念;二是怎么通过K8S支撑微服务架构;三是基于融合架构更好的落地微服务。

PART-1

微服务架构大家就关注几个问题:什么时候、哪个时间节点需要采取微服务架构,实施微服务架构的改造。我这边总结了几点,如果你当前所负责的应用系统面临这些瓶颈,那么你需要考虑微服务架构。


1、业务的复杂度已经增长到了,传统单体架构没有办法应对这个复杂度的时候,可以考虑采用微服务架构。右边是一张比较有说服力的图,比较了微服务架构和单体架构,随着业务的复杂度上升,它带来的生产力的比较,大家可以发现,其实在业务复杂度比较低的时候,咱们采用单体架构,其实它的生产力比微服务更高,随着咱们的业务复杂度越来越高之后,你采用微服务的优势相对比较明显。如果大家有过比较丰富的软件开发经验,在一个项目或者公司的初创期,大家一般不会一开始采用微服务架构,而是追求更快速的系统上线,通过单体架构进行应用的开发,采用短平快的方式,而发展到一定阶段之后,则开始考虑实施微服务架构。


2、第二个因素和人相关。如果大家看过《人类简史》就会发现,里面有一个结论,当一个组织的人数超过150人,那整个组织的沟通效率会随着人数的增长逐渐变低。对软件开发也是一样,如果一个项目非常大,做好几年甚至上十年,团队规模达到好几百人,你维护整个项目非常麻烦。


3、传统单体架构的问题,整个应用的维护随着时间往后越来越难。现在加入一个团队,它已经开发很多年一个大的应用,你会发现很头痛,怎么快速融入到整个项目的开发或者运维里面,它里面可能有数百万行代码,很可能让新人感觉无从下手。


4、传统的架构的升级和部署的难度相对来讲会更大一些,传统的架构,如果你要做一次服务的升级,可能需要将整个系统的服务停掉,从0开始,完整部署一个新版本的应用。


5、另外一个问题是应用迭代效率,如果迭代效率越来越低,比如从一两周发布一次,到几个月发布一次,且越来越慢,这时候你就会发现整个应用的迭代速度已经赶不上业务发展的效率,业务端提出的新需求无法得到响应。


6、传统的架构在应对互联网高并发、高压力的业务场景的时候面临比较大的瓶颈。如果采用传统架构应对高并发场景,在物理机时代,可能需要提前好几天开始准备,准备新的服务器,部署应用,部署负载均衡、数据库等,整个周期非常长,而且成本非常高。后来有了公有云平台或者OpenStack这种私有IaaS云平台,效率相对会高一些,但也只是把云主机、云存储和云网络部署出来,上层应用还是要自己部署,虽然能带来一定的弹性伸缩能力,但相对来讲效率还是不够高。


7、应用的容错性,单体应用的一个缺陷是,当其中有一个功能模块出现故障,很可能导致整个应用出现故障,无法实现良好的容错性和高可用性。


第二个问题,什么是微服务架构?相信大家了解微服务架构很多了。这边从技术角度和业务角度看微服务架构。微服务架构大家一致认为最早是美国的Netflix公司开始实践的,而微服务概念正式提出来是在2014年,Martin Flower发表论文将微服务的定义和特征进行了系统的总结和梳理。可以说,微服务架构是随着云计算的应用和发展,应运而生的一种软件设计服务的风格。技术角度它有什么特点?一是拆,用一组服务的方式构建一个系统。二是微服务组件是自包含,可以独立升级、独立部署、独立扩缩。相对来讲每个微服务都是独立的进程。这和原来单体架构的应用不一样,单体架构通常运行起来是一个进程,现在不一样,每个微服务都是单独的进程。第三,服务之间怎么进行调用?微服务更多的是采用轻量的交互机制,使用HTTP型的API进行交互。以上这些只是从技术方面讲微服务的特征,而更重要的从业务角度理解微服务。其中第一点是它的单一职责设计原则,一个微服务只负责一个单一职责。另外很重要的一点是需要从业务边界来确定微服务的边界,而不是从技术的角度来区分边界。


第三个问题,为什么要使用微服务架构?我这边列了重要的一点。


一个是解决刚才提到的问题,提升整个应用系统的迭代效率,与原来单体架构不同,采用微服务架构的应用,每个微服务都可以独立发布。现在有些大型互联网公司一个系统每天会进行上千次甚至上万次的发布,迭代的效率是非常高的。另外,升级带来的代价比较小,无需应用进行全部功能的完整升级,每个微服务组件做单独的升级。通过以上途径,提升迭代效率,更快速的响应需求变更。


二是弹性扩展,微服务采用松耦合设计,原来单体架构做弹性伸缩通常是整体进行弹性伸缩,而微服务可以单独做弹性伸缩。在在应用扩展时,仅需扩展有瓶颈的微服务,这样效率更高,而且节省资源。


三是容错能力,微服务因为本身是进程级别的隔离,且每个微服务是自治的,单个服务的异常通常不会导致整个系统的故障。


四是能丰富技术栈,每个微服务组件是自包含性的,每个微服务组件根据业务需求,都可以选用最合适的技术栈,比如不同的微服务可以用不同的语言,不同的开发框架,不同的后端数据库。针对不同的微服务,可以选择最合适的技术栈。


最后是和组织相关,这点也非常重要。康威定理提到,一个系统的架构跟组织的架构是对应的,也就是说,开发的应用系统的架构,是与组织架构对应的。原来传统的软件团队架构通常分为前端、后端、DBA等等,对应的话应用系统也分为这几个层次。而在微服务领域,会发生变化,每个微服务都由独立的团队开发和维护,从最初开发到测试到维护,负责它完整的生命周期。微服务团队规模不大,亚马逊有一个原则叫“两张披萨饼”,也就是说如果一个微服务的负责团队,两张披萨饼不够这个团队吃,则说明这个团队规模太大。控制好团队规模,可以提升整个沟通效率,而如果做得不好会产生负面的影响。


第四个问题,怎么做微服务的架构?有业务方面,有技术方面,还有组织结构方面的。


一般分三个步骤:


一是服务的建模,需要业务部门、架构部门和开发部门一起实现整个服务的建模,因此属于技术域和业务域。业界现在最受欢迎的方法就是领域驱动设计(DDD),这是非常有效的微服务建模方法。采用DDD主要是实现两个目的:1、如何合理的设计和拆分业务架构。2、保证所设计的业务架构和系统架构是统一的。


二是架构的设计和实现,属于技术域。业界现在有很多比较成熟的微服务开发框架,能够给你实现微服务架构带来很大的帮助。另外,需要选择合适的支撑平台,类型有以下几种,一是基于容器的,也就是基于Kubernetes、Docker技术,这也是目前用的比较多的;另外还有基于公有云平台、私有云OpenStack平台来做,还有基于面向应用的PaaS平台来做,像OpenShift、CloudFoundry。目前微服务开发框架和支撑平台两者之间的界限也在逐渐模糊,很明显的一个趋势就是,Kubernetes已经实现了很多原来微服务开发框架所实现的功能特性。


三是构建DevOps体系,属于组织结构域和技术域。组织结构相关的是团队文化需要DevOps化,团队要参与从软件开发到测试到运维整个环节里面来,而不是相互割裂。另外需要构建一整套DevOps所需要的工具链,比如大家经常用CI的工具,比如Jenkins,代码管理工具,GitLab、GitHub等等,现在开源的DevOps相关的工具非常多。

PART-2

Kubernetes的愿景是为构建基于微服务架构的大规模分布式系统提供标准化的框架。接下来给大家分享一下Kubernetes与微服务的关系,以及它如何支撑微服务。


这页片子里面列举了比较重要的点,例如,微服务的服务发现怎么做的?如何实现集中的配置中心,还有负载均衡,整个微服务的编排、升级、任务管理、日志管理、高可用怎么做的等等。基本上大部分支撑微服务架构所需的功能,Kubernetes都能提供,当然还有一些缺失,比如咱们经常用的断路器、服务网关等,相信Kubernetes后续会逐步完善其他方面的功能。


服务发现,实现原理很简单,基于服务端的服务发现原理,基于Kube Dns和service的机制做的。咱们要明确一点,微服务为什么需要服务发现的组件?因为微服务更多是基于云平台做的,有频繁的迭代和升级,有各种应用的发展,有一个问题是服务IP地址或者端口的标识会变化,传统架构大家固定不动,通过IP端口它就可以访问。有变化之后就需要引入服务发现的机制让我的服务之间能找到对方。


服务发现业界做的方式有几种:


第一个是使用比较成熟的云平台内置的服务发现组件,大型共有云平台有服务发现的组件。第二个是建服务发现的系统,常用的三种,Etcd、Zookeeper、Consul,另外使用微服务框架,比如SpringCloud Eureka。Kube-dns是属于第一种,云平台自带的服务发现组件。实现原理,K8S把service的名称注册到Kube-dns组件里面,它通过dns服务做映射,把service的名字和class做映射,如果Pod需要访问另外一个service,你就直接访问service name,不需要再找service的ClusterIP或者直接找POD的IP,都不需要,直接通过service name。具体实现的原理,Kube dns组件它是一个POD,里面有三个容器,它内置集成SkyDNS,做的事是监听K8S service,去更新整个DNS的记录。老版本里面集成了Etcd,新版本已经把Etcd去掉了。Dnsmasq为集群提供DNS查询服务,会将Kubedns中的记录读取到缓存中,提升整个DNS查询的效率。下面的exechealthz容器,作用是使用K8S健康检查探针来检查上面两个组件的健康状态。


集中式配置中心,现在为什么要实施微服务需要配置中心呢?


1、企业级应用配置管理确实比较复杂,配置信息的种类比较多,数据库的配置文件,还有中间件的配置文件,种类非常多。随着时间的积累,配置文件会非常多,版本也会非常多。


2、环境的种类也非常多,开发环境、测试环境、预生产环境、生产环境,开发环境也有很多套,基本上每套都有自己的配置文件。


3、如果采用微服务架构,服务的数量基本上是线性增长,配置文件的数量也是线性增长,你就需要有一个配置管理中心管理所有的配置文件。


4、更新配置文件的时候,相对来讲会比较烦琐,原来传统方式更新配置可能做的工作是整个应用都要重新构建、重新部署,重启一遍,现在构建微服务架构都要统一的配置中心。在Kubelet里面当然是采用大家提到的ConfigMap做配置管理,达到的是配置和容器分离,相当于有统一的配置管理中心,如果POD要使用配置文件,在生成POD的时候,就把yaml文件扩展进去。另外批量更新配置文件,相对来讲,如果我有一组POD使用的是同一个配置文件,只要在里面更新一下配置文件,自动把它同步到一组POD里面去。secret存储的是敏感信息,也可以归到配置中心功能里面去。


负载均衡,原来大家要自己实现,通过硬件的负载均衡或者软件的负载均衡做,K8S把负载均衡帮你做了。具体实践也比较简单,service后端会实现负载均衡,具体是Kube-Proxy组件做的,访问service的流量都会到后面一组POD里面去,默认采用轮巡的方式分配。这是POD和POD之间访问的负载均衡。大家肯定要做的外部负载均衡的实践,现在有三种方式做,一个是我自己建,通过软件或者硬件的方式,比如HAProxy、Nginx、F5,早期K8S都是第一种方式做。后来的K8S推出了Ingress,也可以基于Ingress做,还有使用云平台IaaS平台提供的负载均衡做,现在大的公有云平台肯定会提供负载均衡的服务,你可以做集成对接,比如OpenStack也可以提供Neutron LB做对接。这是负载均衡的实现。


下面的是弹性伸缩,这个场景非常多,大家比较容易理解,一个是定时性,周期性,我有一个定时的秒杀、推广,定时的抢票活动,其实比较推荐的还是提前规划,手动实施你的弹性伸缩。毕竟咱们通过底下自动的弹性伸缩的方式,是有监控指标的,肯定还是会有小段时间的延时,对秒杀活动,就算是1秒、2秒延时都会对整个系统带来影响,具体实现方式就是改ReplicaSet的副本数量。第二个是突发性的,这种事件没办法预测。基于HPA这个资源对象去做,它根据POD负载,它目前默认的是CPU,当然你可以自定义去做,比如QPS、TPS。应用行业很多,这只是列了一小部分,只要有大量2C的业务,有大量公众的业务,都会有这种高并发的需求。Kubernetes处理高并发场景也是它很强的优势。


容错性,其实主要是通过两方面做,一是故障自愈,容器异常时自动重启,二是Node节点宕机时,重新调度并启动容器。它检查整个容器是否运行正常,如果发现容器运行不正常,会重启整个容器,一般直接重启。Liveness探针,是检查容器是否处于运行状态,如检测到容器运行状态不正常,则Kubelet会杀掉容器,并根据设置的Restart Policy进行相应操作,比如重启。Readness探针,判断容器内服务器是否已正常工作。如果发现启动没有完成,它会把Pod IP从service的Endpoint中移除,不接受请求。还有自定义,可以判断执行一条命令,来判断容器健康状态。


比较重要的一方面是怎么做微服务的编排, K8S默认的实现相对比较简单,通过Deployment做,我通过Deployment,对整个Pod和Replica  set都做了编排,典型的应用场景,通过Deployment实施灰度的升级,还有通过Deployment查看应用部署状态。要做更高层的应用编排,现在其实大家用得多的是Helm的开源项目,它的特点,类似于客户管理的工具,这里面会看到一组yaml文件,包括我的Deployment和其他资源对象的yaml模板文件都放在charts目录下,通过这组模板定义整组应用,这是Helm项目做的工作。


灰度升级问题,原生采用灰度升级的方式,保证业务系统在升级过程中不中断,升级过程中新/旧版本并存。当然目前还无法控制新旧版本的请求来源。快速回滚是基于Docker的版本管理机制,升级发现问题,能快速做回滚的操作。


任务管理,刚才咱们vivo的讲师讲到很多和Job相关的,job更多是批量处理一次性任务,Cron job是周期性服务,你也有定时任务的场景,定时做数据库的备份,定时发送邮件,这种场景使用Job或者Cron job做会比长时间运行的POD更合适一些。


日志管理,业界最常用的是EFK的方式,基于Elasticsearch做整个日志的搜索和分析工作,Fluentd,在每个节点可以通过DaemonSet的方式进行部署,它会从log文件夹里收集日志。kibana做可视化展示。


采用微服务架构之后,整个监控系统的设计和原来不一样,原来只要监控单个单体应用就可以,现在整个微服务数量非常多,如何实现统一的监控管理非常重要。容器的监控告警,业界有比较多的方式,用的多的,一个是老的基于Heapster的方式,另外一个是大家用的更多是Prometheus的工具,它的特点是相对来讲,提供监控方案更完备一些,它包括整个数据的采集、存储,还包括整个节点的监控数据以及K8S集群的健康状态都可以做监控。现在大家更多的是采用Prometheus监控容器化的应用。还有方式是说内置集成Alertmanager工具实现告警功能,可以对接短信网关或者邮件。


另外一个需要考虑的东西是把微服务设计出来之后怎么做整个应用的发布,基于容器的微服务应用,发布方式有:1、基于镜像仓库的发布,镜像仓库可以自己上传或者share自己Docker的现象。直接从源代码就整个通过CICD工具链来推送到镜像仓库里面去,这种方式的缺点在于缺乏应用编排的功能。2、要实现这种编排要使用编排模板,通过标准化和规范化的方式去完成一组应用的编排以及一组应用的发布。3、应用中心,如果整个团队规模比较大,如果我做出一个应用,可以把整个应用分享出来,上传到应用中心供大家下载,然后做统一的发布。

PART-3

基于Kubernetes和OpenStack融合支撑微服务架构。


为什么要做呢?本身通过纯容器的平台落地微服务,怎么落地还是面临一些问题,有状态集群的服务怎么部署到容器上,现在相对来讲还不是那么成熟。我怎么做这种异构平台的管理,相信大家的数据中心里面,包括物理机,虚拟化平台,包括容器都是并存的,怎么管理异构的资源,怎么做资源的编排都是比较大的问题。一个老生常谈的问题,容器安全性的问题,应用之间怎么实现安全的隔离。还有网络,网络怎么选择异构平台SDN的网络解决方案。还有存储,怎么支撑异构平台的软件定义存储的解决方案,这些都是需要考虑的问题。我们基于K8S和OpenStack融合构建一体化的支撑平台。


Kubernetes层,我们定位为上层,以应用为中心,更专注于上层微服务架构,运用它的交互和管理。OpenStack是一个IaaS平台,擅长管理底层资源,包括网络、计算、存储。我把它定位到专注于底层基础设施的编排、管理和调度。两个分工不一样。融合之后想达到的愿景,优势互补,达到1+1大于2的效果。


这是融合的架构,底层是OpenStack平台的计算存储网络资源管理,中间是容器平台,容器平台现在有两种主流的部署方式,一种是把容器集群部署到虚拟化平台之上。另外一个是把容器集群直接部署到物理机上。容器平台和OpenStack平台和Kubernetes平台之间采用网络解决方案,存储这块也是采用统一的存储解决方案,通过OpenStack的Manila、Cinder来构建统一的存储服务,搭好平台还可以做很多工作,上层相关,从管理界面可以做统一的管理试图。在编排层可以做统一的编排。另外就是构建统一的应用中心,可以做统一的应用中心发布我所有的应用。另外和一体化平台整体相关的,能做的工作很多,包括监控报警、日志管理等都可以做到一体化统一的管理。自动部署,现在OpenStack有一个项目Magnum,通过调用OpenStack Heat编排工具快速部署Kubernetes平台,实现K8S平台的快速自动的部署。这是整个平台的架构。


能实现哪些好处呢?两个维度的场景伸缩,K8S能实现的是POD平台的弹性伸缩,如果要实现两个维度的IaaS层和容器层的弹性伸缩,则需要对接容器平台和IaaS平台。我们通过OpenStack和Kubernetes的融合方案,假如说POD层面弹性伸缩无法应对高并发业务的场景,在节点层面做弹性伸缩,在新的Node节点上再启动Pod。


刚才提到的网络,看一下网络怎么做的。网络现有的容器解决方案有很多,相对来讲虽然用的很多,但是和具备伸展环境的网络解决方案相比,它的成熟度有欠缺,它生产环境经受的考验没有那么多。另外碰到的问题是嵌套Overlay网络的问题,如图,如果在IaaS平台的Overlay网络之上,再构建一层容器的Overlay网络,例如Flannel VXLAN,网络传输的性能损耗、延时都比较高,而且多个SDN网络,管理调试起来很麻烦。我们的解决方案是直接使用Neutron构建统一的网络服务。


采用统一网络管理的好处在哪?一是方便管理,一个SDN网络统一管理容器平台和OpenStack平台的网络。二是能够实现容器和容器之间,容器和虚拟器之间,能实现网络的直通。具体怎么做呢?可以通过开发CNI插件把Neutron对接进来。OpenStack社区有一个Kuryr项目做的就是这个工作,现在它有两个子项目,一个是针对Docker的,相对更成熟。还有一个针对K8S的,相对来讲不是很成熟。我们在社区版的基础上,针对Kuryr做了大量优化和改造工作,才把Neutron接入进来,具备生产环境的可用性。另外一个优点,可以引入OpenStack领域比较成熟、高级的特性,比如安全组等,这块其实也是社区一直做的工作,把这些功能引入容器网络,因为容器网络的高级功能比较缺失。


存储,其实K8S的存储,也可以对应第三方存储。我们的需求更多是企业级客户,K8S能支持的商业存储,尤其是集中式存储,它的支持力度相比Cinder和Manila有差距。我们直接采用Cinder和Manila去做持久化存储驱动,去构建整个统一的存储服务。后端默认是对接的开源Ceph的存储,如果我的客户有对接集中式存储的需求,更多是从OpenStack这层做对接,上层K8S和虚拟机都会调用底层的存储,这是统一存储的方案。


现在大家在构建K8S平台比较多的是多租户隔离的问题,更多处理安全的问题。安全隔离问题,因为K8S虽然有名称 namespace的概念,但是更多是限制资源的使用,并不是真正意义的多租户。OpenStack就不一样,它有严格的多租户隔离特性,租户和租户之间资源、网络都是隔离的,现在大家去构建大的容器平台要做多租户隔离有两种做法,一种是一套K8S平台,从网络解决多租户隔离,例如Calico网络。另外一种方式是大规模环境里面用的比较多的,每个IaaS平台的租户都是自己构建并且管理自己的K8S集群。对于我们来讲也一样,我们确实有很多客户的体量和规模很大,往往一个租户对一个部门或者对一个开发团队或者一个测试团队,每个团队都需要自己的K8S集群。我让它自己管理、自己创建,让它自己管理K8S集群,集群和集群之间,一方面我们借助多租户之间的特性保证相互之间的隔离。


有了统一架构的云平台,如何设立全类型的应用就比较好了,可能一个平台里面就有Docker容器的部署器,也有虚拟机的部署区,还有裸机部署区,容器更多的是放一些偏互联网的,要应对大规模弹性伸缩的应用把它放到容器里。相对来讲比较传统的应用,放到虚拟机部署区里面,还有一些目前还是比较适合部署在物理机上面的,例如Oracle RAC,Hadoop,HBase/Hive等,多数还是部署在物理机上。


最后这片是总结整个OpenStack和Kubernetes融合能带来的好处,可以从两个层面理解,一是技术层面,一方面是应用,企业内部的应用架构确实非常多,架构比较复杂,传统类型的应用,云上的应用,还有经过传统应用改造过来的应用,需要通过统一架构支撑全面的应用。基于基础资源,异构的基础资源需要统一的平台,需要统一的调度和管理。还有人的角度出发,开发者诉求很简单,我降低开发层、应用层和底层基础设施的耦合性,不希望过多受到底层基础设施的平台限制,底层是各种资源都统一管理,自然就可以通过底层跟上层的解耦提升应用系统架构设计和开发的灵活度和敏捷性。运维者的诉求就更简单,需要统一的平台管理所有资源,要不然运维同志的压力很大,又是容器,又是虚拟机,又是公有云,又是物理机,有统一平台之后就对所有基础设施能够对它做统一的运维管理,包括监控和日志,都可以做统一的运维管理。

Posted in 市场活动 Tagged 市场活动,解决方案