业界比较认同的是William Morgan关于服务网格(Service Mesh)的一段定义,这里提取和解释该定义中的几个关键字来讲解服务网格的特点。
◎ 基础设施:服务网格是一种处理服务间通信的基础设施层。
◎ 云原生:服务网格尤其适用于在云原生场景下帮助应用程序在复杂的服务拓扑间可靠地传递请求。
◎ 网络代理:在实际使用中,服务网格一般是通过一组轻量级网络代理来执行治理逻辑的。
◎ 对应用透明:轻量网络代理与应用程序部署在一起,但应用感知不到代理的存在,还是使用原来的方式工作。
经典的服务网格示意图如图1-8所示。
图1-8 经典的服务网格示意图
笔者所在的团队曾经开发过一个微服务框架,该框架已经从 Apache 毕业。团队的老同事在聊起服务网格时,大家戏言它不就是个 Sidecar 嘛,其实我们为了支持多语言也构思过类似的东西,但那时还没有服务网格的概念。服务网格能这么快就产生如此大的影响,确实让人始料未及。那么,服务网格为什么会大行其道呢?
在云原生时代,随着采用各种语言开发的服务剧增,应用间的访问拓扑更加复杂,治理需求也越来越多。原来的那种嵌入在应用中的治理功能无论是从形态、动态性还是可扩展性来说都不能满足需求,迫切需要一种具备云原生动态、弹性特点的应用治理基础设施。
首先,从单个应用来看,Sidecar与应用进程的解耦带来的应用完全无侵入、开发语言无关等特点解除了开发语言的约束,从而极大降低了应用开发者的开发成本。这种方式也经常被称为一种应用的基础设施层,类比TCP/IP网络协议栈,应用程序像使用TCP/IP一样使用这个通用代理:TCP/IP 负责将字节码可靠地在网络节点间传递,Sidecar 则负责将请求可靠地在服务间进行传递。TCP/IP 面向的是底层的数据流,Sidecar 则可以支持多种高级协议(HTTP、gRPC、HTTPS 等),以及对服务运行时进行高级控制,使服务变得可监控、可管理。
然后,从全局来看,在多个服务间有复杂的互相访问时才有服务治理的需求。即我们关注的是这些 Sidecar 组成的网格,对网格内的服务间访问进行管理,应用还是按照本来的方式进行互相访问,每个应用程序的Inbound流量和Outbound流量都要经过Sidecar代理,并在Sidecar上执行治理动作。
最后,Sidecar是网格动作的执行体,全局的管理规则和网格内的元数据维护通过一个统一的控制面实现,如图 1-9 所示,只有数据面的 Sidecar 和控制面有联系,应用感知不到Sidecar,更不会和控制面有任何联系,用户的业务和控制面彻底解耦。
图1-9 服务网格的统一控制面
当然,正所谓没有免费的午餐,这种形态在服务的访问链路上多引入的两跳也是不容回避的问题。
如图1-10所示,从forecast服务到recommendation服务的一个访问必须要经过forecast服务的 Sidecar拦截 Outbound流量执行治理动作;再经过 recommendation服务的 Sidecar拦截Inbound流量,执行治理动作。这就引入两个问题:
◎ 增加了两处延迟和可能的故障点;
◎ 多出来的这两跳对于访问性能、整体可靠性及整个系统的复杂度都带来了新的挑战。
图1-10 服务网格访问路径变长
其中,后者本来就属于基础设施层面可维护性、可靠性的范畴,业界的几个产品都用各自的方式在保证。而前者引入的性能和资源损耗,网格提供商提供的方案一般是这样解决的:通过保证转发代理的轻量和高性能降低时延影响,尤其是考虑到后端实际使用的应用程序一般比代理更重,叠加代理并不会明显影响应用的访问性能;另外,对于这些高性能的代理,只要消耗足够的资源总能达到期望的性能,特别是云原生场景下服务的弹性特点使得服务实例的弹性扩展变得非常方便,通过扩展实例数量总是能得到期望的访问性能。
所以,对于考虑使用服务网格的用户来说,事情就会变成一个更简单的选择题:是否愿意花费额外的资源在这些基础设施上来换取开发、运维的灵活性、业务的非侵入性和扩展性等便利。相信,在这个计算资源越来越便宜、聪明的程序员越来越贵的时代,对于把程序员从机械的基础设施就可以搞定的繁杂事务中解放出来,使其专注于更能发挥聪明才智和产生巨大商业价值的业务开发上,我们很容易做出判断。
目前,华为、谷歌、亚马逊等云服务厂商将这种服务以云服务形态提供了出来,并和底层的基础设施相结合,提供了完整的服务治理解决方案。这对于广大应用开发者来说,更加方便和友好。
在多种服务网格项目和产品中,最引人注目的是后来居上的 Istio,它有希望成为继Kubernetes之后的又一款重量级产品。
在本书码字快要完成时,Istio在 GitHub上已经收获了近两万个 Star(https://timqian.com/star-history/#istio/istio),这着实是个非常了不起的成绩,如图1-11所示。
图1-11 Istio项目的Star进展
可以看到,Istio从2017年5月发布第1个版本0.1开始就被广泛关注。据Istio官方称,Istio 1.1解决了生产大规模集群的性能、资源利用率和可靠性问题,提供了众多生产中实际应用的新特性,已经达到企业级可用的标准。
首先,在控制面上,Istio作为一种全新的设计,在功能、形态、架构和扩展性上提供了远超服务网格的能力范围。它基于xDS协议提供了一套标准的控制面规范,向数据面传递服务信息和治理规则。Istio的早期版本使用Envoy V1版本的API,即Restful方式,其新版本使用Envoy V2版本的API,即gRPC协议。标准的控制面API解耦了控制面和数据面的绑定。Nginx的nginMesh、F5 Networks的Aspen Mesh等多种数据面代理支持Istio的控制面,甚至有些老牌微服务SDK也开始往Istio上集成,虽然其本身的功能定位和功能集合有些“不对齐”,但至少说明了Istio控制面的影响力和认同程度。
然后,在数据面的竞争上,Istio的标准数据面Envoy是由Lyft内部于2016年开发的,比 Linkerd更早。2016年9月,Envoy开源并发布了 1.0.0版本;2017年 9月,Envoy加入CNCF,成为第2个Service Mesh项目;2018年11月,Envoy从CNCF毕业,这标志着其趋于成熟。从开发语言上看,Envoy是使用C++开发的,其性能和资源占用比用Rust开发的 Linkerd Proxy 要更好,更能满足服务网格中对透明代理的轻量高性能要求;从能力上看,Envoy提供L3/L4过滤器、HTTP L7过滤器,支持HTTP/2、HTTP L7路由及gRPC、MongoDB、DynamoDB等协议,有服务发现、健康检查、高级LB、前端代理等能力,具有极好的可观察性、动态配置功能;从架构实现上看,Envoy是一个可高度定制化的程序,通过 Filter机制提供了高度扩展性,还支持热重启,其代码基于模块化编码,易于测试。除了在Istio中应用,Envoy在其他Service Mesh框架中也被广泛应用,渐渐成为Service Mesh的数据平面标准。
最后,在大厂的支持上,Istio 由谷歌和 IBM 共同推出,从应用场景的分析规划到本身的定位,从自身架构的设计到与周边生态的结合,都有着比较严密的论证。Istio项目在发起时已经确认了将云原生生态系统中的容器作为核心打包和运行时,将Kubernetes作为管理容器的编排系统,需要一个系统管理在容器平台上运行的服务之间的交互,包括控制访问、安全、运行数据收集等,而 Istio 正是为此而生的;另外,Istio 成为架构的默认部分,就像容器和Kubernetes已经成为云原生架构的默认部分一样。
云原生社区的定位与多个云厂商的规划也不谋而合。华为云已经在 2018 年 8 月率先在其容器服务CCE(Cloud Container Engine)中内置Istio;Google的GKE也在2018年12月宣布内置 Istio;越来越多的云厂商也已经选择将 Istio作为其容器平台的一部分提供给用户,即提供一套开箱即用的容器应用运行治理的全栈服务。正因为看到了 Istio 在技术和产品上的巨大潜力,各大厂商在社区的投入也在不断加大,其中包括Google、IBM、华为、VMware、思科、红帽等主流厂商。