Istio之架构

Posted by 淦 Blog on July 19, 2023

架构

Istio在架构上分为控制面和数据面两部分,控制面只有一个单体应用Istiod。在Istio 1.6中,上游为了简化控制面的部署和运维,将原来分离的Istio组件Pilot、Citadel、Mixer、Galley、Sidercar-Injector等组件合并为单体应用(Istiod),并且为了提升性能,又将Mixer彻底移除。数据面主要由伴随每个应用程序部署的代理Envoy组成,Envoy根据控制面的配置执行流量管理操作。

服务调用双方的服务网格数据面代理Envoy拦截流量,并根据Istiod的相关配置执行相应的治理动作,这是Istio的数据面和控制面的基本配合方式。

工作机制

①自动注入:在Kubernetes场景中创建Pod时,Kube-apiserver调用Istio的Sidecar-injector服务,自动修改应用程序的描述信息并注入Sidecar代理和Init容器。在真正运行Pod时,首先运行Init容器,设置流量拦截规则,然后同时运行应用容器和Sidecar容器。在用户无感知的情况下,Sidecar容器中的Envoy程序伴随着应用程序运行,对进出应用程序的流量进行透明的管理。

②流量拦截:Istio默认通过注入Init容器进行Iptables规则的设置,拦截进入容器的Inbound流量和从应用程序发出的Outbound流量。由于Init容器需要NET_ADMIN和NET_RAW权限执行网络设置,所以Istio还提供了Istio CNI插件,取代Init容器进行流量拦截规则的设置。Istio CNI插件识别用户的应用程序Pod和需要流量重定向的Sidecar,并在Kubernetes Pod生命周期的网络设置阶段进行设置,从而消除用户在启用Istio的集群中对Pod额外的权限要求。当有流量到来时,Sidecar基于配置的iptables规则拦截业务容器的Inbound流量和Outbound流量。应用程序完全感知不到Sidecar的存在,仍然以原本的方式进行互相访问。在图中,frontend发送的流量会被frontend侧的Sidecar拦截,而当流量到达forecast时,Inbound流量被forecast侧的Sidecar拦截。

③服务发现:服务发起方的Envoy调用Istiod的服务发现接口获取目标服务的实例列表。在图中,frontend侧的Envoy通过Pilot的服务发现接口得到forecast各个实例的地址,为负载均衡做准备。

④负载均衡:服务发起方的Envoy根据配置的负载均衡策略选择服务实例,并将请求分发到对应的目标服务实例上。在图中,frontend侧的Envoy从Istiod中获取forecast的负载均衡配置并执行负载均衡操作。

⑤流量治理:Envoy从Istiod中获取配置的流量治理规则,在拦截到Inbound流量和Outbound流量时执行治理逻辑。在图中,frontend侧的Envoy从Istiod中获取流量治理规则,并根据灰度策略将不同特征的流量分发到forecast的v1或v2版本。

⑥访问安全:在服务问访问时,Envoy可以进行双向认证和通道加密,并基于授权策略的配置对请求进行鉴权。在图中默认启用服务间的双向认证,在frontend和forecast侧的Envoy上自动加载证书和密钥来实现双向认证。其中的证书和密钥的管理由Citadel和Istio-Agent协作完成。

⑦服务监控:在服务问通信时,通信双方的Envoy根据请求的信息进行监控指标的统计、访问日志的收集和分布式调用链的埋点等。Istio通过标准的可观测性接口对接各种不同的可观测性后端,接收相关的可观测性数据。在图中,frontend对forecast的访问监控指标、访问日志和调用链都可以通过这种方式收集到对应的监控后端。

⑧策略执行:Envoy原生支持访问限流。在图中,可以部署限流服务,通过限流规则控制frontend到forecast的访问速率。截至Istio 1.16,Istio暂时还没有标准的限流API帮助用户配置限流策略,在限流策略的配置方面,还只能通过EnvoyFilter开放Envoy的限流能力。

⑨访问入口:在服务网格的入口处有个Envoy扮演入口网关Ingress-gateway的角色。在图中,外部服务通过网关访问入口服务frontend,对frontend的负载均衡和一些流量治理策略都在这个网关上执行。

⑩外部服务:出口网关Egress-gateway统一接收和管理服务网格访问外部的流量。在图中,forecast 通过出口网关访问外部服务,还可以对外部访问的流量进行管理。

主要组件

控制面

Pilot

Pilot是Istio的控制中枢。如果把数据面的Envoy也看作一种Agent,则Pilot类似传统C/S架构中的服务端Master,下发指令控制客户端完成业务功能。在Istio中,Pilot主要包含两部分工作:服务发现和配置管理。

