专栏
天翼云开发者社区

浅谈下一代微服务架构——Istio服务网格

2023-05-25 10:41:46 125阅读

一、背景

从服务架构的演绎过程来看,服务架构经历了从单体架构到SOA架构,并到微服务架构的演进,在在微服务架构中,我们需要关注服务间怎么通信,服务怎么查找,服务故障怎么处理等,在现有的微服务架构中,SpringCloud提供了比较成熟的微服务治理全家桶方案,阿里也形成了以Dubbo为基础的微服务技术体系,包括服务注册中心Nacos、隔离熔断Sentinel、分布式事务seata、分布式任务调度SchedulerX等。而SpringCloud/Dubbo框架提供的服务治理能力是代码侵入的,主要支持Java,其它语言像go/nodejs/python等需要定制开发对应的SDK才能享有完整的服务治理能力。

因此,需要把与应用业务逻辑无关的功能抽象到共同基础设施,来降低应用程序代码和底层平台的耦合度,使开发者更能专注于本身的业务逻辑,而无需耗费精力在基础代码的设计上。

1.1什么是服务网格

服务网格(Service Mesh)是一个专门处理服务通讯的基础设施层。它的职责是在由云原生应用组成服务的复杂拓扑结构下进行可靠的请求传送。服务网格的目的是将服务治理能力下沉到基础设施,让业务更加专注于业务逻辑。在实际部署时,Service Mesh 通常以轻量级的网络代理的方式跟应用的代码部署在一起,从而以应用无感知的方式实现服务治理。

服务网格从总体架构上可以分为一堆紧挨着各项服务的用户代理,和一组任务管理组件组成。

管理组件被称为控制层或控制平面(control plane),负责与控制平面中的代理通信,下发策略和配置。

代理在服务网格中被称为数据层或数据平面(data plane),直接处理入站和出站数据包,转发、路由、健康检查、负载均衡、认证、鉴权、产生监控数据等。

一个典型的服务网格部署网络结构图如下:

其中绿色方块为应用服务,蓝色方块为 Sidecar Proxy,应用服务之间通过 Sidecar Proxy 进行通信,整个服务通信形成图中的蓝色网络连线,图中所有蓝色部分就形成了 Service Mesh。

服务网格有如下几个特点:

  • 应用程序间通讯的中间层
  • 轻量级网络代理
  • 应用程序无感知
  • 解耦应用程序的重试/超时、监控、追踪和服务发现

1.2 服务网格选型

目前社区比较活跃的 Service Mesh 实现主要有2个:Linkerd2、Istio。

Istio和Linkerd的区别在于数据平面使用了两种不同的代理技术,Istio使用Envoy作为其代理。Envoy是C++编写的,最初是由Lyft构建,以便以非Kubernetes方式促进微服务的流量管理。许多公司已经将Envoy扩展为Kubernetes的ingress技术;Linkerd(v2)使用的是一种名为Linkerd-proxy的专用服务网格代理。这个代理是使用Rust编写的。

Istio是构建与Envoy之上的因此在流量管理方面它是占据优势的,Envoy已经包含了重要的IMHO功能,比如子集路由。用户仍然可以使用Linkerd实现金丝雀/蓝绿/a-b发布,但必须依靠单独的Kubernetes服务和能够分发流量的集群ingress技术,比如Gloo(gloo.solo.io)。Linkerd团队在最近一次社区会议上公开表示,计划在未来的版本中实现更加高级的L7流量管理功能。

Linkerd未能提供请求追踪。想要以非侵入方式查。。。。看请求追踪跨度必须等待Linkerd实现该功能。Istio利用了Envoy支持添加追踪headers的事实。

在性能方面,对于综合工作负载,Istio的Envoy代理使用比Linkerd多50%的CPU。

Istio比Linkerd2.3有多的特性。更多的特性意味着处理更复杂和边缘用例的能力增强。更多的特性通常意味着更多的配置,潜在的资源利用率和运营成本的增加。

二、Istio架构与概念

2.1 Istio基础架构

2.1.1 数据平面

Istio的数据平面主要包括Envoy代理的扩展版本。Envoy是一个开源边缘和服务代理,可帮助将网络问题与底层应用程序分离开来。应用程序仅向localhost发送消息或从localhost接收消息,而无需了解网络拓扑。

Envoy的核心是在OSI模型的L3和L4层运行的网络代理。它通过使用可插入网络过滤器链来执行连接处理。此外,Envoy支持用于基于HTTP的流量的附加L7层过滤器。而且,Envoy对HTTP/2和gRPC传输具有一流的支持。

Envoy在Istio上表现出色的另一个原因之一是它的可扩展性。Envoy提供了基于WebAssembly的可插拔扩展模型。这在定制策略执行和遥测生成中非常有用。此外,我们还可以使用基于Proxy-Wasm沙箱API的Istio扩展在Istio中扩展Envoy代理。

数据平面的特点:

  •     通常是按照无状态目标设计的,但实际上为了提高流量转发性能,需要缓存一些数据,因此无状态也是有争议的。
  •     直接处理入站和出站数据包,转发、路由、健康检查、负载均衡、认证、鉴权、产生监控数据等。
  •     对应用来说透明,即可以做到无感知部署。

从istio1.5 开始,简化了控制平面,将先前由 Pilot,Galley,Citadel 和 sidecar 注入器执行的功能统一为一个二进制文件istiod 。其提供服务发现,配置和证书管理功能。

2.1.2 控制平面

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

  •     不直接解析数据包。
  •     与数据平面中的代理通信,下发策略和配置。
  •     负责网络行为的可视化。
  •     通常提供 API 或者命令行工具可用于配置版本化管理,便于持续集成和部署

2.2 核心概念

  • Sidecar( 边 车): Sidecar 自定义资源描述了Sidecar代理的配置,该代理协调与其连接的工作负载实例的入站和出站通信。
  • 服务(Service):在服务注册表中的具有唯一名称的应用单位。服务由运行在pod、容器、虚拟机上的工作负载实例实现的多个网络端点组成。
  • 服务版本(Service Versions):也称为服务子集(Subsets),在持续部署场景中,灰度发布常用到的术语。
  • 源(Source):调用目标服务的下游客户端。
  • 主机(Host):客户端在连接服务时的地址
  • 访问模型(Access Model): 应用程序在不知道各个服务版本(子集)的情下仅对目标服务( 主机)进行寻址。 版本的实际选择由Sidecar代理确定,使应用程序代码能够脱离依赖服务的演变。
  • 虚拟服务(Virtual Service):一个虚拟服务定义了一系列针对指定服务的流量路由规则。每个路由规则都针对特定协议定义流量匹配规则。如果流量符合这些特征,就会根据规则发送到服务注册表中的目标服务(或者目标服务的子集或版本)。
  • 目标规则(Destination Rule):目标规则定义了在路由发生后应用于服务的流量的策略。这些规则指定负载均衡的配置,来自Sidecar代理的连接池大小以及异常检测设置,以便从负载均衡池中检测和驱逐不健康的主机。

Kubernetes、xDS、Istio 三者之间的资源抽象对比。

