得益于良好的模块化设计,Istio的各个组件设计清晰,分工明确,几个大的组件之间甚至可以独立工作,所以接下来我们将逐一深入分析Istio的各个组件。本文首先详细分析一下我们最常用的流量管理功能所对应的模块——Pilot和Envoy。
Istio基本架构图如下图所示,网格东西向及南北向的流量控制,核心思路是由Pilot维护管理策略,并通过标准接口下发到Envoy Proxy中,由Envoy最终实现流量的转发。
Istio服务网格逻辑上分为数据平面和控制平面:
其中与流量管理相关的主要包括控制层面的Pilot以及数据层面的Envoy Proxy。
Pilot的基本架构如下图所示。
根据上图,Pilot主要实现下述功能:
1.统一服务模型
统一服务模型主要功能是从底层平台获取服务相关信息以及通过RuleAPI定义的服务间流量规则,以kubernetes为例,统一服务模型从平台上获取注册在Pod、Service、Node以及流量规则信息,获取到各种信息后转变成数据平面上可理解的数据格式存储在Abstract Model中。
2. 标准数据平面API
获取到各种服务信息以及流量规则之后,会通过该API下发到数据面的Sidecar中。
3. 业务DSL语言(Domain Specific Language)
SL语言提供了面向业务的高层抽象,可以被运维人员理解和使用。运维人员使用该DSL定义流量规则并下发到Pilot,这些规则被Pilot翻译成数据面的配置,再通过标准API分发到Envoy实例,可以在运行期对微服务的流量进行控制和调整。
Pilot的规则DSL是采用K8S API Server中的Custom Resource (CRD)实现的,因此和其他资源类型如Service Pod Deployment的创建和使用方法类似,都可以用Kubectl进行创建。
通过运用不同的流量规则,可以对网格中微服务进行精细化的流量控制,如按版本分流,断路器,故障注入,灰度发布等。
与Pilot相关的服务主要有两个:
(1)Discovery Service
对应的docker为gcr.io/istio-release/pilot,进程为pilot-discovery,该组件的功能包括:
从Service Provider中获取服务信息,除了这里主要介绍的Kubernetes之外,Istio还支持Consul作为Service Provider。
从Kubernetes API Server中获取流量规则(Kubernetes CRD Resource)。
将服务信息和流量规则转化为数据面可以理解的格式,通过标准的数据面API下发到网格中的各个Sidecar中。
(2)Kubernetes API Server
提供Pilot相关的CRD Resource的增、删、改、查。和Pilot相关的CRD有以下几种:
Virtualservice:用于定义路由规则,如根据来源或 Header 制定规则,或在不同服务版本之间分拆流量。
DestinationRule:定义目的服务的配置策略以及可路由子集。策略包括断路器、负载均衡以及 TLS 等。
ServiceEntry:用 ServiceEntry 可以向Istio中加入附加的服务条目,以使网格内可以向Istio 服务网格之外的服务发出请求。
Gateway:为网格配置网关,以允许一个服务可以被网格外部访问。
EnvoyFilter:可以为Envoy配置过滤器。由于Envoy已经支持Lua过滤器,因此可以通过EnvoyFilter启用Lua过滤器,动态改变Envoy的过滤链行为。我之前一直在考虑如何才能动态扩展Envoy的能力,EnvoyFilter提供了很灵活的扩展性。
Istio通过K8s的Admission Webhook机制实现了sidecar的自动注入,Istio集群中的每个微服务会被加入Envoy相关的容器。下面是官方示例productpage微服务的Pod内容,可见除productpage之外,Istio还在该Pod中注入了两个容器gcr.io/istio-release/proxy_init和gcr.io/istio-release/proxyv2。
1.初始化容器器proxy_init
Productpage的Pod中有一个InitContainer proxy_init,InitContrainer是K8S提供的机制,用于在Pod中执行一些初始化任务,在Initialcontainer执行完毕并退出后,才会启动Pod中的其它container。
在proxy_init中执行iptables.sh脚本,该脚本的作用是通过配置iptable来劫持Pod中的流量。
2.运行时Sidecar容器器proxyv2
Envoy的大部分配置都是dynamic resource,包括网格中服务相关的service cluster, listener, route规则等。这些dynamic resource是通过xDS接口从Istio控制面中动态获取的。但Envoy如何知道xDS server的地址呢?这是在Envoy初始化配置文件中以static resource的方式配置的。
在Proxyv2容器运行时,有两个进程pilot-agent和envoy。
1)pilot-agent进程
该进程根据K8S API Server中的配置信息生成Envoy的配置文件,并负责启动Envoy进程。注意Envoy的大部分配置信息都是通过xDS接口从Pilot中动态获取的,因此Agent生成的只是用于初始化Envoy的少量静态配置。
2)envoy进程
Envoy由Pilot-agent进程启动,启动后,Envoy读取Pilot-agent为它生成的配置文件,然后根据该文件的配置获取到Pilot的地址,通过数据面标准API的xDS接口从pilot拉取动态配置信息,包括路路由(route),监听器器(listener),服务集群(cluster)和服务端点(endpoint)。Envoy初始化完成后,就根据这些配置信息对微服务间的通信进行寻址和路由。
数据面组件中涉及的概念比较多,这里列举如下。
Envoy的配置包含两部分,初始化配置和动态更新的配置。
1.Envoy初始配置
Pilot-agent进程根据启动参数和K8S API Server中的配置信息生成Envoy的初始配置文件,并负责启动Envoy进程。从ps命令输出可以看到Pilot-agent在启动Envoy进程时传入了pilot地址和zipkin地址,并为Envoy生成了一个初始化配置文件envoy-rev0.json。
2.Envoy动态更新配置
通过管理接口获取完整配置。从Envoy初始化配置文件中,我们可以大致看到Istio通过Envoy来实现服务发现和流量管理的基本原理。即控制面将xDS server信息通过static resource的方式配置到Envoy的初始化配置文件中,Envoy启动后通过xDS server获取到dynamic resource,包括网格中的service信息及路由规则。
详细流程如下:
下图表述了服务与服务之间通过sidecar进行交互的流程。
基本流程分析如下:
参考链接
https://zhaohuabing.com/post/2018-09-25-istio-traffic-management-impl-intro/
https://istio.io/zh/docs/concepts/what-is-istio/
https://www.cnblogs.com/xishuai/p/microservices-and-service-mesh.html
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。