微服务化的不一样阶段 Kubernetes 的不一样玩法

做为容器集群管理技术竞争的大赢家,Kubernetes已经和微服务紧密联系,采用Kubernetes的企业每每都开始了微服务架构的探索。然而不一样企业不一样阶段的微服务实践面临的问题千差万别,注定要在技术路线上产生分叉。如何选择适合本身的技术,是每个践行微服务的团队面临的第一个问题。网易云是Kubernetes的第一批重度用户,在不一样业务场景下解决了不少挑战,在本文中,网易云首席解决方案架构师刘超梳理了基于Kubernetes构建微服务体系的进阶之路。数据库

微服务化的必要性

一个产品的发展,一般可分为冷启动阶段、高速增加阶段和成熟阶段。
产品冷启动阶段,需求是以最简单的架构验证业务。以网易考拉海购(如下简称“考拉”)为例,最初的架构设计目标就是快速启动,验证产品方向,该架构包括在线、缓存、线下和管理服务四个方面,即通常电商平台加上跨境电商必备的进销存系统,采用了Oracle数据库、OpenStack管理的虚拟机(VM),并无诸如高并发之类的考虑。缓存

产品高速增加阶段,业务规模逐渐扩大,产品复杂度也随着增长,企业须要解决快速迭代、高可靠和高可用等问题,一个天然的选择是服务化的拆分,把一个单体架构拆分红一些较小的模块,并遵循康威定律,用5-9个小团队来适应架构的变化。仍以考拉为例,考拉在高速增加阶段也慢慢演化出各类新的模块,好比单独的支付模块、货仓模块、第三方商家模块、推送模块等,并基于Dubbo框架打造服务发现功能来支持各模块之间的相互调用。网络

服务化主要解决了变动的问题。在整个架构演进的过程当中,各个模块都面临爆炸性的增加,好比海淘、自营、第三方商家的供应链,Web、APP、H5的呈现,限时购、秒杀、预售的活动页,以及仓库与物流系统、支付系统的对接等,紧耦合则牵一发而动全身,工程臃肿,影响迭代速度,分别独立上线更有利于适应业务发展的需求。考拉在高速增加阶段首先按照主页、活动页、优惠券、支付等维度纵向拆分,以后又不断演进成为100多个相互关联的模块,变动频率由天天2次增加到天天1000屡次,产品质量提高52%。架构

容器化的优点与挑战

拆分红大量小模块以后,虚拟机与服务化架构的配合就出现了不少新的挑战,因而有了容器化的需求。并发

刘超解释说,拆分以前首先要解决“合”的问题,即须要保证功能仍是原来的功能,代码质量仍是原来的代码质量,不会引入新的bug。他认为,微服务化须要从一开始就要作好持续集成,而容器是很好的持续集成的工具,完成从代码提交到自动测试、自动发布的工做。容器化会带来开发流程的变化,把环境交付过程从运维人员提早到开发人员手上。负载均衡

图片描述

在架构复杂的状况下,好比100多个模块,再加上各类副本,全部环境都由一个运维团队来完成,不只工做量繁重,并且还容易出错,但这是使用虚拟机的模式。而若是写一个Dockerflie放到代码仓库,由开发人员来考虑开发完成以后应用部署的配置环境、权限等问题,包括测试环境的部署、联调环境的部署、生产环境的部署,问题就很好解决了。这就是容器化带来的流程变化。
然而,这种转变涉及到开发人员是否愿意学习容器技术。刘超推荐的解决办法,是使用镜像分层的形式,即最内部的环境包括操做系统及系统工具的镜像由运维人员来作,中间层环境的镜像由核心开发人员完成,普通开发人员只需把jar或者war扔到相应的路径下便可,这就极大下降企业组织容器化的障碍。框架

图片描述

场景一:Kubernetes + Docker + VM + Host Network