Kubernetes xDS Istio 服务网格
Endpoint Endpoint WorkloadEntry
Service Route VirtualService
kube-proxy Route DestinationRule
kube-proxy Listener EnvoyFilter
Ingress Listener Gateway
Service Cluster ServiceEntry

2.3 基本组件

2.3.1 控制平面

从istio1.5 开始,简化了控制平面,将先前由 Pilot,Galley,Citadel 和 sidecar 注入器执行的功能统一为一个二进制文件istiod 。其提供服务发现,配置和证书管理功能。

2.3.1.1 Pilot

Pilot类似传统C/S架构中的服务端Master,为 Envoy sidecar 提供服务发现功能,为智能路由(例如 A/B 测试、金丝雀部署等)和弹性(超时、重试、熔断器等)提供流量管理功能。它将控制流量行为的高级路由规则转换为特定于 Envoy 的配置,并在运行时将它们传播到 sidecar。和传统的微服务架构对比,Pilot 至少涵盖服务注册中心和 Config Server 等管理组件的功能。

Pilot 组件架构如下图:

Pilot 直接从运行平台提取数据并将其构造和转换成 Istio 的服务发现模型,因此Pilot只有服务发现功能,无须进行服务注册。这种抽象模型解耦了Pilot和底层平台的不同实现,可支持Kubernetes、Consul等平台。

除了服务发现,Pilot 更重要的一个功能是向数据面下发规则,包括 VirtualService、DestinationRule、Gateway、ServiceEntry 等流量治理规则,也包括认证授权等安全规则。Pilot 负责将各种规则转换成 Envoy 可识别的格式,通过标准的 xDS 协议发送给 Envoy,指导Envoy完成动作。在通信上,Envoy通过gRPC流式订阅Pilot的配置资源。

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。

pilot-agent

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

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

在proxy镜像中,pilot-agent负责的工作包括:

  1. 生成envoy的配置。
  2. 启动envoy。
  3. 监控并管理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 的架构下图所示:

pilot-discovery扮演服务注册中心、istio控制平面到Envoy之间的桥梁作用。pilot-discovery的主要功能包括:

  1. 监控服务注册中心(如Kubernetes)的服务注册情况。在Kubernetes环境下,会监控service、endpoint、pod、node等资源信息。
  2. 监控istio控制面信息变化,在Kubernetes环境下,会监控包括RouteRule、VirtualService、Gateway、EgressRule、ServiceEntry等以Kubernetes CRD形式存在的istio控制面配置信息。
  3. 将上述两类信息合并组合为Envoy可以理解的(即遵循Envoy data plane api的)配置信息,并将这些信息以gRPC协议提供给Envoy。

2.3.1.2 Citadel 组件

服务列表中的 istio-citadel是 Istio的核心安全组件,提供了自动生成、分发、轮换与撤销密钥和证书功能。Citadel一直监听Kube-apiserver,以 Secret的形式为每个服务都生成证书密钥,并在Pod创建时挂载到Pod上,代理容器使用这些文件来做服务身份认证,进而代理两端服务实现双向TLS认证、通道加密、访问授权等安全功能,这样用户就不用在代码里面维护证书密钥了。1.5版本之后取消了独立进程,作为一个模块被整合在istiod中。

总体来说,Istio 在安全架构方面主要包括以下内容:

  • 证书签发机构(CA)负责密钥和证书管理
  • API 服务器将安全配置分发给数据平面
  • 客户端、服务端通过代理安全通信
  • Envoy 代理管理遥测和审计

Citadel 工作原理

Citadel 主要包括 CA 服务器、SDS 服务器、证书密钥控制器等模块,它们的工作原理如下。

CA 服务器

Citadel 中的 CA 签发机构是一个 gRPC 服务器,启动时会注册两个 gRPC 服务,一个是 CA 服务,用来处理 CSR 请求(certificate signing request);另外一个是证书服务,用来签发证书。CA 首先通过 HandleCSR 接口处理来自客户端的 CSR 请求,对客户端进行身份验证(包括 TLS 认证和 JWT 认证),验证成功后会调用 CreateCertificate 进行证书签发。

SDS 服务器

SDS 即安全发现服务(Secret discovery service),它是一种在运行时动态获取证书私钥的 API,Envoy 代理通过 SDS 动态获取证书私钥。Istio 中的 SDS 服务器负责证书管理,并实现了安全配置的自动化。相比传统的方式,使用 SDS 主要有以下优点:

  • 无需挂载 Secret 卷
  • 动态更新证书,无需重启
  • 可以监听多个证书密钥对

目前的版本中,SDS 是默认开启的,它的工作流程如下:

  • Envoy 通过 SDS API 发送证书和密钥请求
  • istio-agent 作为 Envoy 的代理,创建一个私钥和证书签名请求(CSR),并发送给 istiod
  • CA 机构验证收到的 CSR 并生成证书
  • istio-agent 将私钥和从 istiod 收到的证书通过 SDS API 发送给 Envoy
  • 以上流程周期性执行实现密钥和证书轮换

证书密钥控制器

证书密钥控制器(CaSecretController)监听 istio.io/key-and-cert 类型的 Secret 资源,它会周期性的检查证书是否过期,并更新证书。

证书轮换

如果没有自动证书轮换功能,当证书过期时,就不得不重启签发,并重启代理。证书轮换解决了这一问题,提高了服务的可用性。Istio 里通过一个轮换器(Rotator)自动检查自签名的根证书,并在证书即将过期时进行更新,它本质上是一个协程(goroutine)在后台轮询实现的:

  • 获取当前证书,解析证书的有效期并获取下一次轮换时间
  • 启动定时器,如果发现证书到达轮换时间,从 CA 获取最新的证书密钥对
  • 更新证书

2.3.2 数据平面

Envoy 和 pilot-agent 打在同一个镜像中,即Proxy。

2.3.2.1 Envoy 组件

目前Istio使用Envoy代理的扩展版本。 Envoy是使用C++开发的高性能代理,可为服务网格中的所有服务路由控制所有入站和出站流量。 Envoy代理是与数据平面流量交互的唯一Istio组件。

目前Istio使用的不是Envoy官方版本,不过随着Envoy对于wasm的支持已经merge到了master,也许未来的istio的版本会直接使用官方版本。

2.3.2.2 Pilot-agent 组件

pilot-agent负责的工作包括:

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

2.3.2.3 istio-init 组件

Istio需要透明拦截服务的进站流量,实现原理为写入iptables,让该 pod 所在的 network namespace 的网络流量转发到 proxy 进程。

默认情况下,Istio在网格中部署的Pod中注入一个initContainer istio-init 。 istio-init容器设置了与Istio Sidecar代理之间的Pod网络流量重定向。这要求该Pod用户或服务帐户,必须具有足够的Kubernetes RBAC权限才能部署具有NET_ADMIN和NET_RAW功能的容器。

三、Istio核心实现原理

