图2-1展示了Istio的工作机制和架构,分为控制面和数据面两部分。可以看到,控制面主要包括Pilot、Mixer、Citadel等服务组件;数据面由伴随每个应用程序部署的代理程序Envoy组成,执行针对应用程序的治理逻辑。为了避免静态、刻板地描述组件,在介绍组件的功能前,我们先通过一个动态场景来了解图2-1中对象的工作机制,即观察frontend服务对 forecast 服务进行一次访问时,在 Istio 内部都发生了什么,以及 Istio 的各个组件是怎样参与其中的,分别做了哪些事情。
图2-1上带圆圈的数字代表在数据面上执行的若干重要动作。虽然从时序上来讲,控制面的配置在前,数据面执行在后,但为了便于理解,在下面介绍这些动作时以数据面上的数据流为入口,介绍数据面的功能,然后讲解涉及的控制面如何提供对应的支持,进而理解控制面上组件的对应功能。
(1)自动注入:指在创建应用程序时自动注入 Sidecar代理。在 Kubernetes场景下创建 Pod时,Kube-apiserver调用管理面组件的 Sidecar-Injector服务,自动修改应用程序的描述信息并注入Sidecar。在真正创建Pod时,在创建业务容器的同时在Pod中创建Sidecar容器。
图2-1 Istio的工作机制和架构
(2)流量拦截:在 Pod 初始化时设置 iptables 规则,当有流量到来时,基于配置的iptables规则拦截业务容器的Inbound流量和Outbound流量到Sidecar上。应用程序感知不到Sidecar的存在,还以原本的方式进行互相访问。在图2-1中,流出frontend服务的流量会被 frontend服务侧的 Envoy拦截,而当流量到达forecast容器时,Inbound流量被forecast服务侧的Envoy拦截。
(3)服务发现:服务发起方的 Envoy 调用管理面组件 Pilot 的服务发现接口获取目标服务的实例列表。在图 2-1 中,frontend 服务侧的 Envoy 通过 Pilot 的服务发现接口得到forecast服务各个实例的地址,为访问做准备。
(4)负载均衡:服务发起方的Envoy根据配置的负载均衡策略选择服务实例,并连接对应的实例地址。在图2-1中,数据面的各个Envoy从Pilot中获取forecast服务的负载均衡配置,并执行负载均衡动作。
(5)流量治理:Envoy 从 Pilot 中获取配置的流量规则,在拦截到 Inbound 流量和Outbound 流量时执行治理逻辑。在图 2-1 中,frontend 服务侧的 Envoy 从 Pilot 中获取流量治理规则,并根据该流量治理规则将不同特征的流量分发到forecast服务的v1或v2版本。当然,这只是Istio流量治理的一个场景,更丰富的流量治理能力参照第3章。
(6)访问安全:在服务间访问时通过双方的Envoy进行双向认证和通道加密,并基于服务的身份进行授权管理。在图2-1中,Pilot下发安全相关配置,在frontend服务和forecast服务的Envoy上自动加载证书和密钥来实现双向认证,其中的证书和密钥由另一个管理面组件Citadel维护。
(7)服务遥测:在服务间通信时,通信双方的Envoy都会连接管理面组件Mixer上报访问数据,并通过Mixer将数据转发给对应的监控后端。在图2-1中,frontend服务对forecast服务的访问监控指标、日志和调用链都可以通过这种方式收集到对应的监控后端。
(8)策略执行:在进行服务访问时,通过Mixer连接后端服务来控制服务间的访问,判断对访问是放行还是拒绝。在图2-1中,Mixer后端可以对接一个限流服务对从frontend服务到forecast服务的访问进行速率控制。
(9)外部访问:在网格的入口处有一个Envoy扮演入口网关的角色。在图2-1中,外部服务通过Gateway访问入口服务 frontend,对 frontend服务的负载均衡和一些流量治理策略都在这个Gateway上执行。
这里总结在以上过程中涉及的动作和动作主体,可以将其中的每个过程都抽象成一句话:服务调用双方的Envoy代理拦截流量,并根据管理面的相关配置执行相应的治理动作,这也是Istio的数据面和控制面的配合方式。