Pilot直接从运行平台提取数据并将其构造和转换成Istio的服务模型,而且无须为了迁移到Istio进行额外的服务注册。这种抽象模型解耦了Pilot和底层平台,屏蔽了不同平台的服务差异,可支持Kubernetes、虚拟机等平台。另外,在非Kubernetes环境下,Pilot支持以MCP从其他服务端获取配置。MCP是一种基于xDS的协议,主要通过使用MCP抽象来规范配置处理,并且避免Istio维护各种各样的注册中心适配代码,以及Istio核心功能分裂。

除了服务发现,Pilot更重要的一个功能是构造维护和向数据面下发规则,包括VirtualService、DestinationRule、Gateway等流量规则,也包括RequestAuthentication、PeerAuthentication、AuthorizationPolicy等安全规则。Pilot负责将各种规则转换成Envoy可识别的格式,通过标准的xDS协议发送给Envoy,指导Envoy完成工作。在通信上,Envoy通过gRPC流式订阅Pilot的配置资源。即作为xDS服务器,Pilot内部启动了一个gRPC服务,用来承载数据面Sidecar的连接并处理xDS的订阅请求。

Pilot将VirtualService表达的路由规则分发到Envoy上,Envoy根据该路由规则进行流量转发。

Citadel

Citadel是Istio的核心安全组件,提供了自动生成、分发、轮换与撤销密钥和证书的功能。Citadel为工作负载提供了两种形式的证书:①默认双向TLS所使用的证书,无须用户指定,Citadel将根据工作负载的身份自动为其签发;②用户指定的证书,主要用在服务网格入口网关上,用户为入口网关指定权威机构颁发的证书。

控制面组件Citadel提供服务网格的证书管理功能,数据面服务代理基于证书和密钥提供透明的服务间安全访问功能。

Galley

Galley是服务网格控制面负责配置管理的组件。首先作为Webhook Server,在配置创建过程中验证配置信息的格式和内容的正确性,即作为Kubernetes的准入控制器,在Istio API对象创建阶段对其进行校验,拦截非法的配置。Galley还负责监控(Watch)API对象,包括ServiceEntry、WorkloadEntry、Gateway、VirtualService等,当资源对象发生变化时,通知Pilot根据最新的API对象生成xDS配置,并推送给相关的数据面Sidecar。目前API对象源支持Kubernetes、MCP、文件系统。

Sidecar-injector

Sidecar-injector是负责自动注入的组件。Istio只要开启了自动注入,在Pod创建时,Kubernetes就会自动调用Sidecar-injector向Pod中注入Sidecar容器。在Kubernetes环境下,根据自动注入配置模板,Kube-apiserver在拦截到Pod创建的请求时,会调用Sidecar-injector生成istio-init和istio-proxy容器,并将其插入原Pod的定义中,容器注入过程对用户完全透明。

数据面

Istio-proxy

在Istio-proxy容器中除了包括Envoy,还包括一个Pilot-agent的守护进程。Pilot-agent由原来独立的Pilot-agent及Node-agent合并而来,将Envoy的启动管理及SDS证书服务统一为单体,进一步简化了Istio在虚拟机及裸金属服务器上的安装及维护。

Envoy是用C++开发的非常有影响力的轻量级、高性能开源服务代理。作为服务网格的数据面,Envoy提供了动态服务发现、负载均衡、TLS、HTTP/2及gRPC代理、熔断器、健康检查、流量拆分、灰度发布、故障注入等功能。

Ingress-gateway

Ingress-gateway是部署在数据面接收服务网格入口流量的一个网关组件,从服务网格外部访问服务网格内部服务全部要通过这个入口网关。

Ingress-gateway开放了一组端口,作为服务网格内部服务被服务网格外部访问的端口。外部端口是客户端从服务网格外部访问的端口,内部端口是Gateway进程真正在侦听并处理流量的端口。

服务网格入口网关Ingress-gateway的负载和服务网格内部的Sidecar是同样的执行体,也和服务网格内部的其他Sidecar一样,从Pilot接收流量规则并执行。因为入口处的流量都通过这个网关服务,会有较大的并发并可能出现流量峰值,所以需要评估流量来规划网关资源规格和实例数。

Egress-gateway

为了处理服务网格访问外部服务的流量,在Istio数据面中规划了一个Egress-gateway组件。

一般通过配置将外部访问的出流量转发到这个对外网关上,再经由网关访向外部服务。可以在这个网关处对出流量进行统一的管理。比如服务网格内部的普通负载部署的节点都不具有连通外部网络的能力,只在Egress-gateway所在节点开放外部网络访问,可达到统一管控对外访问的目的。

其他组件

命令行工具Istioctl,可选的可观测性相关的Jaeger、Kiali、Prometheus、Grafana、ELK等组件。可观测性组件通过标准的接口收集和管理服务网格自动生成的调用链、访问指标、访问日志、拓扑等。