3.1 SideCar注入

  • Kubernetes 通过 Admission Controller 自动注入,或者用户使用 istioctl 命令手动注入 sidecar 容器。
  • 应用 YAML 配置部署应用,此时 Kubernetes API server 接收到的服务创建配置文件中已经包含了 Init 容器及 sidecar proxy。
  • 在 sidecar proxy 容器和应用容器启动之前,首先运行init-container,init-container用于设置 iptables(Istio 中默认的流量拦截方式,还可以使用 BPF、IPVS 等方式) 将进入 pod 的流量劫持到 Envoy sidecar proxy。所有 TCP 流量(Envoy 目前只支持 TCP 流量)将被 sidecar 劫持,其他协议的流量将按原来的目的地请求。
  • 启动 Pod 中的 Envoy sidecar proxy 和应用程序容器。
  • 不论是进入还是从 Pod 发出的 TCP 请求都会被 iptables 劫持,inbound 流量被劫持后经 Inbound Handler 处理后转交给应用程序容器处理,outbound 流量被 iptables 劫持后转交给 Outbound Handler 处理,并确定转发的 upstream 和 Endpoint。
  • Sidecar proxy 请求 Pilot 使用 xDS 协议同步 Envoy 配置,其中包括 LDS、EDS、CDS 等,不过为了保证更新的顺序,Envoy 会直接使用 ADS 向 Pilot 请求配置更新。

3.2 流量管理

3.2.1 架构

  • 流量管理一般是指采用合适的策略控制流量的速度和方向。如
    • OpenStack使用安全组规则来管理云主机的出/如口流量、流量类型等
    • Nginx 通过反向代理模式控制访问端的 ip 和认证
  • Istio 架构由 数据平面(data plane) 和 控制平面(control plane) 组成,因此 Istio 的流量包括:
    • 数据平面流量:容器里微服务之间的业务流量,一般 Istio 的流量管理指的是该部分流量
    • 控制平面流量:Istio 内部各组件之间配置和控制网格行为的流量
  • Istio 流量管理依赖于 Envoy 实现,网格发送和接收的所有流量(数据平面流量)都通过 Envoy 代理
    • 作用:通过 Envoy 能引导和控制网格周围的流量,且无需对服务进行任何更改

3.2.2 控制面

数据模型

包含两类数据

  • 服务数据:包含ServiceEntry和通过CRD定义的数据
  • 自定义流量规则:通过CRD定义的流量规则数据
服务发现模型

服务发现的数据来源

  • Pilot直接支持K8S的service数据
  • ServiceEntry:外部服务可以添加到pilot的注册表
  • WorkloadEntry:支持虚拟机服务以workload方式添加
  • MCP:适配模式,由第三方服务注册组件实现,如nacos、eureka、consul
pilot与Envoy数据流

Pilot是控制平面和envoy主要通信的组件,包括Discover Service和Agent两部分,其中agent运行在容器pod sidecar内,但是也是属于控制平面的一部分,这两部分共同构成pilot。

Discover Service获取服务信息、流量规则等,envoy通过xDS获取到配置信息修改。

Agent负责envoy的配置管理、生命周期管理,同样也是通过xDS和agent交互。

3.2.3 数据面

数据面以istio官方例子分析

Envoy配置模型&xDS协议&Sidecar配置

Envoy主要概念:

  • Downstream:连接到 Envoy 的下游 Host,发送请求并接收响应。
  • Upstream: 上游 Host 接收来自 Envoy 的连接和请求,并返回响应。
  • Listener:监听器是命名网地址(可以是TCP socket 或者 Unix domain socket),可以被下游客户端连接。在 Envoy 中,Listener 可以绑定到端口上直接对外服务,也可以不绑定到端口上,而是接收其他 listener 转发的请求。
  • Cluster:集群是指 Envoy 连接的一组上游主机,集群中的主机是对等的,对外提供相同的服务,组成了一个可以提供负载均衡和高可用的服务集群。Envoy 通过负载均衡策略决定将请求路由到哪个集群成员。

xDS 协议概念:

xDS提供了标准的控制面规范,通过此规范传递信息到数据面,控制平面和数据平面Envoy所使用的通信协议,目前xDS版本主要是v3版本,为一组不同数据源的服务发现协议总称。该协议是由envoy组件定义规范,istiod实现响应envoy的请求。
主要包括LDS、RDS、CDS、EDS、SDS、HDS、MS等多种类型,其中LDS、RDS、CDS、EDS为流量管理常用资源类型,ADS为聚合发现服务,一次请求能够获取LDS、RDS等所有信息。

  • Listener Discovery Service (LDS) : 监听器发现服务。Listener监听器控制Envoy启动端口监听(目前只支持TCP协议),并配置L3/L4层过滤器,当网络连接达到后,配置好的网络过滤器堆栈开始处理后续事件。这种通用的监听器体系结构用于执行大多数不同的代理任务(限流,客户端认证, HTTP连接管理, TCP代理等)
  • Route Discovery Service(RDS) : 路由发现服务。路由配置包含HTTP头部修改(增加、删除HTTP头部键值),virtual hosts (虚拟主机),以及virtual hosts 定义的各个路由条目。
  • Cluster Discovery Service (CDS): 集群发现服务。Envoy cluster管理器管理着所有的上游cluster。鉴于上游cluster或者主机可用于任何代理转发任务,所以上游cluster一般从Listener或Route中抽象出来。
  • Endpoint Discovery Service (EDS) :集群中的服务实例发现服务。Endpoint为上游主机标识。
  • Secret Discovery Service (SDS) :证书发现服务。用于运行时动态获取TLS证书。
  • Aggregated Discovery Service(ADS): 通过一个Aggregated Server提供所有xDS服务,以解决各个不同xDS服务的顺序导致的数据一致性问题。

Istio中的 Envoy Sidecar 配置:
Istio 通过 Listener、Route Config 和 Cluster 为 Mesh 中的 Envoy 生成了入向和出向两个不同方向的处理流程的配置。
在 Envoy 的基础上增加了 VirtualInboundListener,VirtualOutboundListener、OutboundCluster、InboundCluster 等概念。

端到端请求流程

下图显示了Envoy的inbound和outbound处理过程:

以Bookinfo 为例说明服务间 HTTP 调用的流量拦截及处理流程:

  1. Productpage 发起对 reviews 服务的调用:http://reviews:9080/reviews/0 。
  2. 请求被 productpage Pod 的 iptables 出向流量规则拦截,处理后重定向到本地 15001 端口。
  3. Envoy 在 15001 端口上监听的 VirtualOutbound listener 收到了该请求。
  4. 请求被 VirtualOutbound listener 根据原目标 IP(通配)和端口(9080)转发到 0.0.0.0_9080 这个
    outbound listener。
  5. 根据 0.0.0.0_9080 listener 的 http_connection_manager filter 配置,该请求采用 9080 route 进行分发。
  6. 9080 这个 route 的配置中,host name 为 reviews:9080 的请求对应
    的 cluster 为 outbound|9080||reviews.default.svc.cluster.local。
  7. outbound|9080||reviews.default.svc.cluster.local cluster 配置为通过EDS获取对应的Endpoint,通过 EDS
    查询得到该 cluster 中有3个 endpoint。
  8. 请求被 Envoy 转发到其中一个 endpoint 10.40.0.15,即 reviews-v1 所在的 pod。
  9. 然后该请求被 reviews-v1 pod 的 iptables 入向流量规则拦截,处理后重定向到本地的 15006 端口。
  10. 10.Envoy 在 15006 端口上监听的 VirtualInbound listener 收到了该请求。
  11. 根据匹配条件,请求被 VirtualInbound listener 内部配置的 Http connection manager filter 处理,该 filter
    设置的路由配置为将其发送给 inbound|9080|http|reviews.default.svc.cluster.local 这个 inbound cluster
  12. inbound|9080|http|reviews.default.svc.cluster.local cluster 配置的 host 为 127.0.0.1:9080。
  13. 请求被转发到 127.0.0.1:9080,即 reviews 服务进行业务处理。

