购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.3 控制平面

上一节向大家介绍了数据平面,它是对流量的实际承载,而承载的具体的操作方式则是由控制平面统一决定的。这样的设计为系统整体运维带来了极大便利,可能以往需要3~5人的运维团队,现在只需 1~2 个人就可以了。这些都得益于 Istio 平台化、透明接入的设计思想,将链路层面的基础服务与业务逻辑层明确界定开,并实施统一配置及管理,Istio 设计的优秀之处便在于此。

控制平台的核心由三大组件组成:Pilot、Mixer 及 Citadel,三个组件分别负责配置维护、策略执行及安全相关功能。它们都拥有非常强大的扩展性,特别是 Mixer,通过其扩展接口接入众多三方链路扩展。

接下来,就逐一向读者介绍。

2.3.1 Pilot 结构及功能

在 Istio 架构中,Pilot 是对各容器平台(也可以是VM)的逻辑抽象,通过适配器模式,形成统一的对接接口,官方版本可以支持 Kubernetes、Cloud Foundry 及 Apache Mesos。由于Istio 开源,要想支持更多的平台也是非常容易的事。

Pilot 的基本工作就是为数据平台的 Sidecar 提供服务发现能力,让服务之间可以相互发现,并根据配置的策略进行调用。不过 Pilot 本身并不做服务注册,它只是提供一个接口,对接已有的服务注册系统,例如 Eureka 、Etcd 等。除此之外,还负责为动态路由(如灰度发布、测试环境分离)提供总控配置,并将这些配置分发给数据平面代理(即 Envoy)。Pilot 对配置格式做了抽象,与具体代理支持的配置格式无关,并且能够实时推送给代理。这就是为什么 Istio能够支持多种平台的关键所在。

Pilot 的整体结构模块如图2.7所示。

图2.7 “官方文档中的 Pilot 构架图”

2.3.2 Mixer 结构及功能

在 Istio 架构中,Mixer 负责在服务调用之间实施控制策略,同时在调用间收集请求的遥测数据(例如调用时长、异常统计等)。Mixer 拥有非常强大的扩展接口,可以根据自己的需要添加各种链路功能,仅在官方文档中其支持的就达十几种。从逻辑抽象角度上来说,Mixer 提供两个方面的服务。

后端逻辑抽象 :链路除了正常的请求,还拥有很多扩展逻辑(如分布式请求日志),Mixer 将后端这些功能实现细节都屏蔽,只留下直观的接口,方便调用与扩展。

中心化的控制 :Mixer 能对每个请求进行细致的控制,让任何通信都处于管控范围内。

为了实现上述目的,每个请求在到达 Sidecar 的时候都需要向 Mixer 发起一次逻辑请求,以进行前置检查;而在每次请求结束之后,还需要再次向 Mixer 做一次汇报,如图2.8所示。

图2.8 “官方文档中的 Mixer 架构”

当处理请求到达 Mixer 时,其就会依次执行通过适配器注册的各类处理器,例如日志处理器、服务遥测处理器、鉴权处理器等。Mixer 的这种设计将基础层的逻辑从业务代码中完全抽取了出来,业务工程师只需要关心自己的业务逻辑,至于基础框架层面上的功能开发,只需要交给框架工程师即可。逻辑写好后,以适配器的形式注册到 Mixer 中就可以了,完全不需要业务工程师的介入。而且,这一切都是透明的。例如,如果想对请求的参数进行遥测,只需要对Mixer 添加如下配置即可:

这样配置好后,每次请求经过数据平面的代理网关 Envoy,其都会向 Mixer 发送相关数据信息,Mixer 中对应的模块会进行汇总处理,以报表的形式展现给运维与开发人员,这里 Istio默认使用的是 Grafana

相信有调优经验的读者很快就能发现,这里存在一个很明显的性能瓶颈,即每次请求都需要经过中心节点 Mixer 才能进行下去。这就意味着,整体链路的请求被放大了 2 倍,原来只需 1 次的通信请求,变成了 3 次。而且针对 Mixer 的请求存在流量汇聚的情况,例如不管请求从何处来、去向何处,都需要请求 Mixer。

笔者在了解 Istio 之初也非常不理解 Istio 的这种设计,无论怎么考虑,这种设计都不适合大规模高并发的服务架构,每次对 Mixer 的请求都是没有必要的资源开销。要解决这个问题,有两种方式:一种是把 Mixer 的部分请求处理逻辑放置在数据平面的网关 Envoy 上;另一种方式则是将 Mixer 的数据二级缓存到 Envoy 上。

第一种请求逻辑下沉方案,即将 Mixer 的部分逻辑,例如限流、鉴权等链路基础逻辑放置到 Sidecar(Envoy)中,这些逻辑必须是与链路密不可分的;而其他如分布式日志、链路追踪等插拔的功能则还是放置在 Mixer 中。由于实现链路基础逻辑是非常高频的功能,这样已经能够大幅度缓解请求压力的问题了。

第二种缓存方案,即在 Sidecar 中放置缓存,以让绝大多数的检查规则都通过缓存走掉,而不是都请求中心的 Mixer,否则,不但流量压力非常大,而且整体链路的通信效率都会被拖累;而对于请求汇报,Sidecar 也会做一次缓存,批量上报,以避免频繁的请求。