第一种场景,就是用Kubernetes管理虚拟机,容器的网络、存储会面临各类各样的选型。企业若是对容器的网络、存储了解不足,能够把容器当成一个持续集成的工具,把一个容器嵌入到一个虚拟机里面,至关于用容器镜像代替脚本部署。这种作法须要解决两个问题:一是IP保持的问题,二是盘保持的问题。由于原先采用虚拟机的时候,是基于有状态的设计,认为IP、Volume都是保持不变的。当容器仅仅做为持续集成的工具,团队的这个习惯可能改不了。less

一个方案是本身实现一个有状态容器的方式,实现IP的保持,当一个节点挂了,从新启动的虚拟机和容器仍然可使用原先分配的IP,二是把Docker容器的镜像一层层地Mount到外面的Volume里面,当一个节点挂了,Docker全部的镜像和Volume其实还挂载在外面的Ceph上,数据并未丢失。这和使用VM很类似,既能够Docker化支持微服务化,也不须要改变用户习惯。使用Kubernetes压力相对比较大的团队,能够经过这种方式切入。运维

场景二:Kubernetes + Docker + PM + Bridge Network

第二种场景,企业没有使用虚拟机,有一部分应用部署在物理机(PM)上,同时想把一部分应用迁移到容器里。此时,无论物理机是否嵌套虚拟机,直接建立一个Bridge Network,把物理网卡也打进去,当Docker的网卡和Bridge连起来的时候,整个网络就是平的,容器和容器旁边的物理机都使用同一个指定的网段。网络打平以后,使用Dubbo的团队也能够比较顺畅地把一部分物理机上部署的应用逐渐迁移到容器里,而若是没有Bridge Network,中间过负载均衡(LB)或者NAT时会很别扭,由于Kubernetes层的维护人员一般很难劝说Dubbo层开发人员改变应用开发的方式。分布式

使用Bridge Network,Kubernetes网络配置很简单,使用CNI的方式便可。若是有定制化以适应应用层的需求,能够参考Docker run的手动配置方式,开发本身的CNI插件。大体流程是先建立网桥(若是不存在),获取Namespace,配置veth pair并放到Namespace里,而后获取IP地址,获取网络和路由。

场景三:Kubernetes + Docker + PM + SR-IOV Network

Bridge的方式,可以知足通常的Java应用部署的需求,但一些须要更高性能的应用,须要高吞吐量、高并发、高PPS,好比电商大促状况下的缓存,这时候能够采用SR-IOV代替Bridge来解决问题,带宽比较大但PPS上不去(大包或大量小包)的状况,SR-IOV均可以解决,可是须要购买SR-IOV网卡,成本比较高。

高可用设计要点

无状态。作好持续集成以后,第一件事情应该是把应用分为有状态(Stateful)和无状态(Stateless)两个部分,而且使大部分应用是无状态的,这样能够更好地适应弹性伸缩。即使Kubernetes已经能够支持有状态应用的部署,刘超仍是建议在应用层尽可能实现无状态,使得有状态应用汇集在少数的集群里面。有状态最重要的是数据库和缓存,一般内存数据放在缓存,须要持久化的数据放在数据库里。

图片描述

分布式数据库。数据库的高可用,网易云采用的是DDB(分布式数据库)方案,基于MySQL的多台主备及负载均衡作分库分表,网易云RDS基于本身的MySQL内核优化,可以实现主备切换不丢数据,可以很好地支持容器化,有状态容器挂掉以后,从新启动一个容器,只要作好前序重置和幂等,就不会有业务问题。因此网易云RDS的主备切换也从虚拟机向容器过渡。

缓存。高并发应用须要每一层都有缓存,把客户需求尽量地拦在前面,吞吐量就大不少。但缓存不像数据库同样有持久化机制,其高可用、跨机房就须要作双写,由于缓存保持在内存中,挂了就没有了,修复难度很大。其余的组件,好比ZooKeeper、Kafka、消息队列、HBase,都有各自的高可用机制。因此,一个发展中的应用应当被分红很显著的两个部分,一部分是无状态的,另外一部分有状态的就放到自己具备高可用机制的组件里面。

成熟阶段架构