3.3 可观测性

istio在v1.5之前的遥测数据主要是Mixer提供的,Mixer因为性能问题在v1.5后废弃,它的功能被Envoy Proxy承载,以上是Telemetry V2的架构。

根据Istio的文档,新的遥测系统将延迟减少了一半——延迟从7ms减少到3.3 ms。 不仅如此,Mixer废弃后CPU的总消耗降低了50%,降至每1,000个请求每秒0.55 vcpu。 新的API主要实现是在Envoy代理中提供wasm的运行环境Google的V8引擎,然后提供自定义的wasm插件来提供遥测数据。

service-level的指标主要通过两个插件提供,在源代码istio/proxy/extension中可以看到:

  • metadata exchange:会做reqeust和response的上下游标记,记录请求,

    在Http Header中添加envoy.wasm.metadata_exchange.upstreamenvoy.wasm.metadata_exchange.downstream

  • stats: 请求相关监控指标,暴露Prometheus 可采集的接口。

其它access_log_policy,stackdriver 是用于往Google StackDriver推送数据。

3.4 安全

istio 为微服务提供了无侵入,可插拔的安全框架。应用不需要修改代码,就可以利用 Istio 提供的双向 TLS 认证实现服务身份认证,并基于服务身份信息提供细粒度的访问控制。上图为istio官方的安全架构,安全主要分为认证和授权两个部分。安全需要通过控制面和数据面的协作来实现

  • 控制面:Istiod 中实现了一个 CA (Certificate Authority,证书机构) 服务器。该 CA 服务器负责为网格中的各个服务签发证书,并将证书分发给数据面的各个服务的边车代理。
  • 数据面:在网格中的服务相互之间发起 plain HTTP/TCP 通信时,和服务同一个 pod 中的边车代理会拦截服务请求,采用证书和对端服务的边车代理进行双向 TLS 认证并建立一个 TLS 连接,使用该 TLS 连接来在网络中传输数据。

四.常见问题

4.1 什么是服务网格?

服务网格是一种在分布式(可能是基于微服务的)软件系统内管理所有服务对服务(东西向)流量的技术。它既提供以业务为重点的功能操作,如路由,也提供非功能支持,如执行安全策略、服务质量和速率限制。它通常(尽管不是唯一的)使用 sidecar 代理来实现,所有服务都通过 sidecar 代理进行通信。

4.2 服务网格与 API 网关有什么不同?

关于服务网格的定义,见上文。

另一方面,API 网关管理进入集群的所有入口(南北)流量,并为跨功能的通信要求提供额外支持。它作为进入系统的单一入口点,使多个 API 或服务凝聚在一起,为用户提供统一的体验。

4.3 如果我正在部署微服务,我是否需要服务网格?

不一定。服务网格增加了技术栈的操作复杂性,因此通常只有在组织在扩展服务与服务之间的通信方面遇到困难,或者有特定的用例需要解决时才会部署。

4.4 我是否需要服务网格来实现微服务的服务发现?

不,服务网格提供了实现服务发现的一种方式。其他解决方案包括特定语言的库(如 Ribbon 和 Eureka 或 Finagle)。

4.5 服务网格是否会给我的服务之间的通信增加开销 / 延迟?

是的,当一个服务与另一个服务进行通信时,服务网格至少会增加两个额外的网络跳数(第一个是来自处理源的出站连接的代理,第二个是来自处理目的地的入站连接的代理)。然而,这个额外的网络跳转通常发生在 localhost 或 loopback 网络接口上,并且只增加了少量的延迟(在毫秒级)。实验和了解这对目标用例是否是一个问题,应该是服务网格分析和评估的一部分。

4.6 服务网格不应该是 Kubernetes 或应用程序被部署到的 “云原生平台” 的一部分吗?

潜在的。有一种说法是在云原生平台组件内保持关注点的分离(例如,Kubernetes 负责提供容器编排,而服务网格负责服务间的通信)。然而,正在进行的工作是将类似服务网格的功能推向现代平台即服务(PaaS)产品。

4.7 我如何实施、部署或推广服务网格?

最好的方法是分析各种服务网格产品(见上文),并遵循所选网格特有的实施准则。一般来说,最好是与所有利益相关者合作,逐步将任何新技术部署到生产中。

4.8 我可以建立自己的服务网格吗?

是的,但更相关的问题是,你应该吗?建立一个服务网格是你组织的核心竞争力吗?你能否以更有效的方式为你的客户提供价值?你是否也致力于维护你自己的网络,为安全问题打补丁,并不断更新它以利用新技术?由于现在有一系列的开源和商业服务网格产品,使用现有的解决方案很可能更有效。

4.9 在一个软件交付组织内,哪个团队拥有服务网格?

通常,平台或运维团队拥有服务网格,以及 Kubernetes 和持续交付管道基础设施。然而,开发人员将配置服务网格的属性,因此这两个团队应该紧密合作。许多企业正在追随云计算先锋的脚步,如 Netflix、Spotify 和谷歌,并正在创建内部平台团队,为以产品为重点的全周期开发团队提供工具和服务。

4.10 Envoy 是一个服务网格吗?

Envoy 是一个云原生代理,最初是由 Lyft 团队设计和构建的。Envoy 经常被用作服务网格的数据平面。然而,为了被认为是一个服务网格,Envoy 必须与控制平面一起使用,这样才能使这些技术集合成为一个服务网格。控制平面可以是简单的集中式配置文件库和指标收集器,也可以是全面 / 复杂的 Istio。

4.11 Istio 和 “服务网格 " 这两个词可以互换使用吗?

不,Istio 是服务网格的一种。由于 Istio 在服务网格类别出现时很受欢迎,一些人将 Istio 和服务网格混为一谈。这个混淆的问题并不是服务网格所独有的,同样的挑战发生在 Docker 和容器技术上。

4.12 我应该使用哪个服务网格?

这个问题没有唯一的答案。工程师必须了解他们当前的需求,以及他们的实施团队的技能、资源和时间。上面的服务网格比较链接将提供一个良好的探索起点,但我们强烈建议企业至少尝试两个网格,以了解哪些产品、技术和工作流程最适合他们。

4.13 我可以在 Kubernetes 之外使用服务网吗?

是的。许多服务网格允许在各种基础设施上安装和管理数据平面代理和相关控制平面。HashiCorp 的 Consul 是最知名的例子,Istio 也被实验性地用于 Cloud Foundry。

  • 3
  • 3
  • 1
1 评论
0/1000
网个大鱼

首发

2023-06-21 10:30:05
0
回复
评论(1) 发表评论
网个大鱼

首发

网个大鱼

网个大鱼

12 篇文章 1 粉丝
关注

