乐趣区

必须要了解的Service-Meth-Istio

传统的微服务架构本身就是残次品,很快就会被淘汰,所以 Service Meth 必须掌握。

本文经出版社授权发布,摘自《Istio 实战指南》第二章节

Istio:

它是一个完全开源的服务网格,以透明层的方式构建在现有分布式应用中。它也是一个提供了各种 API 的平台,可以与任何日志平台、监控系统或策略系统集成。Istio 的多样化特性可以让你高效地运行分布式微服务架构,并提供一种统一的方式来保护、连接和监控微服务。

从上面的定义中可以了解到,Istio 为微服务应用提供了一个完整的解决方案,可以以统一的方式去检测和管理微服务。同时,它还提供了管理流量、实施访问策略、收集数据等功能,而所有这些功能都对业务代码透明,即不需要修改业务代码就能实现。

有了 Istio,就几乎可以不需要其他的微服务框架,也不需要自己去实现服务治理等功能,只要把网络层委托给 Istio,它就能帮助完成这一系列的功能。简单来说,Istio 就是一个提供了服务治理能力的服务网格。

Istio 的架构
对服务网格来讲,业务代码无侵入和网络层的全权代理是其重要的优势。我们来了解一下 Istio 的架构,看一看它是如何做到这两点的,并了解架构中的各个组件是如何协同工作并完成网络层功能的。

Istio 的架构从逻辑上分成数据平面(Data Plane)和控制平面(Control Plane)。是否觉得似曾相识?没错,Kubernetes 的架构也具有相似的结构,分为控制节点和计算节点。毫无疑问,这样的设计可以很好地解耦各个功能组件。

数据平面:由一组和业务服务成对出现的 Sidecar 代理(Envoy)构成,它的主要功能是接管服务的进出流量,传递并控制服务和 Mixer 组件的所有网络通信(Mixer 是一个策略和遥测数据的收集器,稍后会介绍)。
控制平面:主要包括了 Pilot、Mixer、Citadel 和 Galley 共 4 个组件,主要功能是通过配置和管理 Sidecar 代理来进行流量控制,并配置 Mixer 去执行策略和收集遥测数据(Telemetry)。

图 2 - 1 展示了由这些组件组成的 Istio 架构。

图 2 -1 Istio 架构

从 Istio 的架构中可以看出,Istio 追求尽可能的透明,通过各种解耦设计让系统对内对外都没有依赖。同时,它还提供了高度的扩展性。Istio 认为随着应用的增长和服务的增多,扩展策略系统是最主要的需求,因此它被设计为以增量的方式进行扩展。可移植也是 Istio 在设计中充分考虑的因素,它被设计为支持多种平台,以便服务可以被方便地迁移到不同的云环境中(在撰写本书的过程中,Istio 仍然深度依赖于 Kubernetes 平台)。
通过数据平面和控制平面的分离,各个组件都成为插件,这种开放和包容的设计思路相当具有前瞻性,我想这也就是其他服务网格产品都放弃了和它竞争而选择合作的重要原因。

下面对架构中的各组件做进一步介绍。

Istio 的核心控件

Envoy
从 2.2 节的架构图可以看出,Istio 的数据平面就是指代理。Istio 选择 Envoy 作为 Sidecar 代理,Envoy 本质上是一个为面向服务的架构而设计的 7 层代理和通信总线。Envoy 基于 C ++11 开发而成,性能出色。除了具有强大的网络控制能力外,Envoy 还可以将流量行为和数据提取出来发送给 Mixer 组件,用以进行监控。

Envoy 在网络控制方面的主要功能如下。
HTTP 7 层路由。
支持 gRPC、HTTP/2。
服务发现和动态配置。
健康检查。
高级负载均衡。

