istio 系列:3 envoy 原理基础

[TOC]

1 envoy 原理基础


envoy 是服务网格的非常重要的数据平面,而控制层面的实现则是 istio ,所以我们这里先从数据平面的这一步来慢慢了解云原生的服务网格,所有在本文中会讲到

  • 什么是Envoy

  • Envoy 组件拓扑

  • Envoy xDS 核心术语

  • Envoy的部署类型
  • Enovy线程模型和连接处理机制
  • Envoy核心配置组件
    • Listener
    • Filter
    • Cluster

1.1 什么是 Envoy

Envoy 是一种 L7 代理和通信总线,专为面向服务的大型现代系统而设计架构。

envoy 是作为新一代服务网格或者说是微服务的服务架构当中,用于实现以独立进程方式来做到高级网络功能的、轻量级的、7 层服务代理程序,通常以 sidecar 的方式运行在我们应用程序的旁边,当同时也可以作为整个网络的边缘代理来运行。

1.1.1 Envoy 功能:

  • 主要以 sidecar 的方式运行,业务进程外体系架构
  • L3/L4 过滤器体系
    • 更像是 nginx 中讲到的模块 (比如通过加载模块来扩展 nginx 的功能,那再 envoy 中就是启用过滤器来使用某个方面的功能) ,而且对 L3/L4 (网络传输层,网络层) 提供大量的扩展功能,从而实现网络管理功能
  • HTTP L7过滤器
    • 这个 L7 过滤器相较于 3、4 层过滤器来讲只能够支持一部分意义上比较主流的 7 层协议,当然最具有代表性的就是 http 和 https ,并且也能代理 redis 或者 zk 这种 7 层协议
  • 支持 http2 协议
  • 支持 htt3 协议
  • http 7 层路由各级功能
  • GRPC 支持
  • 服务发现和动态配置机制
  • 健康状态检查
  • 高级负载平衡
  • 前端/边缘代理支持
  • 一流的可观察性
  • 服务代理
  • 用 C++ 编写,高度并行,无阻塞
  • 提供服务发现/运行状况检查
  • 高级负载平衡
  • 统计数据、指标、跟踪
  • 通过 xDS 进行动态配置
  • 区域感知、优先级/位置负载平衡
    • 能够实现在接收一个请求尽量的根据配置把请求的后端局限在请求所在的区域内,这样能有更快的响应
  • 断路
  • 异常检测
    • 在 envoy 中功能很高级,可以被动的侦测对集群而言后端的状态码或者流量等,如果后端代理的 web 服务老是出现 5xx、4xx 系列状态码,这时候达到 envoy 的峰值就会将后端的被代理服务器弹出,从而实现将流量转发至好的后端服务器
  • 重试,重试策略
  • 超时(包括预算)
  • 流量镜像
  • 请求竞速
  • 速率限制
  • 访问日志记录、统计数据收集
  • 请求套期保值
  • 重试预算
  • 负载平衡优先级
  • 局部加权负载平衡
  • 区域正在路由
  • 降级端点(回退)
  • 聚集簇

1.1.2 Envoy 工作逻辑


如上图:

envoy 有两个工作位置:

  1. sidecar Proxy:

    sidecar proxy 运行在 workload 周边

    网格内部与每一个 workload 的旁边运行一个实例,这个时候 envoy 就是以 sidecar 的方式运行,只代理到当前 workload 的正向请求和反向请求,也就意味着 workload 对外发出的请求可以由 envoy 来代理,同时外部对该 workload 的请求也由这个 envoy 来代理,一个 sidecar 的 envoy 只负责当前的这个应用程序,这种 envoy 我们成为 sidecar proxy

  2. front Proxy:

    from proxy 不需要运行在应用程序周边,是独立运行为一个 pod

    envoy 也可以作为前端的负载均衡器,位于整个网络的边缘处代理该应用,envoy 用法很独特他未必是 api gateway 这种方式,大家应该都知道一个应用程序很可能有三五个实例,而这三五个实例是否需要一个专门的负载均衡器,那这个时候只有一个 envoy 就够了

    这个 envoy 作为一个边缘处的网络代理,接收到请求之后再分发给后端几个以 sidecar 形式启动的 envoy

    这时候每一个 sidecar 的 envoy 在代理给本地的 workload ,所以像这种 envoy 我们称为from proxy

1.1.3 Envoy 如何接收请求并向后端进行代理?


如上图:

用户请求通过 listeners (监听器) 将监听到的套接字发送至 envoy,客户端的请求就能与 envoy 建立连接,随后就可以发送报文,然后再由 listeners 监听器将报文进来之后需要的 filter chains (过滤链) 进行处理,也就是说收进来报文以后依次根据我们在配置文件中配置的多个过滤器来进行逐一过滤并处理之后向后端代理。如上图可以看到是三路不同的请求、分别各自有各自的过滤器链来进行处理。

一旦过滤器处理完了,这时候就需要向上代理,这时候一旦 filter chains (过滤链) 处理完毕之后就将对应的请求交给了真正适配的 cluster 来处理的

