使者。 一、简介

问候! 这是一篇简短的文章,回答了以下问题:“什么是 Envoy?”、“为什么需要它?” 和“从哪里开始?”。

这是什么

Envoy 是一个用 C++ 编写的 L4-L7 平衡器,专注于高性能和可用性。 一方面,这在某种程度上类似于 nginx 和 haproxy,在性能上与它们相当。 另一方面,它更面向微服务架构,功能不比java和go中的平衡器差,例如zuul或traefik。

haproxy/nginx/envoy 的对比表,它并不声称是绝对真实的,但给出了一个大概的情况。

nginx的
hapoxy
使者
特拉菲克

github 上的星星
11.2k/镜像
1.1k/镜像
12.4k
27.6k

写在
C
C
C + +中
go

API
没有
仅套接字/推送
数据平面/拉动

主动健康检查
没有
是的
是的
是的

开放追踪
外部插件
没有
是的
是的

智威汤逊
外部插件
没有
是的
没有

延期
卢阿/C
卢阿/C
卢阿/C++
没有

为什么

这是一个年轻的项目,有很多东西缺失,有些还处于早期 alpha 阶段。 但 使者也由于它很年轻,正在迅速发展,并且已经拥有许多有趣的功能:动态配置、许多现成的过滤器、用于编写自己的过滤器的简单界面。
应用领域由此而来,但首先有 2 个反模式:

  • 静态反冲。

事实是,此刻在 使者 没有缓存支持。 谷歌的人正在尝试这个 修复。 这个想法将在一次实施 使者 RFC 合规性的所有微妙之处(zoo 标头),并为特定实现创建一个接口。 但现在还不是 alpha,架构正在讨论中, PR 打开(当我写PR文章时,PR冻结了,但这一点仍然相关)。

现在,使用 nginx 进行静态分析。

  • 静态配置。

你可以使用它,但是 使者 这不是它创建的目的。 静态配置中的功能不会被公开。 有很多时刻:

在 yaml 中编辑配置时,你会犯错误,责骂开发人员冗长,并认为 nginx/haproxy 配置虽然结构较少,但更简洁。 这才是重点。 Nginx 和 Haproxy 的配置是为了手动编辑而创建的,并且 使者 用于从代码生成。 整个配置描述于 protobuf的,从 proto 文件生成它更难犯错误。

Canary、b/g 部署场景等通常仅在动态配置中实现。 我并不是说这不能静态地完成,我们都这样做。 但为此,您需要在任何平衡器中使用拐杖,在 使者 包括。

Envoy 不可或缺的任务:

  • 复杂动态系统中的流量平衡。 这包括服务网格,但它不一定是唯一的。
  • 对分布式跟踪功能、复杂授权或其他可用功能的需求 使者 开箱即用或方便实现,但在 nginx/haproxy 中,您需要被 lua 和可疑插件包围。

如有必要,两者都可以提供高性能。

怎么开动这个

Envoy 仅作为 docker 镜像以二进制文件形式分发。 该图像已包含静态配置的示例。 但我们对它感兴趣只是为了了解其结构。

envoy.yaml 静态配置

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  host_rewrite: www.google.com
                  cluster: service_google
          http_filters:
          - name: envoy.router
  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
    load_assignment:
      cluster_name: service_google
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: www.google.com
                port_value: 443
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext
        sni: www.google.com

动态配置

我们正在寻找什么问题的解决方案? 您不能只是在负载下重新加载负载均衡器配置;将会出现“小”问题:

  • 配置验证。

配置可以很大,可以非常大,如果我们一次超载所有配置,某处出错的可能性就会增加。

  • 长久的连接。

初始化新侦听器时,您需要照顾旧侦听器上运行的连接;如果更改频繁发生并且存在长期连接,则您将不得不寻找折衷方案。 你好,nginx 上的 kubernetes 入口。

  • 积极的健康检查。

如果我们有主动的健康检查,我们需要在发送流量之前在新配置中仔细检查它们。 如果有很多上游,这需要时间。 你好。

这是如何解决的 使者通过动态加载配置,根据池模型,您可以将其划分为单独的部分,并且无需重新初始化未更改的部分。 例如,侦听器的重新初始化成本很高并且很少更改。

布局 使者 (来自上面的文件)具有以下实体:

  • 倾听者 — 侦听器挂在特定的 ip/端口上
  • 虚拟主机 - 按域名的虚拟主机
  • 路线 - 平衡规则
  • — 一组具有平衡参数的上游
  • 端点 — 上游实例地址

这些实体中的每一个以及其他一些实体都可以动态填充;为此,配置指定将从中接收配置的服务的地址。 服务可以是REST或gRPC,gRPC是更好的选择。

这些服务分别命名为:LDS、VHDS、RDS、CDS 和 EDS。 您可以将静态和动态配置结合起来,但限制是不能在静态资源中指定动态资源。

对于大多数任务来说,实现后三个服务就足够了,它们被称为ADS(聚合发现服务),用于 java的 那里有一个现成的 gRPC 数据平面实现,您只需在其中填充源中的对象即可。

配置采用以下形式:

envoy.yaml 动态配置

dynamic_resources:
  ads_config:
    api_type: GRPC
    grpc_services:
      envoy_grpc:
        cluster_name: xds_clr
  cds_config:
    ads: {}
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          rds:
            route_config_name: local_route
            config_source:
              ads: {}
          http_filters:
          - name: envoy.router
  clusters:
  - name: xds_clr
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: xds_clr
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: xds
                port_value: 6565

当您运行 使者 使用此配置,它将连接到控制平面并尝试请求 RDS、CDS 和 EDS 配置。 描述了交互过程如何发生 这里.

简而言之, 使者 发送请求,指示所请求的资源类型、节点的版本和参数。 作为响应,它接收资源和版本;如果控制平面上的版本没有更改,则它不响应。
有 4 个交互选项:

  • 适用于所有类型资源的一个 gRPC 流,发送资源的完整状态。
  • 独立的溪流,状况齐全。
  • 一个流,增量状态。
  • 单独的流,增量状态。

增量 xDS 允许您减少控制平面和 使者,这与大型配置相关。 但这使交互变得复杂;请求包含用于取消订阅和订阅的资源列表。

我们的示例使用 ADS - 用于 RDS、CDS、EDS 和非增量模式的一个流。 要启用增量模式,您需要指定 api_type: DELTA_GRPC

由于请求包含节点参数,因此我们可以针对不同实例向控制平面发送不同的资源 使者,这方便构建服务网格。

暖身

使者 在启动时或从控制平面接收新配置时,将启动资源预热过程。 分为监听器预热和集群预热。 第一个在 RDS/LDS 发生变化时启动,第二个在 CDS/EDS 发生变化时启动。 这意味着如果只有上游发生变化,则不会重新创建侦听器。

在预热过程中,在超时期间预计控制平面会提供相关资源。 如果超时,初始化将不会成功,新的侦听器将不会开始侦听该端口。
初始化顺序:EDS、CDS、主动健康检查、RDS、LDS。 启用主动运行状况检查后,只有在一次成功的运行状况检查后,流量才会上行。

如果重新创建侦听器,则旧侦听器将进入 DRAIN 状态,并在所有连接关闭或超时到期后将被删除 --drain-time-s,默认10分钟。

要继续进行下去。

来源: habr.com

添加评论