浅谈下一代微服务架构——Istio服务网格

2023-05-25 10:41:46 125阅读

一、背景

从服务架构的演绎过程来看,服务架构经历了从单体架构到SOA架构,并到微服务架构的演进,在在微服务架构中,我们需要关注服务间怎么通信,服务怎么查找,服务故障怎么处理等,在现有的微服务架构中,SpringCloud提供了比较成熟的微服务治理全家桶方案,阿里也形成了以Dubbo为基础的微服务技术体系,包括服务注册中心Nacos、隔离熔断Sentinel、分布式事务seata、分布式任务调度SchedulerX等。而SpringCloud/Dubbo框架提供的服务治理能力是代码侵入的,主要支持Java,其它语言像go/nodejs/python等需要定制开发对应的SDK才能享有完整的服务治理能力。

因此,需要把与应用业务逻辑无关的功能抽象到共同基础设施,来降低应用程序代码和底层平台的耦合度,使开发者更能专注于本身的业务逻辑,而无需耗费精力在基础代码的设计上。

1.1什么是服务网格

服务网格(Service Mesh)是一个专门处理服务通讯的基础设施层。它的职责是在由云原生应用组成服务的复杂拓扑结构下进行可靠的请求传送。服务网格的目的是将服务治理能力下沉到基础设施,让业务更加专注于业务逻辑。在实际部署时,Service Mesh 通常以轻量级的网络代理的方式跟应用的代码部署在一起,从而以应用无感知的方式实现服务治理。

服务网格从总体架构上可以分为一堆紧挨着各项服务的用户代理,和一组任务管理组件组成。

管理组件被称为控制层或控制平面(control plane),负责与控制平面中的代理通信,下发策略和配置。

代理在服务网格中被称为数据层或数据平面(data plane),直接处理入站和出站数据包,转发、路由、健康检查、负载均衡、认证、鉴权、产生监控数据等。

一个典型的服务网格部署网络结构图如下:

其中绿色方块为应用服务,蓝色方块为 Sidecar Proxy,应用服务之间通过 Sidecar Proxy 进行通信,整个服务通信形成图中的蓝色网络连线,图中所有蓝色部分就形成了 Service Mesh。

服务网格有如下几个特点:

  • 应用程序间通讯的中间层
  • 轻量级网络代理
  • 应用程序无感知
  • 解耦应用程序的重试/超时、监控、追踪和服务发现

1.2 服务网格选型

目前社区比较活跃的 Service Mesh 实现主要有2个:Linkerd2、Istio。

Istio和Linkerd的区别在于数据平面使用了两种不同的代理技术,Istio使用Envoy作为其代理。Envoy是C++编写的,最初是由Lyft构建,以便以非Kubernetes方式促进微服务的流量管理。许多公司已经将Envoy扩展为Kubernetes的ingress技术;Linkerd(v2)使用的是一种名为Linkerd-proxy的专用服务网格代理。这个代理是使用Rust编写的。

Istio是构建与Envoy之上的因此在流量管理方面它是占据优势的,Envoy已经包含了重要的IMHO功能,比如子集路由。用户仍然可以使用Linkerd实现金丝雀/蓝绿/a-b发布,但必须依靠单独的Kubernetes服务和能够分发流量的集群ingress技术,比如Gloo(gloo.solo.io)。Linkerd团队在最近一次社区会议上公开表示,计划在未来的版本中实现更加高级的L7流量管理功能。

Linkerd未能提供请求追踪。想要以非侵入方式查。。。。看请求追踪跨度必须等待Linkerd实现该功能。Istio利用了Envoy支持添加追踪headers的事实。

在性能方面,对于综合工作负载,Istio的Envoy代理使用比Linkerd多50%的CPU。

Istio比Linkerd2.3有多的特性。更多的特性意味着处理更复杂和边缘用例的能力增强。更多的特性通常意味着更多的配置,潜在的资源利用率和运营成本的增加。

二、Istio架构与概念

2.1 Istio基础架构

2.1.1 数据平面

Istio的数据平面主要包括Envoy代理的扩展版本。Envoy是一个开源边缘和服务代理,可帮助将网络问题与底层应用程序分离开来。应用程序仅向localhost发送消息或从localhost接收消息,而无需了解网络拓扑。

Envoy的核心是在OSI模型的L3和L4层运行的网络代理。它通过使用可插入网络过滤器链来执行连接处理。此外,Envoy支持用于基于HTTP的流量的附加L7层过滤器。而且,Envoy对HTTP/2和gRPC传输具有一流的支持。

Envoy在Istio上表现出色的另一个原因之一是它的可扩展性。Envoy提供了基于WebAssembly的可插拔扩展模型。这在定制策略执行和遥测生成中非常有用。此外,我们还可以使用基于Proxy-Wasm沙箱API的Istio扩展在Istio中扩展Envoy代理。

数据平面的特点:

  •     通常是按照无状态目标设计的,但实际上为了提高流量转发性能,需要缓存一些数据,因此无状态也是有争议的。
  •     直接处理入站和出站数据包,转发、路由、健康检查、负载均衡、认证、鉴权、产生监控数据等。
  •     对应用来说透明,即可以做到无感知部署。

从istio1.5 开始,简化了控制平面,将先前由 Pilot,Galley,Citadel 和 sidecar 注入器执行的功能统一为一个二进制文件istiod 。其提供服务发现,配置和证书管理功能。

2.1.2 控制平面

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

  •     不直接解析数据包。
  •     与数据平面中的代理通信,下发策略和配置。
  •     负责网络行为的可视化。
  •     通常提供 API 或者命令行工具可用于配置版本化管理,便于持续集成和部署

2.2 核心概念

  • Sidecar( 边 车): Sidecar 自定义资源描述了Sidecar代理的配置,该代理协调与其连接的工作负载实例的入站和出站通信。
  • 服务(Service):在服务注册表中的具有唯一名称的应用单位。服务由运行在pod、容器、虚拟机上的工作负载实例实现的多个网络端点组成。
  • 服务版本(Service Versions):也称为服务子集(Subsets),在持续部署场景中,灰度发布常用到的术语。
  • 源(Source):调用目标服务的下游客户端。
  • 主机(Host):客户端在连接服务时的地址
  • 访问模型(Access Model): 应用程序在不知道各个服务版本(子集)的情下仅对目标服务( 主机)进行寻址。 版本的实际选择由Sidecar代理确定,使应用程序代码能够脱离依赖服务的演变。
  • 虚拟服务(Virtual Service):一个虚拟服务定义了一系列针对指定服务的流量路由规则。每个路由规则都针对特定协议定义流量匹配规则。如果流量符合这些特征,就会根据规则发送到服务注册表中的目标服务(或者目标服务的子集或版本)。
  • 目标规则(Destination Rule):目标规则定义了在路由发生后应用于服务的流量的策略。这些规则指定负载均衡的配置,来自Sidecar代理的连接池大小以及异常检测设置,以便从负载均衡池中检测和驱逐不健康的主机。

Kubernetes、xDS、Istio 三者之间的资源抽象对比。

