Envoy入门

核心功能
高性能设计:

采用 C++ 编写,拥有良好的四层、七层代理性能,在 8 核的机器上,HTTP 代理可以达到 10w 的 QPS,gRPC 可以达到 15w QPS,完全满足了 Service Mesh 中 Sidecar 的应用场景。

Filter 架构:

可以在四、七层编写 Filter 以扩展 Envoy 的功能,比如监听过滤器、四层网络过滤器,以及七层过滤器。不过 Envoy 支持最完善的还是HTTP 过滤器,支持了限流、路由转发、故障注入等多种服务治理功能,

良好的 HTTP/2 支持:

随着 gRPC 框架的流行以及边缘层网络性能的要求提升,HTTP/2 越来越被重视。Envoy 原生支持 HTTP/2,可以在 HTTP 和 HTTP/2 之间做转换。比如在 Sidecar 模式中,无论应用协议是 HTTP 还是 HTTP/2,Envoy 之间默认使用 HTTP/2 通信,这样极大提升了服务性能和稳定性,避免了 HTTP 频繁建立连接带来的消耗和不稳定性。

多种协议支持:

不仅支持 HTTP 和 HTTP/2,随着社区的发展,Thrift、gRPC、MongoDB、Redis、MySQL 等多种网络协议都被支持,甚至可以使用 Envoy 做 Redis 的 Mesh 方案,用来代替流行的 Redis 中间件。

可观测性:

支持强大的统计系统。日志、Metrics、链路追踪都有良好的支持。

边缘网关:

Envoy 本身就是一个高性能的网络代理组件,完全可以作为入口网关层使用,在 Kubernetes 中,也可以作为 Egress 和 Ingress 使用。

服务发现:

和其他常见的网络代理软件不同,Envoy 默认支持服务发现组件。Envoy 使用了一套xDS 的动态 API,获取服务的后端节点并实时更新,结合 Envoy 强大的负载均衡器,可以做到最终一致性。

架构设计

下图是 Envoy 架构的设计图,从图中可以看到入流量经过 Iptables 劫持被转发到了 Envoy 的端口,Envoy 通过监听端口创建连接,提供七层代理服务。

Iptable:通过 Iptable 劫持,将入口和出口流量都转发到 Envoy 上,达到劫持流量的目的。

Listener:Envoy 通过建立多个监听器提供不同的服务。比如通过监听的两个端口分别负责 Sidecar 模式的出流量和入流量,Sidecar 多使用这种设计,这样可以简化编程逻辑,也可以增强 Filter 的通用性。

如果提供不同协议,Envoy 也会建立不同的端口来提供服务。

Worker:每个 Listener 维护一个对应的 Worker Pool,Envoy 为每个逻辑处理器创建一个 Worker 线程,当一个新的端口启动一个新的 server 时,Envoy 也会根据 -concurrency 创建对应的 Worker 线程,要注意启动太多的 worker 线程并不一定是好事,特别是在 Sidecar 模式,并不会分配过多的逻辑核心给到 Sidecar,创建过多的 Worker 线程可能导致每个 Worker 线程维护的连接变多,Upstream 压力过大。

Filters:可以理解为中间件,通过 Filter,可以做到四层和七层的流量过滤,支持服务治理需要的限流、熔断等功能。

Cluster Manager:流量经过 Router,识别出需要转发的 Cluster,通过 Cluster Manager 进行服务发现和负载均衡等功能。

Upstream:Upstream 维护了 EndPoint 的连接池,通过负载具衡器,将流量转发到合适的 EndPoint 上面。

Envoy 作为 Service Mesh 中的数据面,也就是 Sidecar 模式下,整个的数据流转过程。

如上图所示,Envoy 作为 Sidecar 使用时,需要和服务部署在同一台机器或者 Pod 中,用户访问其他服务时,流量会被自动劫持到 Envoy 中。

下面结合一个具体的例子来讲解。下图是 Productpage 服务通过 HTTP 协议,调用 review 服务的过程。

通过 Iptables 对流量进行劫持,将 Productpage 访问 Reviews 的流量转发到 Envoy 的出流量 15001 端口上。

Envoy 先根据 virtual_hosts 进行匹配,再通过路由匹配,发现路由对应的 Cluster,通过服务发现找到 Cluster 对应的 EndPoint,将流量转发到 10.40.0.15:9080 的 Pod 上。

Reviews 的 Pod 通过 Iptables 对流量进行劫持,将流量劫持到 Envoy 的入流量端口 15006 上。

Envoy 将本地流量转发到对应的本地地址 127.0.0.1:9080,这里不需要对流量进行识别,因为流量被转发到入流量端口 15006 上,这个端口的配置用于本地流量的转发。

