Istio架构及其组件概述
Istio 架构总体来说分为控制面和数据面两部分。
控制面是 Istio 的核心,管理 Istio 的所有功能,主要包括Pilot、Mixer、Citadel等服务组件;
数据面由伴随每个应用程序部署的代理程序Envoy组成,执行针对应用程序的治理逻辑。常被称为“Sidecar”。Sidecar 一般和业务容器绑定在一起(在Kubernets中自动注入方式到业务pod中),来劫持业务应用容器的流量,并接受控制面组件的控制,同时会向控制面输出日志、跟踪及监控数据。
Istio 的主要组件及其相互关系大致如图所示(摘自《云原生服务网格Istio》)。
结合上图我们来理解Istio的各组件的功能及相互之间的协作方式。
1. 自动注入:在创建应用程序时自动注入 Sidecar代理Envoy程序。在 Kubernetes中创建 Pod时,Kube-apiserver调用控制面组件的 Sidecar-Injector服务,自动修改应用程序的描述信息并注入Sidecar。在 真正创建Pod时,在创建业务容器的Pod中同时创建Sidecar容器。
2. 流量拦截:在 Pod 初始化时设置 iptables 规则,基于配置的iptables规则拦截业务容器的Inbound流量和Outbound流量到Sidecar上。而应用程序感知不到Sidecar的存在,还以原本的方式 进行互相访问。上图中,流出frontend服务的流量会被 frontend服务侧的 Envoy拦截,而当流量到达forecast容器时,Inbound流量被forecast 服务侧的Envoy拦截。
3. 服务发现:服务发起方的 Envoy 调用控制面组件 Pilot 的服务发现接口获取目标服务的实例列表。上图中,frontend 服务侧的 Envoy 通过 Pilot 的服务发现接口得到forecast服务各个实例的地址。
4. 负载均衡:服务发起方的Envoy根据配置的负载均衡策略选择服务实例,并连接对应的实例地址。上图中,数据面的各个Envoy从Pilot中获取forecast服务的负载均衡配置,并执行负载均衡动作。
5. 流量治理:Envoy 从 Pilot 中获取配置的流量规则,在拦截到 Inbound 流量和Outbound 流量时执行治理逻辑。上图中, frontend 服务侧的 Envoy 从 Pilot 中获取流量治理规则,并根据该流量治理规则将不同特征的流量分发到forecast服务的v1或v2版本。
6. 访问安全:在服务间访问时通过双方的Envoy进行双向认证和通道加密,并基于服务的身份进行授权管理。上图中,Pilot下发安全相关配置,在frontend服务和forecast服务的Envoy上自动加载证书和密钥来实现双向认证,其中的证书和密钥由另一个管理面组件 Citadel维护。
7. 服务监测:在服务间通信时,通信双方的Envoy都会连接管理面组件Mixer上报访问数据,并通过Mixer将数据转发给对应的监控后端。上图中,frontend服务对forecast服务的访问监控指标、日志和调用链都可以通过这种方式收集到对应的监控后端。
8. 策略执行:在进行服务访问时,通过Mixer连接后端服务来控制服务间的访问,判断对访问是放行还是拒绝。上图中,Mixer 后端可以对接一个限流服务对从frontend服务到forecast服务的访问进行速率控制等操作。
9. 外部访问:在网格的入口处有一个Envoy扮演入口网关的角 色。上图中,外部服务通过Gateway访问入口服务 frontend,对 frontend服务的负载均衡和一些流量治理策略都在这个Gateway上执行。
Istio各组件详解
Istio服务组件有不少,从上面的流程中也基本能看出每个组件如何协作的,下面具体讲解每个组件的具体用途和功能。
$ kubectl get svc -n istio-system |grep istio |awk '{print $1}' istio-citadel istio-egressgateway istio-galley istio-ingressgateway istio-pilot istio-policy istio-sidecar-injector istio-telemetry istiod
Pilot
Pilot 是 Istio 的主要控制组件,下发指令控制客户端。在整个系统中,Pilot 完成以下任务:
• 从 Kubernetes 或者其他平台的注册中心获取服务信息,完成服务发现过程。
• 读取 Istio 的各项控制配置,在进行转换之后,将其发给数据面进行实施。
Pilot 将配置内容下发给数据面的 Envoy,Envoy 根据 Pilot 指令,将路由、服务、监听、集群等定义信息转换为本地配置,完成控制行为的落地。
Telemetry
Telemetry是专门用于收集监测数据的Mixer服务组件。Istio控制面部署了两个Mixer组件:istio- telemetry和istio-policy,分别处理监测数据的收集和策略的执行,两个组件的 Pod 镜像都是 mixer。
从调用时机上来说,Pilot管理的是配置数据,在配置改变时和数据面交互即可,对于Mixer来说,在服务间交互时Envoy都会对Mixer进行一次调用,因此这是一种实时管理。
如图所示,当网格中的两个服务间有调用发生时,服务的代理 Envoy就会上报监测数据给 istio-telemetry 服务组件,istio-telemetry 则根据配置将生成访问的 Metric等数据分发给后端的监测服务,如Prometheus等。