官方在发现这个性能问题后,采用的也是第二种解决方案,如图2.9所示。为什么采用后一种而不是将功能放置在 Sidecar 上?经过仔细推敲后,笔者看来主要是从容灾能力与功能维护性两个层面上来考虑的。因为二级缓存在一定程度上就是 Mixer 的一个副本,就算 Mixer 采用心全面宕机,大部分请求也会通过走本地缓存而通过;另一方面,由于 Mixer 是中心维护,那么功能升级就变得非常简单,相比于第一种方案将功能分布式地放置在 Envoy,只需要升级中心的服务,本地网关就会在缓存失效后自动更新,整个升级显得更加平滑。第一种方案显然具备更高的性能,但是从维护工作上来讲,就不那么轻松了。

图2.9 “Mixer 解决请求集中问题

除此之外,Mixer 提供丰富的接口,为众多组件提供了强大的扩展支持,让其以插件的形式运作于 Istio 平台之上——如链路跟踪 Zipkin、分布式日志 Fluentd、监控报警 Promethus、性能遥测 StatsD 等

可以说,Mixer 就是整体大系统的链路数据及分析中心。

2.3.3 稳定性与容灾能力

作为全局的策略及统计中心,Mixer 的稳定性显然非常重要,一旦出现问题,请求策略均得不到有效的执行,影响面相当广。为此,Istio 的工程师们做了如下的努力。

无状态 :Mixer 本身是完全无状态的,其自身不管理、不存储任何数据。

99.999%可用性 :Mixer 通过架构上的优化与努力(例如使用多机存储、全量同步方案),确保实施可用高达 99.999% 的稳定系统。

缓存与缓冲 :Sidecar 会将 Mixer 的缓存策略做一次缓存(Caching),再对需要汇报的数据做一次缓冲(Buffering),以最大限度地减少对 Mixer 的直接依赖。

在第二点的架构上,Mixer 与 Sidecar 面临的情况并不同。Sidecar 由于是部署在服务资源中的,因此对内存及其他资源的占用上都有相当严格的要求,但 Mixer 则不同,它是独立占用资源的,因此可以利用分布式策略来横向以集群的形式扩展。笔者将在第4章从代码级别为大家深入分析 Mixer 在架构上的容灾考虑。

2.3.4 请求属性(Attribute)

请求属性是控制平面的数据元,每个 Sidecar 在处理数据流动的时候均会向 Mixer提供一种叫“请求属性(Attribute)”的键值,它的作用是描述请求体或其对应的环境情况,以让控制平面掌握请求的每项指标。具体来说,请求属性其实就是简单的 key-value对。以下是一些例子:

例如链路跟踪服务,就需要在整个请求栈中携带一个跟踪ID,才能对每次调用进行跟踪并最终汇总,来向运维或者开发人员展示详细调用路径,让大家轻松掌握一次用户请求在相关系统中的跳转情况。请求属性实质上就是为整个链路加上了类似消息头的功能,让元数据能够在其中穿梭,将流量与服务之间的关系打通。总之,基于请求属性,很多链路管理与策略相关的功能才得以实现。

按照请求属性的思路,Mixer 实际上就是一个处理请求属性的状态机(如图2.10所示),运维人员通过模板(Template)对每个属性做出相应的规则配置,然后请求在执行前后均会向Mixer 汇报。Mixer会依据之前的配置对属性进行处理,再将它们移交给后端的扩展逻辑——这些逻辑是由各类插件来支持的,官方或非官方的。

图2.10 'Mixer与Attributes组成请求处理状态机”

需要注意的是,Istio 里的请求属性数量及种类都是固定的,主要受 Sidecar 及采集体系影响。当然这个数量也不是完全不能扩展,只是没那么简单,而且对于一般情况来说,默认的请求属性已经够用了。

完整的列表可以参看第7章7.3节。

2.3.5 操作配置(Operator Config)

操作配置是控制平面的数据配置概念,是 Mixer 的规则定义,包含三方面子配置:数据实例(Instance)、处理器(Handler)以及规则(Rule)配置。

○数据实例(Instance)配置用于告诉 Mixer 需要根据请求属性生成什么样的数据实例——因为每次请求携带的属性不同,生成的消息体内容不同,所以称为实例。

○处理器(Handler)是实质处理数据实例的逻辑体,这其中有很多三方扩展,例如日志收集、监控数据分析、链路跟踪等。

○规则(Rule)配置则是连接以上两个配置的连接配置。

例如,一个典型的数据实例配置如下:

从上可以看出,数据实例配置的核心便是,规定 Mixer 从请求属性中采集什么数据以及在一些条件下应该采取什么样的行为,即如何来生成一个数据实例。针对上述数据实例配置的一个处理器与规则的配置可以如下:

在这种设计下,工程师可以将一个模板生成的数据源连接到不同的处理器,在需求变化时只需要更换部分配置即可,非常灵活,这是 Istio 设计巧妙体现之一。

这样就知道了,对于 Mixer 来说,三个基础的配置是数据实例(Instance)、规则(Rule)与处理器(Handler)。这三个配置将请求属性与后端的扩展插件结合起来,组成请求策略执行的数据链路。 MR/sQBIhGKwLoTxsrhwPVX8F6HdBHgLWdU58xJd3Bx3qu8ZYGMiWTFaUP3YEvuH4

点击中间区域
呼出菜单
上一章
目录
下一章
×