到这里整个 Sidecar 的流量出入过程就结束了。出入流量都经由 Envoy,最终被正确的转发到了 Reviews 的 Pod 上面。

Envoy 的数据结构

静态配置

Envoy 的配置分为静态配置和动态配置,静态配置就是手动填写的配置,动态配置是指由 xDS API 获取的配置。

如下代码,这里定义了 Listener 监听器,监听端口为 10000。virtual_hosts 匹配所有域名,Routes 的匹配规则为所有 Path,也就是所有访问 10000 端口的请求都会被转发到 service_google 服务。

listeners:
- name: listener_0
  address:
    socket_address: { address: 0.0.0.0, port_value: 10000 }
  filter_chains:
  - filters:
    - name: envoy.http_connection_manager
      config:
        stat_prefix: ingress_http
        codec_type: AUTO
        route_config:
          name: local_route
          virtual_hosts:
          - name: local_service
            domains: ["*"] // 匹配所有域名
            routes:
            - match: { prefix: "/" }// 匹配所有 path
              route: { host_rewrite: www.google.com, cluster: service_google } // 将流量转发到 service_google 服务
        http_filters:
        - name: envoy.router

下面的配置是 service_google 服务的负载均衡器,连接超时时间,以及要转发的地址。

clusters:
- name: service_google
  connect_timeout: 0.25s
  type: LOGICAL_DNS
  # Comment out the following line to test on v6 networks
  dns_lookup_family: V4_ONLY
  lb_policy: ROUND_ROBIN
  hosts: [{ socket_address: { address: google.com, port_value: 443 }}]
  tls_context: { sni: www.google.com }

边缘代理模式

Envoy 不仅可以用于 Sidecar 模式,也可以用作边缘网关,但是用作边缘网关层我们有一些注意事项,这些问题不仅在 Envoy 中存在,在其他的边缘网关中也应该处理。

HTTP 标头清理

一些外部传入的 header 可能会影响内部行为,应该统一做出清理操作,比如我们经常会用到的 x-forward-for,在反向代理中,未经过一层代理,都应该将代理的 IP 追加在 x-forward-for 中,以保证通过 x-forward-for 可以获取最原始的 IP,如果有客户端恶意传输 x-forward-for,不做清除操作可能会导致拿到错误的客户端 IP。在 Envoy 中可以通过 use_remote_address 设置为 true 来清理 HTTP 标头。

超时控制

超时控制分为连接超时、流超时和路由超时。这些超时控制不仅在边缘网关模式中需要注意,在 Sidecar 模式也需要注意,一些不合理的超时可能会引起服务的雪崩。虽然在内网服务调用时一般都会设置默认超时,但 Sidecar 应该设置一个默认的超时时间,避免服务没有设置有效超时的情况引起的问题。

连接超时

Envoy 为 HTTP 服务提供了空闲连接超时时间的设置,空闲超时是指一个连接在接收到请求后,会设置 TCP 的 idle Timeout 的参数,一段时间内没有收到代理服务的响应请求,则会断开连接。Envoy 默认的空闲超时是 1 小时。连接超时对所有流生效,连接一旦断开,所有流处理也会中断。

流超时

流是 HTTP/2 中的概念,在 HTTP/1 中没有流的概念,Envoy 通过将 HTTP 连接对应到流模式,统一进行处理。

HTTP 连接管理器 stream_idle_timeout 默认超时时间为 5 分钟,推荐对所有流设置合理的超时时间,这个时间就是接收请求到返回数据的处理时间,如果没有特殊需求,建议设置为 10s,默认超时时间偏长。如果触发此超时时间,则会出发 504 Gateway Timeout 的错误码。

路由超时

除了设置全局的流超时外,还可以设置路由层面的超时,为某些请求设置特殊的配置,一些请求可能需要更快的响应速度,所以要设置较短的超时时间,这个时候只要在路由层面设置即可,比如针对某些 Path 设置更短的超时时间。

连接限制

Envoy 可以针对全局或者监听器设置连接限制。一般单一服务器可承载的并发连接数有限,根据线上的峰值连接运行情况,设置合理的连接设置,可以避免因服务出问题时响应过慢,大量新建 HTTP 连接击垮 Envoy 的情况。

Envoy 不仅可以作为 Service Mesh 中的 Sidecar 使用,也可以作为边缘网关使用,它的本质就是一个反向代理服务器,Nginx、HAProxy 能做的事情 Envoy 也可以做得很好。

 

posted @ 2023-01-18 17:47  muzinan110  阅读(791)  评论(0编辑  收藏  举报