Kubernetes xDS Istio 服务网格
Endpoint Endpoint WorkloadEntry
Service Route VirtualService
kube-proxy Route DestinationRule
kube-proxy Listener EnvoyFilter
Ingress Listener Gateway
Service Cluster ServiceEntry

2.3 基本组件

2.3.1 控制平面

从istio1.5 开始,简化了控制平面,将先前由 Pilot,Galley,Citadel 和 sidecar 注入器执行的功能统一为一个二进制文件istiod 。其提供服务发现,配置和证书管理功能。

2.3.1.1 Pilot

Pilot类似传统C/S架构中的服务端Master,为 Envoy sidecar 提供服务发现功能,为智能路由(例如 A/B 测试、金丝雀部署等)和弹性(超时、重试、熔断器等)提供流量管理功能。它将控制流量行为的高级路由规则转换为特定于 Envoy 的配置,并在运行时将它们传播到 sidecar。和传统的微服务架构对比,Pilot 至少涵盖服务注册中心和 Config Server 等管理组件的功能。

Pilot 组件架构如下图:

Pilot 直接从运行平台提取数据并将其构造和转换成 Istio 的服务发现模型,因此Pilot只有服务发现功能,无须进行服务注册。这种抽象模型解耦了Pilot和底层平台的不同实现,可支持Kubernetes、Consul等平台。

除了服务发现,Pilot 更重要的一个功能是向数据面下发规则,包括 VirtualService、DestinationRule、Gateway、ServiceEntry 等流量治理规则,也包括认证授权等安全规则。Pilot 负责将各种规则转换成 Envoy 可识别的格式,通过标准的 xDS 协议发送给 Envoy,指导Envoy完成动作。在通信上,Envoy通过gRPC流式订阅Pilot的配置资源。

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。

pilot-agent

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

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

在proxy镜像中,pilot-agent负责的工作包括:

  1. 生成envoy的配置。
  2. 启动envoy。
  3. 监控并管理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 的架构下图所示:

pilot-discovery扮演服务注册中心、istio控制平面到Envoy之间的桥梁作用。pilot-discovery的主要功能包括:

  1. 监控服务注册中心(如Kubernetes)的服务注册情况。在Kubernetes环境下,会监控service、endpoint、pod、node等资源信息。
  2. 监控istio控制面信息变化,在Kubernetes环境下,会监控包括RouteRule、VirtualService、Gateway、EgressRule、ServiceEntry等以Kubernetes CRD形式存在的istio控制面配置信息。
  3. 将上述两类信息合并组合为Envoy可以理解的(即遵循Envoy data plane api的)配置信息,并将这些信息以gRPC协议提供给Envoy。

2.3.1.2 Citadel 组件

服务列表中的 istio-citadel是 Istio的核心安全组件,提供了自动生成、分发、轮换与撤销密钥和证书功能。Citadel一直监听Kube-apiserver,以 Secret的形式为每个服务都生成证书密钥,并在Pod创建时挂载到Pod上,代理容器使用这些文件来做服务身份认证,进而代理两端服务实现双向TLS认证、通道加密、访问授权等安全功能,这样用户就不用在代码里面维护证书密钥了。1.5版本之后取消了独立进程,作为一个模块被整合在istiod中。

总体来说,Istio 在安全架构方面主要包括以下内容:

  • 证书签发机构(CA)负责密钥和证书管理
  • API 服务器将安全配置分发给数据平面
  • 客户端、服务端通过代理安全通信
  • Envoy 代理管理遥测和审计

Citadel 工作原理

Citadel 主要包括 CA 服务器、SDS 服务器、证书密钥控制器等模块,它们的工作原理如下。

CA 服务器

Citadel 中的 CA 签发机构是一个 gRPC 服务器,启动时会注册两个 gRPC 服务,一个是 CA 服务,用来处理 CSR 请求(certificate signing request);另外一个是证书服务,用来签发证书。CA 首先通过 HandleCSR 接口处理来自客户端的 CSR 请求,对客户端进行身份验证(包括 TLS 认证和 JWT 认证),验证成功后会调用 CreateCertificate 进行证书签发。

SDS 服务器

SDS 即安全发现服务(Secret discovery service),它是一种在运行时动态获取证书私钥的 API,Envoy 代理通过 SDS 动态获取证书私钥。Istio 中的 SDS 服务器负责证书管理,并实现了安全配置的自动化。相比传统的方式,使用 SDS 主要有以下优点:

  • 无需挂载 Secret 卷
  • 动态更新证书,无需重启
  • 可以监听多个证书密钥对

目前的版本中,SDS 是默认开启的,它的工作流程如下:

  • Envoy 通过 SDS API 发送证书和密钥请求
  • istio-agent 作为 Envoy 的代理,创建一个私钥和证书签名请求(CSR),并发送给 istiod
  • CA 机构验证收到的 CSR 并生成证书
  • istio-agent 将私钥和从 istiod 收到的证书通过 SDS API 发送给 Envoy
  • 以上流程周期性执行实现密钥和证书轮换

证书密钥控制器

证书密钥控制器(CaSecretController)监听 istio.io/key-and-cert 类型的 Secret 资源,它会周期性的检查证书是否过期,并更新证书。

证书轮换

如果没有自动证书轮换功能,当证书过期时,就不得不重启签发,并重启代理。证书轮换解决了这一问题,提高了服务的可用性。Istio 里通过一个轮换器(Rotator)自动检查自签名的根证书,并在证书即将过期时进行更新,它本质上是一个协程(goroutine)在后台轮询实现的:

  • 获取当前证书,解析证书的有效期并获取下一次轮换时间
  • 启动定时器,如果发现证书到达轮换时间,从 CA 获取最新的证书密钥对
  • 更新证书

2.3.2 数据平面

Envoy 和 pilot-agent 打在同一个镜像中,即Proxy。

2.3.2.1 Envoy 组件

目前Istio使用Envoy代理的扩展版本。 Envoy是使用C++开发的高性能代理,可为服务网格中的所有服务路由控制所有入站和出站流量。 Envoy代理是与数据平面流量交互的唯一Istio组件。

目前Istio使用的不是Envoy官方版本,不过随着Envoy对于wasm的支持已经merge到了master,也许未来的istio的版本会直接使用官方版本。

2.3.2.2 Pilot-agent 组件

pilot-agent负责的工作包括:

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

2.3.2.3 istio-init 组件

Istio需要透明拦截服务的进站流量,实现原理为写入iptables,让该 pod 所在的 network namespace 的网络流量转发到 proxy 进程。

默认情况下,Istio在网格中部署的Pod中注入一个initContainer istio-init 。 istio-init容器设置了与Istio Sidecar代理之间的Pod网络流量重定向。这要求该Pod用户或服务帐户,必须具有足够的Kubernetes RBAC权限才能部署具有NET_ADMIN和NET_RAW功能的容器。

三、Istio核心实现原理

