Part 01
要解决的问题
微服务自在2012年提出的概念以来,出现了Spring Could、Dubbo,Spring Cloud Alibaba等成熟稳定的实现方案,并在实际生产中受到广泛应用。其根本思想是通过拆分原则,希望一个服务只负责业务中一个独立的功能,这样任何一个需求不会因为发布或者维护而影响到不相关的服务,然而随着业务越来越大,拆分的服务实例越来越多,各个服务之间的依赖调用就变成了非常复杂的网络拓扑结构,类似于图1所示,就会面临着以下问题。
治理难度大、技术门槛高
随着微服务实施水平的不断深化,除了基础的服务发现,配置中心和授权管理之外,在实施的过程中不可避免的需要在服务治理层面面临着各种新的挑战如分布式跟踪,熔断降级,灰度发布,故障切换等等治理需求。这些众多的非业务性需求,涉及到运维、运营管理层面,这使得整个项目在组织、分工、权责上变得交叉模糊,同时对相关人员提出了非常高的技术要求,然而我们开发的是业务程序,它的核心价值是业务逻辑的处理和实现,将越来越多的时间和精力花费在这些非业务功能上是非常不合理的。
多语言支持不足
对于稍具规模的团队,多语言的技术栈和跨语言调用是常态,然而目前开源社区上并没有一套统一的跨语言的微服务技术[1],那些没有框架支持的语言编写的服务很难融入面向微服务的已有架构体系中,想因地制宜的用多种语言实现架构体系中的不同模块在现实开发中很难做到。
代码侵入性强
主流的微服务实现框架或多或少都对业务代码有一定的侵入性,比如Spring Cloud框架中几乎每个微服务都需要集成Eureka、Feign等组件,这些组件框架替换成本高,复杂项目依赖时的库版本兼容问题也非常棘手,同时,框架库的升级也无法对服务透明,服务会因为和业务无关的依赖库升级而被迫升级,我们希望的是尽量将负责服务间通信的这种非业务代码从业务功能代码中剥离出来。
Part 02
Service Mesh架构思想
为解决上述微服务存在的问题,Service Mesh(服务网格)应运而生,它主要作为处理服务间通信的基础设施层,独立于具体的服务而存在,目的是从根本上解决了多语言支持不足以及代码侵入性的问题,并且凭借服务网格的独立性,使得业务团队不再需要关心复杂的服务治理工作,可以全权交给服务网格处理。
- 核心思想
服务网格的核心思想为Sidecar模式(边车模式),即将每个服务的负载、限流和服务发现等等通信功能和应用业务本身功能进行解耦分离,其负责服务间通信的部分称之为Sidecar代理,业务功能代码只和同机器下的不同进程的代理通信。如图2所示。
- 名称由来
由于每一个服务实例都会有一个Sidecar代理与之配对,服务之间的通信都是通Sidecar进行,在部署图表示为代理的交叉连接形成了一种网络网格,故称之为“服务网格”。目前所说的Service Mesh在若干服务的Sidercar代理基础上提供了统一集中式管理的运维入口即控制面平面, SideCar代理也称为数据平面 ,因此我们通常说Service Mesh由数据平台和控制平面组成,其结构如图3所示。
Part 03
Istio简介
- Istio是什么?
Service Mesh(服务网格)只是一种架构思想,主流的实现方案有Istio、Linkerd、Linkerd2、Consoul等等。其中Istio是目前最受欢迎且在实际生产中应用最为广泛的服务网格,它是由Google,IBM和Lyft这三家互联网巨头联合开发的一个基于服务网格的开源项目,功能丰富,成熟度高。下面将简单介绍Istio的框架及功能。
- Istio架构
Istio架构如下图所示,在逻辑上与Service Mesh框架思想保持一致,分为数据平面和控制平面两大部分,整体架构如图4所示。
①数据平面
数据平面由一组以Sidecar方式部署的Envoy代理组成,所有进入和流出服务的流量都会被Envoy拦截,并与控制平面进行交互,根据配置执行相应的通信功能。
Envoy是用C++开发的高性能代理,Envoy代理作为唯一与数据平面流量交互的 Istio组件,相对于其他服务网格实现方案代理来说有着更丰富的治理能力和灵活的配置方式,并且支持各种插件可用于扩展流量治理能力,可生成遥测数据[2]。
Envoy和Istio并不是强绑定关系,Envoy可以在其他框架中使用,Istio也可以采用其他代理。Envoy本身的内置功能有:负载均衡、TLS 终止、动态服务发现、HTTP/2&gRPC 代理,熔断器,健康检查,基于百分比流量拆分的分段推出,故障注入等。Envoy允许在不需要重新设计架构或重写代码条件下,启用或执行的一些Istio的功能和任务,比如:流量控制功能、网络弹性特性、安全性和身份认证特性基于WebAssembly的可插拔扩展模型等。
②控制平面
Istio的控制平面提供服务发现、配置和证书管理。由Pilot、Citadel、Galley三个组件整合成了一个单进程、多模块的istiod,极大的降低了部署的复杂度。在整个运行流程中,需要这些组件协同工作。
Pilot组件是控制面最重要的组件,负责提供服务发现、流量路由及服务治理功能,其架构如图5所示。
服务发现:Pilot通过插件的形式可以支持多种服务注册平台(K8s、Mesos等),通过平台适配器(Platform Adapter)将服务注册平台的服务数据填充为标准服务模型(Abstract Model),例如Pilot通过K8s适配器,将K8s中的Service及Pod实例等服务信息,转换为标准模型供Pilot使用。Pilot在得到统一的服务信息后,将服务信息通过Envoy API下发到数据面Envoy代理,实现服务发现功能[3]。
流量路由及服务治理:运维人员可以通过Rules API指定各种高级流量管理规则(Gateway、VirtualService等),这些规则将被转换为数据面Envoy可以识别的格式,通过Envoy API下发给Envoy,Envoy在得到这些规则后,按照规则进行流量转发及安全认证[3]。
Gally是负责配置的验证和处理的组件,从底层平台获取配置,验证配置信息的格式和内容的正确性,并将这些配置信息提供给Pilot使用。
Citadel 是与安全相关的组件,主要负责密钥和证书的管理,可以实现强大的授权和认证等功能。
Part 04
总结
本文从传统微服务在具体实施中存在的问题出发,简述了为解决这些问题而产生的服务网格架构思想,最后对这种架构思想一种最受欢迎的实现方案Istio和核心组件进行了的简单介绍。但是任何一种方案都很难做到一劳永逸,Istio只是把原来分散在应用内部的复杂性统一抽象出来放到了统一的地方,且Istio的架构相对复杂,在具体生产中,必须做好清楚的规划,权衡它带来的好处是否远大于额外维护它的花费,选择合适的架构方案。