什么叫做适配呢?一般而言我们在前端这个 filter chains 中一定有一个过滤器能指明我接下来这个请求被那个 cluster 所处理,所以这就是请求路由、以此很有可能会在这个 filter chains 上执行很多高级功能

这个 cluster 是通过 cluster manager 定义管理而来,

在整个 envoy 上有这样几个组件:

  • listeners(监听器) :envoy 来讲任何请求的接入必须要靠 listeners 来实现,listeners 监听器负责监听套接字和过滤器的选择
  • filter chains(过滤链):进行逐一过滤并处理之后向后端代理
  • cluster manager(集群管理器):负责将后端代理的有多少个可以用来处理客户端请求的上游服务器规定成组,这些组被成为 cluster 、而这些 cluster 都是被 cluster manager 所管理,所以真正处理客户端请求的并不是 cluster manager 而是被 cluster manager 所管理的一个个 cluster

总结:

在 envoy 中重要的组件有三个,listeners、cluster,其中 listeners 和 cluster 之间的连接和交互是借助于 filter chains 当中的各种 filter 来实现的,很显然他的 filter 功能有很多种,但是至少应该有一个 filter 是用来做代理的,要么实现三四层代理,要么实现 7 层代理。

1.1.4 Envoy的几个显著特性

性能、可扩展性及动态可配置性:

  • 性能:除了大量功能外,Envoy还提供极高的吞吐量和低尾延迟差异,同时消耗相对较少的CPU和 RAM;
  • 可扩展性:Envoy 在 L4 和 L7上提供丰富的可插拔过滤器功能,允许用户轻松添加新功能;
  • API 可配置性:Envoy 提供了一组可由控制平面服务实现的管理API,也称为 xDS API
    • 若控制平面实现了这所有的 API,则可以使用通用引导配置在整个基础架构中运行 Envoy
    • 所有进一步的配置更改都可通过管理服务器无缝地进行动态传递,使得 Envoy 永远不需要重新启动
    • 于是,这使得 Envoy 成为一个通用数据平面,当与足够复杂的控制平面相结合时,可大大降低整体操作复杂性

Envoy xDS API存在 v1、v2 和 v3 三个版本:

  • v1 API 仅使用 JSON/REST,本质上是轮询
  • v2 API 是 v1 的演进,而不是革命,它是 v1 功能的超集,新的API模式使用 proto3 指定,并同时以 gRPC 和 REST + JSON/YAML 端点实现
    • 2021年第1季度结束支持
  • v3 API:当前支持的版本,支持 start_tls 、拒绝传入的 tcp 连接、4096 位的 tls 密钥、SkyWalking 和 WASM 等

Envoy 业已成为现代服务网格和边缘网关的“ 通用数据平面API ”,Istio、Ambassador 和 Gloo 等项目均是为此数据平面代理提供的控制平面;

1.2 Envoy 组件解析


如上图:

clients 下游服务对 Envoy 发起了访问,请求先发送至 listener ,当请求到达 listener 之后,在 listener 内部通过 filters(过滤器) 进行对处理,也就是说接收的报文依次根据我们在配置文件中配置的多个过滤器来进行逐一过滤并处理之后向后端代理,当过滤器处理完成之后将对应的请求交给了真正适配的 cluster 来处理,而这个 cluster 则是后端代理的可以用来处理客户端请求的上游服务器也就是一个一个散列的分布式应用程序

listener 是重要组件:内部我们要定义各种各样的 filters (过滤器),而对于一个具有代理功能的 filter 而言还需要完成请求的 route

cluster 是重要组件:代理后端多个不同的业务应用 server

用户为 envoy 提供配置的两种方式:

  • 可以在静态文件中直接配置
  • 也可以在配置文件中指定远程配置服务实现动态配置,动态配置使用的就是 XDS 协议

1.2.1 Envoy基础组件


在这张图中我们将 xDS 延申出来,可以看到 xDS 的管理访问可以是多个而不止是一个,除了上图还有很多 DS

  • xds 是LDS,CDS,RDS,EDS,SDS,...的总称,即发现服务,也就是他后2个字母ds是discovery service
    • LDS
    • L :Listener 即 envoy 的监听端口,LDS 用于动态发现 envoy 需要监听哪些端口
    • CDS
    • C:即 cluster,CDS 用于动态发现 cluster 上游的配置信息
    • RDS
    • R:即 route ,RDS 用于发现路由配置

    • EDS

    • E:即 endpoint , EDS 用于动态发现服务端点配置
    • SDS
    • s:即 Secret 密钥,SDS 用于动态发现 tls 证书,和私钥等

而且如上图我们看到有多个来一个 endpoint 组件,在 envoy 中每个 endpoint 的定义只是一个逻辑组件,其实每个 endpoint 对应一个 server,也就是说我们通过使用 EDS 所发现的每一个 server 映射进 envoy 内部来,就叫做一个 endpoint ,