3.1 SideCar注入

  • Kubernetes 通过 Admission Controller 自动注入,或者用户使用 istioctl 命令手动注入 sidecar 容器。
  • 应用 YAML 配置部署应用,此时 Kubernetes API server 接收到的服务创建配置文件中已经包含了 Init 容器及 sidecar proxy。
  • 在 sidecar proxy 容器和应用容器启动之前,首先运行init-container,init-container用于设置 iptables(Istio 中默认的流量拦截方式,还可以使用 BPF、IPVS 等方式) 将进入 pod 的流量劫持到 Envoy sidecar proxy。所有 TCP 流量(Envoy 目前只支持 TCP 流量)将被 sidecar 劫持,其他协议的流量将按原来的目的地请求。
  • 启动 Pod 中的 Envoy sidecar proxy 和应用程序容器。
  • 不论是进入还是从 Pod 发出的 TCP 请求都会被 iptables 劫持,inbound 流量被劫持后经 Inbound Handler 处理后转交给应用程序容器处理,outbound 流量被 iptables 劫持后转交给 Outbound Handler 处理,并确定转发的 upstream 和 Endpoint。
  • Sidecar proxy 请求 Pilot 使用 xDS 协议同步 Envoy 配置,其中包括 LDS、EDS、CDS 等,不过为了保证更新的顺序,Envoy 会直接使用 ADS 向 Pilot 请求配置更新。

3.2 流量管理

3.2.1 架构

  • 流量管理一般是指采用合适的策略控制流量的速度和方向。如
    • OpenStack使用安全组规则来管理云主机的出/如口流量、流量类型等
    • Nginx 通过反向代理模式控制访问端的 ip 和认证
  • Istio 架构由 数据平面(data plane) 和 控制平面(control plane) 组成,因此 Istio 的流量包括:
    • 数据平面流量:容器里微服务之间的业务流量,一般 Istio 的流量管理指的是该部分流量
    • 控制平面流量:Istio 内部各组件之间配置和控制网格行为的流量
  • Istio 流量管理依赖于 Envoy 实现,网格发送和接收的所有流量(数据平面流量)都通过 Envoy 代理
    • 作用:通过 Envoy 能引导和控制网格周围的流量,且无需对服务进行任何更改

3.2.2 控制面

数据模型

包含两类数据

  • 服务数据:包含ServiceEntry和通过CRD定义的数据
  • 自定义流量规则:通过CRD定义的流量规则数据
服务发现模型

服务发现的数据来源

  • Pilot直接支持K8S的service数据
  • ServiceEntry:外部服务可以添加到pilot的注册表
  • WorkloadEntry:支持虚拟机服务以workload方式添加
  • MCP:适配模式,由第三方服务注册组件实现,如nacos、eureka、consul
pilot与Envoy数据流

Pilot是控制平面和envoy主要通信的组件,包括Discover Service和Agent两部分,其中agent运行在容器pod sidecar内,但是也是属于控制平面的一部分,这两部分共同构成pilot。

Discover Service获取服务信息、流量规则等,envoy通过xDS获取到配置信息修改。

Agent负责envoy的配置管理、生命周期管理,同样也是通过xDS和agent交互。

3.2.3 数据面

数据面以istio官方例子分析

Envoy配置模型&xDS协议&Sidecar配置

Envoy主要概念:

  • Downstream:连接到 Envoy 的下游 Host,发送请求并接收响应。
  • Upstream: 上游 Host 接收来自 Envoy 的连接和请求,并返回响应。
  • Listener:监听器是命名网地址(可以是TCP socket 或者 Unix domain socket),可以被下游客户端连接。在 Envoy 中,Listener 可以绑定到端口上直接对外服务,也可以不绑定到端口上,而是接收其他 listener 转发的请求。
  • Cluster:集群是指 Envoy 连接的一组上游主机,集群中的主机是对等的,对外提供相同的服务,组成了一个可以提供负载均衡和高可用的服务集群。Envoy 通过负载均衡策略决定将请求路由到哪个集群成员。

xDS 协议概念:

xDS提供了标准的控制面规范,通过此规范传递信息到数据面,控制平面和数据平面Envoy所使用的通信协议,目前xDS版本主要是v3版本,为一组不同数据源的服务发现协议总称。该协议是由envoy组件定义规范,istiod实现响应envoy的请求。
主要包括LDS、RDS、CDS、EDS、SDS、HDS、MS等多种类型,其中LDS、RDS、CDS、EDS为流量管理常用资源类型,ADS为聚合发现服务,一次请求能够获取LDS、RDS等所有信息。

  • Listener Discovery Service (LDS) : 监听器发现服务。Listener监听器控制Envoy启动端口监听(目前只支持TCP协议),并配置L3/L4层过滤器,当网络连接达到后,配置好的网络过滤器堆栈开始处理后续事件。这种通用的监听器体系结构用于执行大多数不同的代理任务(限流,客户端认证, HTTP连接管理, TCP代理等)
  • Route Discovery Service(RDS) : 路由发现服务。路由配置包含HTTP头部修改(增加、删除HTTP头部键值),virtual hosts (虚拟主机),以及virtual hosts 定义的各个路由条目。
  • Cluster Discovery Service (CDS): 集群发现服务。Envoy cluster管理器管理着所有的上游cluster。鉴于上游cluster或者主机可用于任何代理转发任务,所以上游cluster一般从Listener或Route中抽象出来。
  • Endpoint Discovery Service (EDS) :集群中的服务实例发现服务。Endpoint为上游主机标识。
  • Secret Discovery Service (SDS) :证书发现服务。用于运行时动态获取TLS证书。
  • Aggregated Discovery Service(ADS): 通过一个Aggregated Server提供所有xDS服务,以解决各个不同xDS服务的顺序导致的数据一致性问题。

Istio中的 Envoy Sidecar 配置:
Istio 通过 Listener、Route Config 和 Cluster 为 Mesh 中的 Envoy 生成了入向和出向两个不同方向的处理流程的配置。
在 Envoy 的基础上增加了 VirtualInboundListener,VirtualOutboundListener、OutboundCluster、InboundCluster 等概念。

端到端请求流程

下图显示了Envoy的inbound和outbound处理过程:

以Bookinfo 为例说明服务间 HTTP 调用的流量拦截及处理流程:

  1. Productpage 发起对 reviews 服务的调用:http://reviews:9080/reviews/0 。
  2. 请求被 productpage Pod 的 iptables 出向流量规则拦截,处理后重定向到本地 15001 端口。
  3. Envoy 在 15001 端口上监听的 VirtualOutbound listener 收到了该请求。
  4. 请求被 VirtualOutbound listener 根据原目标 IP(通配)和端口(9080)转发到 0.0.0.0_9080 这个
    outbound listener。
  5. 根据 0.0.0.0_9080 listener 的 http_connection_manager filter 配置,该请求采用 9080 route 进行分发。
  6. 9080 这个 route 的配置中,host name 为 reviews:9080 的请求对应
    的 cluster 为 outbound|9080||reviews.default.svc.cluster.local。
  7. outbound|9080||reviews.default.svc.cluster.local cluster 配置为通过EDS获取对应的Endpoint,通过 EDS
    查询得到该 cluster 中有3个 endpoint。
  8. 请求被 Envoy 转发到其中一个 endpoint 10.40.0.15,即 reviews-v1 所在的 pod。
  9. 然后该请求被 reviews-v1 pod 的 iptables 入向流量规则拦截,处理后重定向到本地的 15006 端口。
  10. 10.Envoy 在 15006 端口上监听的 VirtualInbound listener 收到了该请求。
  11. 根据匹配条件,请求被 VirtualInbound listener 内部配置的 Http connection manager filter 处理,该 filter
    设置的路由配置为将其发送给 inbound|9080|http|reviews.default.svc.cluster.local 这个 inbound cluster
  12. inbound|9080|http|reviews.default.svc.cluster.local cluster 配置的 host 为 127.0.0.1:9080。
  13. 请求被转发到 127.0.0.1:9080,即 reviews 服务进行业务处理。