Policy
Policy是另外一个Mixer服务,和Telemetry基本上是完全相同的机制和流程。如图所示,数据面在转发服务的请求前调用 istio-policy的Check接口检查是否允许访问,把结果返回给Envoy。可以对接如配额、授权、黑白名单等不同的控制后端,对服务间的访问进行可扩展的控制。

Citadel
Citadel是 Istio的核心安全组件,提供了自动生 成、分发、轮换与撤销密钥和证书功能。Citadel一直监听 Kube- apiserver,以 Secret的形式为每个服务都生成证书密钥,并在Pod创建时挂载到Pod上,代理容器使用这些文件来做服务身份认证,进而代 理两端服务实现双向TLS认证、通道加密、访问授权等安全功能。如图 所示,frontend 服 务对 forecast 服务的访问用到了HTTP方式,通过配置即可对服务增加认证功能,双方的Envoy会建立双向认证的TLS通道,从而在服务间启用双向认证的HTTPS。

Sidecar-injector
Sidecar-injector是负责自动注入的组件,只要开启了自动注 入,在Pod创建时就会自动调用istio-sidecar-injector向Pod中注入Sidecar 容器。
在 Kubernetes环境下,根据自动注入配置,Kube-apiserver在拦截到 Pod创建的请求时,会调用自动注入服务 istio-sidecar-injector 生成 Sidecar 容器的描述并将其插入原 Pod的定义中,这样,在创建的 Pod 内除了包括业务容器,还包括 Sidecar容器,这个注入过程对用户透明。
Proxy
Proxy的运行容器时istio-proxy,容器中除了有Envoy,还有一个pilot-agent的守护进程。
Envoy是用C++开发的非常有影响力的轻量级高性能开源服务代理。作为服务网格的数据面,Envoy提供了动态服务发现、负载均 衡、TLS、HTTP/2 及 gRPC代理、熔断器、健康检查、流量拆分、灰度发布、故障注入等功能,本篇描述的大部分治理能力最终都落实到 Envoy的实现上。
在Istio中,规则的描述对象都是类似forecast服务的被访问者,但是真正的规则执行位置对于不同类型的动作可能不同,可能在被访问服务的 Sidecar 拦截到 Inbound 流量时执行,也可能在访问者的Sidecar 拦截到Outbound流量时执行,一般后者居多。当给forecast服务定义流量规则时,所有访问forecast服务的Sidecar都收到规则,并且执行相同的治理逻辑,从而对目标服务执行一致的治理。下表列出了常用的服务访问治理规则和其执行位置。
Ingressgateway
Ingressgateway 就是入口处的 Gateway,从网格外访问网格内的服务就是通过这个Gateway进行的。istio-ingressgateway是一个Loadbalancer类型的Service,不同于其他服务组件只有一两个端 口,istio-ingressgateway 开放了一组端口,这些就是网格内服务的外部访问端口。如下图所示,网格入口网关istio-ingressgateway的负载和网格内的Sidecar是同样的执行流程,也和网格内的其他 Sidecar一样从 Pilot处接收流量规则并执行。

其他组件
除了以“istio”为前缀的Istio自有组件,在集群中一般还安装Jaeger-agent、Jaeger-collector、Jaeger-query、Kiali、Prometheus、Grafana、 Tracing、Zipkin等组件,这些组件提供了Istio的调用链、监控等功能,可以选择安装来完成完整的服务监控管理功能。