当多个 endpoint 属于同一组的时候就定义为了一个 cluster,而 endpoint 自身并非实体组件,而是每一个外部的 server 对应一个甚至多个 endpoint

1.3 Envoy API常用术语

  • 主机(Host):一个具有网络通信能力的端点,例如服务器、移动智能设备等,而在理的 host 通常代表上游服务

  • 集群(Cluster):集群是Envoy连接到的一组逻辑上相似的端点;在v2中,RDS通过路由指向集群,CDS提供集群配置,而Envoy通过EDS发现集群成员,即端点;

  • 下游(Downstream):下游主机连接到 Envoy,发送请求并接收响应,它们是 Envoy 的客户端;

  • 上游(Upstream):上游主机接收来自 Envoy 的连接和请求并返回响应,它们是 Envoy 代理的后端服务器,可能是容器、虚拟机、服务器;

  • 端点(Endpoint):端点即上游主机,是一个或多个集群的成员,可通过 EDS 发现;

  • 侦听器(Listener):侦听器是能够由下游客户端连接的命名网络位置,例如端口或 unix 域套接字等;

  • 位置(Locality):上游端点运行的区域拓扑,包括地域、区域和子区域等;

  • 管理服务器(Management Server):实现 v3 API 的服务器,它支持复制和分片,并且能够在不同的物理机器上实现针对不同 xDS API 的 API 服务;

  • 地域(Region):区域所属地理位置;

  • 区域(Zone):AWS 中的可用区(AZ)或 GCP 中的区域等;

  • 子区域:Envoy 实例或端点运行的区域内的位置,用于支持区域内的多个负载均衡目标;

  • xDS 一组发现协议的合集:CDS 、EDS、HDS 、LDS、RLS(Rate Limit)、 RDS 、 SDS、VHDS和RTDS等API的统称;

  • Mesh 和 Envoy Mesh:mesh 其实指的就是网格,由一堆 envoy 的 sidecar 组成

1.4 Envoy 部署类型

Envoy通常用于以容器编排系统为底层环境的服务网格中,并以sidecar的形式与主程序容器运行为单个Pod;非编排系统环境中测试时,可以将主程序与Envoy运行于同一容器,或手动组织主程序容器与Envoy容器共享同一网络名称空间;

刚才 1.1.2 中讲过 envoy 有两个位置:

  1. front Proxy 是独立运行为一个 pod
  2. sidecar Proxy 将 envoy 以 sidecar 的方式运行,部署在对应的服务周边

1.4.1 front Proxy 做反向代理

具体使用时的常见部署类型如下图所示:


而 sidecar proxy 又有几种部署方式如上图:

  • 对于 service A 而言,这个 sidecar proxy 负责扮演两个作用
    1. 接收客户端请求,并代理给 Service A 应用本身,这种称为 ingress Listener(入站监听器)

    2. 同时还要代理 Service A 本地的服务作为客户端去请求别的服务如上图的 Service D,这种称为 egress Listener(出站监听器)

      如果 service A 访问 Service D 的话可以发现 service D 上有一个 ingress Listener ,而 service A 上有一个 egress listener ,真正通信的其实是两个具有 listener 的 envoy 来完成

  • 对于 service B 这种服务可能只是用来相应的那就无需 egress

  • 对于 service C 则有一个网格外部的 egress Listener ,如果说将流量发送至集群外部为了便于管理,可以将外部服务通过 External Service 引入到集群中,像这种情况之下,我们的 service C 访问客户端服务的时候只需要访问自己 egress Listener,egress Listener 由此将其代理到集群外部或网格外部

1.4.2 sidecar Proxy 做反向代理

1.4.2.1 Service to service only(服务与服务之间通信)


envoy 需要知道自己代理的 service 是谁,同时还需要访问另外一个 service 在什么地方,我们可以通过 discovery 来发现,也可能是访问外部的 external service

1.4.2.2 Service to service egress listener (服务对服务出口侦听器)


自己本地是客户端,然后我们定义一个 listener 监听某个套接字上,本地客户端访问我们本地的 envoy ,在通过 envoy 把外部的上游服务器定义成 cluster ,然后路由给这些 cluster ,近而与我们的网格或者网格外部的服务端进行通信

1.4.2.3 Service to service ingress listener (服务到服务入口侦听器)


自己是服务端,应用是服务端,所以我们定义一个 listener 监听来自下游客户端的请求并基于本地路由,在路由给某个集群的定义,这个集群就是定义的内部的应用程序

1.4.3 Front Envoy 与 Sidecar Envoy 通信


上图显示了位于 envoy 后面的服务到服务配置,用作HTTP L7边缘反向代理的群集。

  • 支持 TLS 连接;

  • 支持 HTTP/1.1 和 HTTP/2

  • 支持 HTTP L7路由;

  • 通过前端 envoy 的进入接入请求,并结合发现服务与服务对服务的 envoy 网格进行通信;

  • 前端 envoy 的工作方式与任何其他 envoy 的工作方式相同,事实除外它们不会与其他服务并置运行

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