3.3 可观测性

istio在v1.5之前的遥测数据主要是Mixer提供的,Mixer因为性能问题在v1.5后废弃,它的功能被Envoy Proxy承载,以上是Telemetry V2的架构。

根据Istio的文档,新的遥测系统将延迟减少了一半——延迟从7ms减少到3.3 ms。 不仅如此,Mixer废弃后CPU的总消耗降低了50%,降至每1,000个请求每秒0.55 vcpu。 新的API主要实现是在Envoy代理中提供wasm的运行环境Google的V8引擎,然后提供自定义的wasm插件来提供遥测数据。

service-level的指标主要通过两个插件提供,在源代码istio/proxy/extension中可以看到:

  • metadata exchange:会做reqeust和response的上下游标记,记录请求,

    在Http Header中添加envoy.wasm.metadata_exchange.upstreamenvoy.wasm.metadata_exchange.downstream

  • stats: 请求相关监控指标,暴露Prometheus 可采集的接口。

其它access_log_policy,stackdriver 是用于往Google StackDriver推送数据。

3.4 安全

istio 为微服务提供了无侵入,可插拔的安全框架。应用不需要修改代码,就可以利用 Istio 提供的双向 TLS 认证实现服务身份认证,并基于服务身份信息提供细粒度的访问控制。上图为istio官方的安全架构,安全主要分为认证和授权两个部分。安全需要通过控制面和数据面的协作来实现

  • 控制面:Istiod 中实现了一个 CA (Certificate Authority,证书机构) 服务器。该 CA 服务器负责为网格中的各个服务签发证书,并将证书分发给数据面的各个服务的边车代理。
  • 数据面:在网格中的服务相互之间发起 plain HTTP/TCP 通信时,和服务同一个 pod 中的边车代理会拦截服务请求,采用证书和对端服务的边车代理进行双向 TLS 认证并建立一个 TLS 连接,使用该 TLS 连接来在网络中传输数据。

四.常见问题

4.1 什么是服务网格?

服务网格是一种在分布式(可能是基于微服务的)软件系统内管理所有服务对服务(东西向)流量的技术。它既提供以业务为重点的功能操作,如路由,也提供非功能支持,如执行安全策略、服务质量和速率限制。它通常(尽管不是唯一的)使用 sidecar 代理来实现,所有服务都通过 sidecar 代理进行通信。

4.2 服务网格与 API 网关有什么不同?

关于服务网格的定义,见上文。

另一方面,API 网关管理进入集群的所有入口(南北)流量,并为跨功能的通信要求提供额外支持。它作为进入系统的单一入口点,使多个 API 或服务凝聚在一起,为用户提供统一的体验。

4.3 如果我正在部署微服务,我是否需要服务网格?

不一定。服务网格增加了技术栈的操作复杂性,因此通常只有在组织在扩展服务与服务之间的通信方面遇到困难,或者有特定的用例需要解决时才会部署。

4.4 我是否需要服务网格来实现微服务的服务发现?

不,服务网格提供了实现服务发现的一种方式。其他解决方案包括特定语言的库(如 Ribbon 和 Eureka 或 Finagle)。

4.5 服务网格是否会给我的服务之间的通信增加开销 / 延迟?

是的,当一个服务与另一个服务进行通信时,服务网格至少会增加两个额外的网络跳数(第一个是来自处理源的出站连接的代理,第二个是来自处理目的地的入站连接的代理)。然而,这个额外的网络跳转通常发生在 localhost 或 loopback 网络接口上,并且只增加了少量的延迟(在毫秒级)。实验和了解这对目标用例是否是一个问题,应该是服务网格分析和评估的一部分。

4.6 服务网格不应该是 Kubernetes 或应用程序被部署到的 “云原生平台” 的一部分吗?

潜在的。有一种说法是在云原生平台组件内保持关注点的分离(例如,Kubernetes 负责提供容器编排,而服务网格负责服务间的通信)。然而,正在进行的工作是将类似服务网格的功能推向现代平台即服务(PaaS)产品。

4.7 我如何实施、部署或推广服务网格?

最好的方法是分析各种服务网格产品(见上文),并遵循所选网格特有的实施准则。一般来说,最好是与所有利益相关者合作,逐步将任何新技术部署到生产中。

4.8 我可以建立自己的服务网格吗?

是的,但更相关的问题是,你应该吗?建立一个服务网格是你组织的核心竞争力吗?你能否以更有效的方式为你的客户提供价值?你是否也致力于维护你自己的网络,为安全问题打补丁,并不断更新它以利用新技术?由于现在有一系列的开源和商业服务网格产品,使用现有的解决方案很可能更有效。

4.9 在一个软件交付组织内,哪个团队拥有服务网格?

通常,平台或运维团队拥有服务网格,以及 Kubernetes 和持续交付管道基础设施。然而,开发人员将配置服务网格的属性,因此这两个团队应该紧密合作。许多企业正在追随云计算先锋的脚步,如 Netflix、Spotify 和谷歌,并正在创建内部平台团队,为以产品为重点的全周期开发团队提供工具和服务。

4.10 Envoy 是一个服务网格吗?

Envoy 是一个云原生代理,最初是由 Lyft 团队设计和构建的。Envoy 经常被用作服务网格的数据平面。然而,为了被认为是一个服务网格,Envoy 必须与控制平面一起使用,这样才能使这些技术集合成为一个服务网格。控制平面可以是简单的集中式配置文件库和指标收集器,也可以是全面 / 复杂的 Istio。

4.11 Istio 和 “服务网格 " 这两个词可以互换使用吗?

不,Istio 是服务网格的一种。由于 Istio 在服务网格类别出现时很受欢迎,一些人将 Istio 和服务网格混为一谈。这个混淆的问题并不是服务网格所独有的,同样的挑战发生在 Docker 和容器技术上。

4.12 我应该使用哪个服务网格?

这个问题没有唯一的答案。工程师必须了解他们当前的需求,以及他们的实施团队的技能、资源和时间。上面的服务网格比较链接将提供一个良好的探索起点,但我们强烈建议企业至少尝试两个网格,以了解哪些产品、技术和工作流程最适合他们。

4.13 我可以在 Kubernetes 之外使用服务网吗?

是的。许多服务网格允许在各种基础设施上安装和管理数据平面代理和相关控制平面。HashiCorp 的 Consul 是最知名的例子,Istio 也被实验性地用于 Cloud Foundry。

文章来自专栏

微服务架构-服务网格

12 篇文章 1 订阅
1 评论
0/1000
网个大鱼

首发

2023-06-21 10:30:05
0
回复
评论(1) 发表评论
网个大鱼

首发

  • 3
    点赞
  • 3
    收藏
  • 1
    评论