我们知道,在 Kubernetes 环境中,同一个 Pod 内的不同容器间共享网络栈,这一特性使得 Sidecar 可以接管进出这些容器的网络流量,这就是 Sidecar 模式的实现基础。Envoy 是目前 Istio 默认的数据平面,实际上因为 Istio 灵活的架构,完全可以选择其他兼容的产品作为 Sidecar。目前很多服务网格产品都可以作为 Istio 的数据平面并提供集成。

Pilot
Pilot 是 Istio 实现流量管理的核心组件,它主要的作用是配置和管理 Envoy 代理。比如可以为代理之间设置特定的流量规则,或者配置超时、重试、熔断这样的弹性能力。Pilot 会将控制流量行为的路由规则转换为 Envoy 的配置,并在运行时将它们广播到 Envoy。另外,Pilot 还能够把服务发现机制抽象出来并转换成 API 分发给 Envoy,使得后者具有服务发现的能力。

简单来说,Pilot 的主要任务有两个。
从平台(如 Kubernetes)获取服务信息,完成服务发现。
获取 Istio 的各项配置,转换成 Envoy 代理可读的格式并分发。

图 2 - 2 展示了 Pilot 架构。Pilot 维护了一套独立于平台的服务规则,并提供了一个平台适配器,以便接入各种不同的平台。Rules API 对运维人员开放,使得他们可以设置想要的流量规则,Pilot 会把这些配置好的规则通过 Envoy API 分发给 Envoy 代理,以使其执行指定的规则。

图 2 -2 Pilot 架构

Pilot 还公开了用于服务发现并且可以动态更新负载均衡和路由表的 API。

Mixer
Mixer 的主要功能是提供策略控制,并从 Envoy 代理收集遥测数据。每次网络通信时 Envoy 代理都会向 Mixer 发出预检要求,用来检测调用者的合法性。调用之后 Envoy 代理会发送遥测数据供 Mixer 收集。一般情况下 Sidecar 代理可以缓存这些数据,不需要频繁地调用 Mixer。

适配器是 Mixer 的重要组成部分,它本质上是一个插件模型,每个插件叫作适配器。这项特性使得 Mixer 可以接入几乎任意的(只要定义好接口)后端基础设施。比如可以选择接入不同的日志收集器、监控工具和授权工具等;可以在运行时切换不同的适配器或者是打开(关闭)它们;还可以自定义适配器以满足特定需求。适配器极大地提高了 Mixer 的扩展性,它让 Istio 的功能拥有了更多可能性。图 2 - 3 展示了 Mixer 的架构图并展示了它和 Envoy 的交互方式。

图 2 -3 Mixer 架构

Citadel
Citadel 是与安全相关的组件,主要负责密钥和证书的管理。它可以提供服务间和终端用户的身份认证,还可以加密服务网格中的流量。在后面介绍安全主题的第 8 章中,我们会详细说明它是如何和其他组件协同工作的。

Galley
在 2019 年 3 月份发布的 1.1 版本中,Galley 作为一个独立的组件被添加到了架构当中(在此之前的版本中 Galley 并未独立出现),它现在是 Istio 主要的配置管理组件,负责配置的获取、处理和分发。Galley 使用了一种叫作 MCP(Mesh Configuration Protocol,网格配置协议)的协议与其他组件进行通信。

Istio 的主要功能
下面详细地介绍一下 Istio 的 4 个主要功能和实现原理。

1、流量管理
第 1 章介绍过,微服务应用最大的痛点就是处理服务间的通信,而这一问题的核心其实就是流量管理。首先来看一看传统的微服务应用在没有服务网格介入的情况下,如何完成诸如金丝雀发布这样的动态路由。假设不借助任何现成的第三方框架,一个简单的实现方法是,在服务间添加一个负载均衡(如 Nginx)做代理,通过修改配置的权重来分配流量。这种方式将对流量的管理和基础设施(云服务器、虚拟机、实体机等)绑定在了一起,难以维护。