产品成熟阶段要解决的问题,主要是如何经过服务治理、系统运维自动化提高可靠性和可用性,如何高效完成大项目的复杂协做,如何梳理功能、深化用户体验。以正在进行全面服务化的考拉为例,2017年双11期间其工程数量相对平时增长了20多倍,应用、存储集群规模膨胀了5倍,挑战之大没必要多说。刘超对成熟阶段架构设计强调了两点:

不可变基础设施:使用Kubernetes容器技术不能沿袭虚拟机时代的操做方式,而是应当采用不可变基础设施,即全部的改变,都应该在Git的改变里面有所体现,修改环境就是修改Dockerfile,修改配置文件也是代码层次的改变,整个环境的部署,当代码merge的时候,会触发经过容器自动部署的脚本,这能很好地保持环境的一致性。大规模节点下,若是是手动部署,出错很容易,排查却很难。因此,不可变基础设施很是重要。

IaC(基础设施即代码)部署与扩容:网易云在Kubernetes的编排以外封装了另外一个编排,也是在仓库里面维护的,任何的修改,好比要升级5个应用,这5个应用的版本号都在这里面都配置好,代码commit以后就触发自动部署,若是发现问题,很容易回滚,只需把代码revert回来,后续流程会自动触发。若是依赖于写Yaml文件来作,频繁升级且版本号控制很差时,就很容易回滚失误。

场景四:Kubernetes+Docker+PM+Overlay Network

成熟阶段一般使用Kubernetes+Docker+PM+Overlay Network的模式,企业一旦开始用Overlay Network,基本上都会使用物理机,不然使用虚拟机会出现两层Overlay。这时候Flannel、Calico、Romana或者Weave等不少的选型均可以,Flannel的性能已经愈来愈好。

场景五:Kubernetes和IaaS层深度融合

网易云的方式,是Kubernetes与IaaS深度融合实现动态扩展资源,目前集群调度规模支持30000+节点。这个规模下,首先要解决的是动态资源建立优化,这样才符合资源精细利用、成本最优化的设计。同时,不论虚拟机的建立仍是容器的建立,对应用都是透明的,也就是说,应用只须要明确一个模块要变成3个节点仍是5个节点,不须要管Docker是否是要变成多少个节点、这些节点要放在哪里、虚拟机和物理机是否有资源之类的问题,后续的动做都是联动的。

动态资源建立的实现,网易云改造了Kubernetes建立流程,主要是监听Pod建立的事件,由Resource Controller判断有没有足够的Volume资源、Network资源,Schedule判断有没有足够的Node资源,有则直接绑定,无则动态申请以后再绑定,而后由Kubernetes下发。添加资源的时候,只有应用层和机房两层,机房只须要把物理机添加到IaaS层,不须要管上面是否有Kubernetes,虚拟机的建立所有是动态的,应用层只管应用层的事情,中间都是透明的。

图片描述

其次是网络优化。网易云大部分容器是运行在虚拟机上的,同时也提供采用SR-IOV网卡的裸机容器,用于须要更高性能的缓存、分布式数据库等。大部分的应用能够横向扩展,仍是在IaaS里面。可是网易云但愿容器里面的网卡,让最外层虚拟机上的OVS也能够看到,即只有一层Overlay,虚拟机里面有一个Bridge,但若是不须要,也能够直接打到外面的OVS上,另外还有一个管理网络,跨租户也是同一个Kubernetes来管理。只有一层Overlay意味着没有二次的虚拟化,同时原来部署在虚拟机里面的应用迁移到容器中,虚拟机和容器的网络都是经过OVS来管理,采用Dubbo作服务发现会很是平滑,这是针对业务层压力的解决方案。其实OpenStack有一个CNI插件,也采用了相似的作法,和Neutron联动,把VIF打在外面的OVS上。

小结

本文结合网易云服务内外部客户的Kubernetes实践经验,总结了产品高速增加期和成熟期使用Kubernetes容器技术实现微服务架构的五种应用场景,针对不一样的挑战提出了易于执行的解决方案,并介绍了网易云的独门优化方法,但愿对读者有所启发。

相关文章
相关标签/搜索