0%

【Service Mesh】Envoy 入门

Envoy 是一款由 Lyft 开源的高性能数据和服务代理软件,使用现代 C++ 开发,提供四层和七层网络代理能力。尽管在设计之初 Envoy没有将性能作为最终的目标,而是更加强调模块化、易测试、易开发等特性,可它仍旧拥有足可媲美 Nginx 等经典代理软件的超高性能。在保证性能的同时,Envoy也提供了强大的流量治理能力和可观察性。其独创的 xDS 协议则成为了构建 Service Mesh 通用数据面 API(UPDA)的基石。

Architecture

Envoy Architecture

首先介绍Envoy中的一些基本概念:

  • Downstream:下游主机,指连接到Envoy的主机,这些主机用来发送请求并接受响应。
  • Upstream:上游主机,指接收来自Envoy连接和请求的主机,并返回响应。
  • Listener:服务或程序的监听器, Envoy暴露一个或多个监听器监听下游主机的请求,当监听到请求时,通过Filter Chain把对请求的处理全部抽象为Filter, 例如ReadFilter、WriteFilter、HttpFilter等。
  • Cluster:服务提供集群,指Envoy连接的一组逻辑相同的上游主机。Envoy通过服务发现功能来发现集群内的成员,通过负载均衡功能将流量路由到集群的各个成员。
  • xDS:xDS中的x是一个代词,类似云计算里的XaaS可以指代IaaS、PaaS、SaaS等。DS为Discovery Service,即发现服务的意思。xDS包括CDS(cluster discovery service)、RDS(route discovery service)、EDS(endpoint discovery service)、ADS(aggregated discovery service),其中ADS称为聚合的发现服务,是对CDS、RDS、LDS、EDS服务的统一封装,解决CDS、RDS、LDS、EDS信息更新顺序依赖的问题,从而保证以一定的顺序同步各类配置信息。以上Endpoint、Cluster、Route的概念介绍如下:
    • Endpoint:一个具体的“应用实例”,类似于Kubernetes中的一个Pod;
    • Cluster:可以理解“应用集群”,对应提供相同服务的一个或多个Endpoint, 类似Kubernetes中Service概念,即一个Service提供多个相同服务的Pod;
    • Route:当我们做金丝雀发布部署时,同一个服务会有多个版本,这时需要Route规则规定请求如何路由到其中的某个版本上。

xDS模块的功能是通过Envoy API V1(基于HTTP)或V2(基于gRPC)实现一个服务端将配置信息暴露给上游主机,等待上游主机的拉取。

Envoy正常的工作流程为Host A(下游主机)发送请求至上游主机(Host B、Host C、Host D等),Envoy通过Listener监听到有下游主机的请求,收到请求后的Envoy将所有请求流量劫持至Envoy内部,并将请求内容抽象为Filter Chains路由至某个上游主机中从而实现路由转发及负载均衡能力。

Envoy为了实现流量代理能力通常需要一个统一的配置文件来记录信息以便启动时加载,在Envoy中启动配置文件有静态配置和动态配置两种方式。静态配置是将配置信息写入文件中,启动时直接加载,动态配置通过xDS实现一个Envoy的服务端(可以理解为以API接口对外实现服务发现能力)。

Network Topology

Envoy作为Service Mesh中的 sidecar 代理,请求可以通过 ingress 或者 egress listener 到达 envoy。

  • Ingress Listener 负责从服务网格中其他节点接受请求,并将请求转发到本地应用。本地应用的响应之后通过 Envoy 转发到 downstream。
  • Egress Listener 负责从本地应用接受请求,并将请求转发到服务网格中的其他节点。

Service Mesh

除了服务网格外,Envoy还可以用作很多其他的请求,比如作为内部的负载均衡器:

Internal Load Balancer

或者作为网络边缘的 ingress/egress 代理:

Ingress/Egress Proxy on Network Edge

在实际应用中,Envoy一般会发挥上述多种功能,一个网络请求路径中可能会通过多个Envoy:

Hybrid Envoy

为了可靠性和可扩充性,Envoy可能会被配置成多层拓扑的形式:

Envoy Tiered

High Level Architecture

Envoy中服务请求处理过程可以大致分为两个部分:

  • Listener 子系统:处理来自 downstream 的请求。
  • Cluster 子系统:负责选择和配置 upstream 连接。

High Level Architecture

Envoy采用了基于事件的线程模型:

  • 一个主线程负责server的生命周期,配置处理,统计等
  • 多个worker线程负责处理请求。

所有的线程都运行在一个基于 libevent 的事件循环中,任何 downstream 的 TCP连接都会被分配一个 work 线程来处理

过滤器

Envoy 进程中运行着一系列 Inbound/Outbound 监听器(Listener),Inbound 代理入站流量,Outbound 代理出站流量。Listener 的核心就是过滤器链(FilterChain),链中每个过滤器都能够控制流量的处理流程。过滤器链中的过滤器分为两个类别:

  • 网络过滤器(Network Filters): 工作在 L3/L4,是 Envoy 网络连接处理的核心,处理的是原始字节,分为 ReadWriteRead/Write 三类。
  • HTTP 过滤器(HTTP Filters): 工作在 L7,由特殊的网络过滤器 HTTP connection manager 管理,专门处理 HTTP1/HTTP2/gRPC 请求。它将原始字节转换成 HTTP 格式,从而可以对 HTTP 协议进行精确控制。

除了 HTTP connection manager 之外,还有一种特别的网络过滤器叫 Thrift ProxyThrift 是一套包含序列化功能和支持服务通信的 RPC 框架,详情参考维基百科。Thrift Proxy 管理了两个 Filter:RouterRate Limit

除了过滤器链之外,还有一种过滤器叫监听器过滤器(Listener Filters),它会在过滤器链之前执行,用于操纵连接的元数据。这样做的目的是,无需更改 Envoy 的核心代码就可以方便地集成更多功能。例如,当监听的地址协议是 UDP 时,就可以指定 UDP 监听器过滤器。根据上面的分类,Envoy 过滤器的架构如下图所示:

img

Request Flow

Listener TCP Accept

Listener TCP Accept

Listener filter chains and network filter chain matching

Listener Filter Chains

../_images/lor-filter-chain-match.svg

TLS transport socket decryption

../_images/lor-transport-socket.svg

Network filter chain processing

../_images/lor-network-filters.svg

../_images/lor-network-read.svg

../_images/lor-network-write.svg

HTTP/2 codec encoding

TLS transport socket encryption

../_images/lor-http-filters.svg

../_images/lor-http.svg

../_images/lor-http-decode.svg

../_images/lor-http-encode.svg

../_images/lor-route-config.svg

Load Balancing

../_images/lor-lb.svg

Response path and HTTP lifecycle

../_images/lor-client.svg

Post-request processing

参考资料