而使用 Istio 就可以轻松地实现各种维度的流量控制。图 2 - 4 展示了两种不同的金丝雀发布策略。第一种是根据权重把 5% 的流量路由给新版本;第二种是根据请求的头信息 User-Agent 把使用 iPhone 的用户流量路由到新版本。

图 2 -4 Istio 的流量管理

Istio 的流量管理是通过 Pilot 和 Envoy 这两个组件实现的,将流量和基础设施进行了解耦。Pilot 负责配置规则,并把规则分发到 Envoy 代理去实施;而 Envoy 按照规则执行各种流量管理的功能,比如动态请求路由,超时、重试和熔断,还可以通过故障注入来测试服务之间的容错能力。下面对这些具体的功能进行逐一介绍。

1.请求路由
Istio 为了控制服务请求,引入了服务版本(Version)的概念,可以通过版本这一标签将服务进行区分。版本的设置是非常灵活的,可以根据服务的迭代编号进行定义(如 v1、v2 版本);也可以根据部署环境进行定义(如 Dev、Staging 和 Production);或者是自定义任何用于区分服务的标记。通过版本标签,Istio 就可以定义灵活的路由规则以控制流量,上面提到的金丝雀发布这类应用场景就很容易实现了。

图 2 - 5 展示了使用服务版本实现路由分配的例子。服务版本定义了版本号(v1.5、v2.0-alpha)和环境(us-prod、us-staging)两种信息。服务 B 包含了 4 个 Pod,其中 3 个是部署在生产环境的 v1.5 版本,而 Pod4 是部署在预生产环境的 v2.0-alpha 版本。运维人员根据服务版本指定路由规则,通过 Pilot 同步给 Envoy 代理,使得 99% 的流量流向 v1.5 版本的生产环境,而 1% 的流量进入 v2.0-alpha 版本的预生产环境。

图 2 -5 服务版本控制

2.入口网关(Ingress)和出口网关(Egress)
服务间通信是通过 Envoy 代理进行的。同样,我们也可以在整个系统的入口和出口处部署代理,使得所有流入和流出的流量都由代理进行转发,而这两个负责入口和出口的代理就叫作入口网关和出口网关。它们相当于整个微服务应用的边界代理,把守着进入和流出服务网格的流量。图 2 - 6 展示了 Ingress 和 Egress 在请求流中的位置,通过设置 Envoy 代理,出入服务网格的流量也得到了控制。

图 2 -6 请求流中的 Ingress 和 Egress

3.服务发现和负载均衡
服务发现的前提条件是具有服务注册的能力。目前 Kubernetes 这类容器编排平台也提供了服务注册的能力。Istio 基于平台实现服务发现和负载均衡时,需要通过 Pilot 和 Envoy 协作完成,如图 2 - 7 所示。Pilot 组件会从平台获取服务的注册信息,并提供服务发现的接口,Envoy 获得这些信息并更新到自己的负载均衡池。Envoy 会定期地对池中的实例进行健康检查,剔除离线的实例,保证服务信息的实时性。

图 2 -7 服务发现和负载均衡

4.故障处理
Istio 的故障处理都由 Envoy 代理完成。Envoy 提供了一整套现成的故障处理机制,比如超时、重试、限流和熔断等。这些功能都能够以规则的形式进行动态配置,并且执行运行时修改。这使得服务具有更好的容错能力和弹性,并保证服务的稳定性。

5.故障注入
简单来说,故障注入就是在系统中人为地设置一些故障,来测试系统的稳定性和系统恢复的能力。比如为某服务设置一个延迟,使其长时间无响应,然后检测调用方是否能处理这种超时问题而自身不受影响(如及时终止对故障发生方的调用,避免自己受到影响且使故障扩展)。

Isito 支持注入两种类型的故障:延迟和中断。延迟是模拟网络延迟或服务过载的情况;中断是模拟上游服务崩溃的情况,表现为 HTTP 的错误码和 TCP 连接失败。

策略和遥测

