随着微服务规模和复杂性的增长,服务网格越来越难以理解和管理。其中Istio提供了服务发现、负载均衡、故障恢复、指标收集和监控等完整的服务网格解决方案,降低了功能模块部署的复杂性,减轻了开发团队的压力。本文对Istio网格进行了初步的介绍,希望能激发大家对Istio网格的兴趣。服务网格Istio初探-Pilot组件_微服务

 

1

Istio是什么

服务网格这个术语通常用于描述构成这些应用程序的微服务网络以及应用之间的交互,服务网格是用于处理服务间通信的专用基础设施层。它负责通过包含现代云原生应用程序的复杂服务拓扑来可靠地传递请求。实际上,服务网格通常通过一组轻量级网络代理来实现,这些代理与应用程序代码一起部署,而不需要感知应用程序本身。

随着微服务规模和复杂性的增长,服务网格越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、指标收集和监控以及通常更加复杂的运维需求,例如 A/B 测试、金丝雀发布、限流、访问控制和端到端认证等。

Istio提供了一个完整的解决方案,通过为整个服务网格提供行为洞察和操作控制来满足微服务应用程序的多样化需求。在较高的层次上,Istio有助于降低这些部署的复杂性,并减轻开发团队的压力。它是一个完全开源的服务网格,可以透明地分层到现有的分布式应用程序上。它也是一个平台,包括集成到任何日志记录平台、遥测或策略系统的API。Istio的多样化功能集使您能够成功高效地运行分布式微服务架构,并提供保护、连接和监控微服务的统一方法。

通过两幅图来对比一下Istio在服务网格中的作用,未使用Istio的微服务之间的调用方式如下:

服务网格Istio初探-Pilot组件_微服务_02

使用Istio管理的微服务之间的调用方式:

服务网格Istio初探-Pilot组件_微服务_03

使用 Istio 的流量管理模型,本质上是将流量与基础设施扩容解耦,让运维人员可以通过 Pilot 指定流量遵循什么规则,而不是指定哪些 pod/VM 应该接收流量——Pilot 和Envoy代理会帮我们搞定。

 

2

Istio架构

Istio 服务网格逻辑上分为数据平面和控制平面。

数据平面

数据平面由一组以sidecar方式部署的智能代理(Envoy)组成。这些代理可以调节和控制微服务及Mixer之间所有的网络通信。

数据平面的特点:

  • 通常是按照无状态目标设计的,但实际上为了提高流量转发性能,需要缓存一些数据,因此无状态也是有争议的。

  • 直接处理入站和出站数据包,转发、路由、健康检查、负载均衡、认证、鉴权、产生监控数据等。

  • 对应用来说透明,即可以做到无感知部署。

控制平面

控制平面负责管理和配置代理来路由流量。此外控制平面配置Mixer以实施策略和收集遥测数据。

控制平面的特点:

  • 不直接解析数据包。

  • 与数据平面中的代理通信,下发策略和配置。

  • 负责网络行为的可视化。

  • 通常提供API或者命令行工具可用于配置版本化管理,便于持续集成和部署。

Istio的架构如图:

服务网格Istio初探-Pilot组件_微服务_04

我们今天重点关注的是Pilot组件的基本实现。

 

3

Pilot组件

Pilot为Envoy sidecar提供服务发现功能,为智能路由(例如 A/B 测试、金丝雀部署等)和弹性(超时、重试、熔断器等)提供流量管理功能。它将控制流量行为的高级路由规则转换为特定于Envoy的配置,并在运行时将它们传播到sidecar。

Pilot组件架构如下图:

服务网格Istio初探-Pilot组件_微服务_05

Pilot的架构,最下面一层是Envoy的API,提供Discovery Service的API,这个API的规则由Envoy约定,Pilot实现Envoy API Server,Envoy和Pilot之间通过gRPC实现双向数据同步。Pilot最上面一层称为Platform Adapter,这一层不是Kubernetes调用Pilot,而是Pilot通过调用Kubernetes来发现服务之间的关系,Pilot通过在Kubernetes里面注册一个Controller来监听事件,从而获取Service和Kubernetes的Endpoint以及Pod的关系。Istio通过Kubernets CRD来定义自己的领域模型,使大家可以无缝的从Kubernets的资源定义过度到Pilot的资源定义。

Pilot组件主要包含两部分,pilot-agent和pilot-discovery,我们基于Istio官方的bookinfo应用,探索一下pilot组件。bookinfo应用的架构如图所示:

服务网格Istio初探-Pilot组件_微服务_06

pilot-agent

 

开启集群的Sidecar自动注入,以productpage服务为例,观察一下Istio对我们的应用容器到底做了了什么。

Istio对productpage进行定制化之一:嵌入proxy_init作为InitContainer, InitContainer用于设置iptables规则,让出入流量都转由Sidecar进行处理, Istio-init只用来设置iptables规则。

服务网格Istio初探-Pilot组件_微服务_07服务网格Istio初探-Pilot组件_微服务_08

Istio对productpage进行定制化之二:嵌入proxy容器作为Sidecar,基于Envoy实现。

服务网格Istio初探-Pilot组件_微服务_09

istio-proxy容器的运行的进程包括pilot-agent和envoy:

服务网格Istio初探-Pilot组件_微服务_10

pilot-agent的启动流程:

服务网格Istio初探-Pilot组件_微服务_11

总结一下pilot-agent的作用:

  • 生成 Envoy的启动配置。

  • 启动envoy。

  • 监控并管理envoy的运行状况,比如envoy出错时pilot-agent负责重启envoy,或者envoy配置变更后reload envoy。

pilot-discovery

 

pilot-discovery负责从k8s apiserver list/watch service、endpoint、pod、node等获取资源信息,监听istio控制平面配置信息(如VirtualService、DestinationRule等), 并将其翻译为Envoy可以直接理解的配置格式。

pilot的架构下图所示:

服务网格Istio初探-Pilot组件_微服务_12

pilot-discovery的启动流程:

服务网格Istio初探-Pilot组件_微服务_13

bootstrap.NerServer:

服务网格Istio初探-Pilot组件_微服务_14

initConfigController:

服务网格Istio初探-Pilot组件_微服务_15

initServiceControllers:

服务网格Istio初探-Pilot组件_微服务_16

initDiscoveryService:

服务网格Istio初探-Pilot组件_微服务_17

在initDiscoveryService阶段,注册了Service(k8s services)和ServiceInstance(k8s endpoints)的两个eventHandler,在k8s资源发生变化时会触发更新envoy配置的操作,这里的实现留待后续详细分析。

通过以上的简单分析,我们对pilot组件有了一个初步认识,后续我们会进一步深入代码探讨具体的执行流程,并发现在大规模部署的生产环境中可能存在性能瓶颈。

 

4

TODO

  • pilot如何转换k8s的数据模型和envoy的数据模型

  • pilot的gRPC推送时机

  • ...

刚开始学习Istio相关组件,理解难免有偏颇,非常欢迎大家指正。

 

相关文章

  • Istio学习之Pilot-agent

  • Istio学习之Pilot-discovery

  • Pilot Discovery源码

  • 深入解读Service Mesh背后的技术细节

  • VirtualServices in Practice

  • 理解 K8S 的设计精髓之 list-watch

  • Istio源码系列3:pilot-discovery 源码分析

  • kubernetes CRD下篇--编写自定义控制器

服务网格Istio初探-Pilot组件_微服务_18