本文源自《云原生服务网关Istio——原理、实践、架构与源码分析》
1. Istio是什么?
Istio 是一个
与Kubernetes紧密结合
的适用于云原生场景
的Service Mesh形态的
用于服务治理
的开放平台。
根据Istio官方的介绍,服务治理涉及连接(Connect)、安全(Secure)、策略执行(Control)和可观察性(Observe)。
-
连接
:Istio通过集中配置的流量规则控制服务间的流量和调用,实现负载均衡、熔断、故障注入、重试、重定向等服务治理功能。 -
安全
:Istio提供透明的认证机制、通道加密、服务访问授权等安全能力,可增强服务访问的安全性。 -
策略执行
:Istio通过可动态插拔、可扩展的策略实现访问控制、速率限制、配额管理、服务计费等能力。 -
可观察性
:动态获取服务运行数据和输出,提供强大的调用链、监控和调用日志收集输出的能力。配合可视化工具,可方便运维人员了解服务的运行状态,发现并解决问题。
2. Istio的重要能力
-
服务运行可观察性
:监控应用及网络相关数据,将相关指标与日志记录发送至任意收集、聚合与查询系统中以实现功能扩展,追踪分析性能热点并对分布式故障模式进行诊断。 -
弹性与效率
:提供了统一的方法配置重试、负载均衡、流量控制和断路器等来解决网络可靠性低所造成的各类常见故障,更轻松地运维高弹性服务网格。 -
研发人员生产力
:确保研发人员专注于基于已选择的编程语言构建业务功能,不用在代码中处理分布式系统的问题,从而极大地提升生产能力。 -
策略驱动型运营
:解耦开发与运维团队的工作,在无须更改代码的前提下提升安全性、监控能力、扩展性与服务拓扑水平。运营人员能够不依赖开发提供的能力精确控制生成流量。 -
默认安全
:允许运营人员配置TLS双向认证并保护各服务之间的所有通信,并且开发人员和运维人员不用维护证书,以应对分布式计算中经常存在的大量网络安全问题。 -
增量适用
:考虑到网络中运行的各服务的透明性,允许团队按照自己的节奏和需求逐步适用各项功能,例如先观察服务运行情况再进行服务治理等。
3. Istio与服务治理
Istio是一个服务治理平台,治理的是服务间的访问,只要有访问就可以治理,不在乎这个服务是不是所谓的微服务,也不要求跑在其上的代码是否是微服务化的。
3.1 关于微服务
微服务是以一组小型服务来开发单个应用程序的方法,每个服务都运行在自己的进程中,服务间采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并可通过全自动部署机制独立部署,还共用一个最小型的集中式管理,可用不同的语言开发,并使用不同的数据存储技术.
——————————Martin Fowler
微服务本质上是分而治之、化繁为简的哲学智慧在计算机领域的体现。
3.1.1 微服务带来的好处:
-
从开发视角来看
:每个服务的功能更内聚,可以在微服务内设计和扩展功能,并且采用不同的开发语言及开发工具; -
从运维视角来看
:在微服务化后,每个服务都在独立的进程里,可以自运维;更重要的是,微服务化是单一变更的基础,迭代速度更快,上线风险更小; -
从组织管理视角来看
:将团队安装微服务切分成小组取代服务大组也有利于敏捷开发。
3.1.2 微服务的缺点:
- 服务数量变多,业务本身的规模和复杂度并没有变少,反而变多。
- 在分布式系统中,网络可靠性、通信安全、网络时延、网络拓扑变化等都成立我们要关注的内容。
- 微服务机制带来了大量的工作,比如服务如何请求目标服务,需要引入服务发现和负载均衡等,以及对跨进程的分布式调用栈进行分布式调用链路追踪。
总之,简单的事情突然变得复杂了。
3.2 服务治理的三种形态
服务治理的演变至少经过了以下三种形态。
3.2.1 第一种形态:在应用程序中包含治理逻辑
自己写代码去实现服务发现和治理的逻辑。
缺点
:
- 功能简单;
- 实现成本高,存在大量重复代码;
- 维护和升级困难;
3.2.1 第二种形态:治理逻辑独立的代码
典型代表:Spring Cloud Eureka
优点
:
- 在代码上解耦了业务和治理逻辑
缺点
:
业务代码和SDK还是要一起编译,业务代码和治理逻辑孩子同一个进程内,这就导致几个问题:
- 业务代码必须和SDK基于同一种语言,即语言绑定;
- 治理逻辑升级时,还需要用户的整个服务升级;
- SDK对开发人员来说有较高的学习门槛。
3.2.3 第三种形态:治理逻辑独立的进程
把治理逻辑彻底从用户的业务代码中剥离出来,即Sidecar模式。
优点
:
- 用户的代码和治理逻辑都以独立的进程存在,两者的代码和运行都无耦合,这样可以做到与开发语言无关,升级也相互独立;
- 在对已存在的系统进行微服务治理时,只需搭配Sidecar即可,对原服务无需做任何修改;
- 可以对老系统渐进式升级改造,先对部分服务进行微服务化。
3.2.3 三种服务治理形态的比较
形态 | 业务逻辑侵入 | 业务代码侵入 | 业务进程侵入 |
---|---|---|---|
在应用程序中包含治理逻辑 | Y | Y | Y |
治理逻辑独立的代码 | N | N | Y |
治理逻辑独立的进程 | N | N | N |
4. Istio与服务网格
业界比较认同的是William Morgan关于服务网关(Service Mesh)的一段定义,这里提取和解释该定义中的几个关键字来讲解服务网格的特点:
-
基础设施
:服务网格是一种处理服务间通信的基础设施层。 -
云原生
:服务网格尤其适用于在云原生场景下帮助应用程序在复杂的服务拓扑间可靠地传递请求。 -
网络代理
:在实际使用用,服务网格一般是通过一组轻量级网络代理来执行治理逻辑的。 -
对应用透明
:轻量网络代理与应用程序部署在一起,但应用感知不到代理的存在,还是使用原来的方式工作。
经典的服务网格示意图如下图所示:
4.1 时代选择服务网格
在云原生时代,随着采用各种语言开发的服务剧增,应用间的访问拓扑更加复杂,治理需求也越来越多。原来的那种嵌入在应用中的治理功能无论是从形态、动态性还是可扩展性来说都不能满足需求,迫切需要一种具备云原生动态、弹性特定的应用治理基础设施。
首先,从单个应用来看,Sidecar与应用程序的解耦带来的应用完全无侵入
、开发语言无关
等特点解除了开发语言的约束,从而极大降低了应用开发者的开发成本。
然后,从全局来看,在多个服务间有复杂的互相访问时才有服务治理的需求。即我们关注的这些Sidecar组成的网格,对网格内的服务间访问进行管理,引用还是按照本来的方式进行互相访问,每个应用程序的Inbound流量和Outbound流量都要经过Sidecar代理,并在Sidecar上执行治理动作
。
最后,Sidecar是网格动作的执行体,全局的管理规则和网格内的元数据维护通过一个统一的控制面实现,如下图所示,只有数据面的Sidecar和控制面有联系,应用感知不到Sidecar,更不会和控制面有任何联系,用户的业务和控制面彻底解耦。
4.2 服务网格带来的新问题
服务网格确实有很多优势,正所谓没有免费的午餐,这种形态在服务的访问链路上多引入的两跳也是不容回避的问题。
- 增加了两处延迟和可能的故障点;
- 多出来的这两跳对应访问性能、整体可靠性及整个系统的复杂度都带来了新的挑战。
针对性能和资源损耗,网格提供商提供的方案一般是这样解决的:
-
通过保证转发代理的轻量和高性能降低时延影响
,尤其是考虑到后端实际使用的应用程序一般比代理更重,叠加代理并不会明显影响应用的访问性能; - 另外,对于这些高性能的代理,只有消耗足够的资源总能达到期望的性能,特殊是云原生场景下服务的弹性特点使得服务实例的弹性扩展变得非常方便,通过
扩展实例数量
总是能得到期望的访问性能。
4.3 服务网格选择Istio
- 在控制面上,Istio作为一种全新的设计,在功能、形态、架构和扩展性上提供了远超服务网格的能力范围;
- Istio基于xDS协议提供了一套标准的控制面规范,想数据面传递服务信息和治理规范;
- Istio的早期版本使用Envoy V1版本的API,即RESTful方式,其新版本使用Envoy V2版本的API,即gRPC协议;
- Envoy是用C++开发的,其性能和资源占用比用Rust开发的Linkerd Proxy更好,更能满足服务网格中对透明代理的轻量高性能的要求;
- Envoy提供L3/L4过滤器、HTTP L7过滤器、支持HTTP/2、HTTP L7路由及gRPC、MongoDB、DynamoDB等协议;
- Envoy有服务发现、健康检查、高级LB、前端代理等能力,具有极好的可观察性、动态配置功能;
- Envoy是一个可高度定制化的程序,通过Filter机制提供了高度扩展性,还支持热重启,其代码基于模块化编码,易于测试;
- 在大厂支持上,Istio由谷歌和IBM共同推出,从应用场景的分析规划到本身的定位,从自身架构的设计到与周边生态的结合,都有着比较严密的论证;
- Istio与Kubernetes无缝结合,Istio称为架构的默认部分,就像容器和Kubernetes已经成为云原生架构的默认部分一样。
4.4 Istio与Kubernetes
Kubernetes的Service基于每个节点的kube-proxy从kube-apiserver上获取Service和Endpoint的信息,并将对Service的请求经过负载均衡转发到对应的Endpoint上。
但Kubernetes只提供了4层负载均衡能力,无法基于应用层的信息进行负载均衡,更不能提供应用层的流量管理,在服务运行管理上也只提供了基本的探针机制,并不能提供服务访问的指标和调用链追踪这种应用的服务运行诊断能力。
Istio复用了Kubernetes Service的定义,在实现上进行了更细粒度的控制。
Istio的服务发现就是从kube-apiserver中获取Service和Endpoint,然后将其转换成Istio服务模型的Service和ServiceInstance,但是其数据面组件不再是kube-proxy,而是在每个Pod里部署的Sidecar,也可以将其看作每个服务实例的Proxy。
通过拦截Pod的Inbound流量和Outbound流量,并在Sidecar上解析各种应用层协议,Istio可以提供真正的应用层治理、监控和安全等能力。
总之,Istio和Kubernetes从设计理念、使用体验、系统架构甚至代码风格等小细节来看,关系都非常紧密,甚至有人认为Istio就是Kubernetes团队开发的Kubernetes可插拔的增强特性。