1.策略
在微服务应用中,除了流量管理以外,常常还需要进行一些额外的控制,比如限流(对调用频率、速率进行限制)、设置白名单和黑名单等。

Istio 中的策略控制是依靠 Mixer 完成的。Envoy 代理在每次网络请求时,都会调用 Mixer 进行预先检查,确定是否满足对应的策略。同时,Mixer 又可以根据这些来自流量的数据,进行指标数据的采集和汇总,这就是遥测功能。

2.遥测(Telemetry)
遥测是工业上常用的一种技术,它是指从远程设备中收集数据,并传输到接收设备进行监测。在软件开发中,遥测的含义引申为对各种指标(metric)数据进行收集,并监控、分析这些指标,比如我们经常听到的 BI 数据分析。

Mixer 的一大主要功能就是遥测。前面已经说过,Envoy 代理会发送数据给 Mixer,这就使得 Mixer 具有了数据收集的能力。在本章 2.3 节对 Mixer 的介绍中读者已经了解到 Mixer 的插件模型,也就是适配器。Mixer 可以接入不同的后端设施作为适配器,来处理收集到的指标数据,比如日志分析系统、监控系统等。

可视化
在微服务应用越来越复杂的情况下,对整个系统的状态进行监控和追踪变得尤为重要。试想如果一个包含上百个服务的系统发生了故障却无法准确定位问题的根源,或者系统压力已经到了承受的临界值而运维人员却浑然不知,这是多么可怕的事情。没有完备的、可观察的监控系统就无法保障系统的稳定性。

Istio 可以很方便地和各种监控、追踪工具集成,以便我们以可视化的方式(网页)直观地查看整个系统的运行状态。比如可以集成 Prometheus 来进行指标数据的收集,然后将收集的数据放在 Grafana 监控工具中展示;还可以集成 Jaeger 作为追踪系统,帮助我们对请求的调用链进行跟踪,在故障发生时分析出现问题的根源;或者将请求日志记录到 Kibana 系统,以图表的方式进行数据分析。

以上提到的这些可视化工具都会在第 7 章被集成到 Istio,并得到详细的介绍。

安全
Istio 中的安全架构是由多个组件协同完成的。Citadel 是负责安全的主要组件,用于密钥和证书的管理;Pilot 会将授权策略等信息分发给 Envoy 代理;Envoy 根据策略实现服务间的安全通信;Mixer 负责管理授权等工作。图 2 - 8 展示了 Istio 的安全架构和运作流程。

图 2 -8 Istio 安全架构

1.认证
Istio 提供如下两种类型的身份认证。
传输认证:也叫作服务到服务认证。这种方式的认证是通过双向 TLS(mTLS)来实现的,即客户端和服务端(或者是调用者和被调用者)都要验证彼此的合法性。
来源认证:也叫作最终用户认证,用于验证终端用户或设备。Istio 使用目前业界流行的 JWT(JSON Web Token)作为实现方案(在配置项上 Istio 提供了扩展性,但在撰写本书时仍然只支持 JWT)。
这两种认证的工作原理类似,都是将来自平台的认证策略存储起来,然后通过 Pilot 分发给 Envoy 代理,如图 2 - 9 所示。

图 2 -9 认证架构

2.授权
Istio 的授权功能沿用了 Kubernetes 中的授权方式:RBAC(Role-Based Access Control,基于角色的访问控制)。它可以为网格中的服务提供不同级别的访问控制。比如命名空间级别、服务级别和方法级别。

图 2 -10 显示了授权的工作方式。运维人员编写授权策略的清单文件并将其部署到平台(Kubernetes)。Pilot 组件会获取策略信息并将其保存到自己的配置存储中,同时监听授权策略的变更情况,以便及时更新。然后 Pilot 会把授权信息分发给 Envoy 代理。Envoy 在请求到达的时候,评估当前的请求是否合法并作出相应的返回。

图 2 -10 授权架构

退出移动版