Envoy XDS 及 Istio 中的配置分发流程介绍

本文分享了 xDS 的组成及 Istio 中配置分发的流程,还有 xDS 的两种模式 SotW 和 Delta xDS。

版权声明
本文为 Jimmy Song 原创。转载请注明来源: https://jimmysong.io/blog/istio-delta-xds-for-envoy/
查看本文大纲

在 Istio 项目的早期采用全局状态(State of the World,简称 SotW)的方式推送配置给 Envoy 代理。一旦有一个服务变更,就要将全局配置推送给所有 Sidecar,造成巨大的网络负担及控制平面的性能损耗。Istio 社区从几年前就开始开发增量 xDS 以解决此问题,并在最近几个 Istio 版本中支持了增量 xDS。在最近的 Istio 1.22 发布中,增量 xDS 成为默认开启的功能。本文将为你介绍 xDS、增量 xDS 及 Istio 的配置分发方式。

什么是 xDS?

xDS(Extensible Discovery Service)是一种通信协议,用于在微服务架构中管理服务发现和动态配置。这种机制被广泛用于 Envoy 代理和 Istio 服务网格中,以管理各种类型的资源配置,如路由、服务发现、负载均衡设置等。

xDS 包含哪些发现服务?

xDS 包括以下主要的发现服务,每种服务都负责不同类型的网络资源配置:

  1. LDS(Listener Discovery Service):管理 Envoy 监听器的配置,这些监听器定义了如何接收和处理入站连接。
  2. RDS(Route Discovery Service):提供路由信息,定义了如何根据指定规则将请求路由到不同的服务。
  3. CDS(Cluster Discovery Service):管理集群信息,集群代表一组逻辑上类似的后端服务实例。
  4. EDS(Endpoint Discovery Service):提供具体服务实例的网络地址,这些服务实例组成了 CDS 中定义的集群。
  5. SDS(Secret Discovery Service):管理安全相关的配置,如 TLS 证书和私钥。
  6. VHDS(Virtual Host Discovery Service):为 RDS 提供虚拟主机配置,允许动态更新虚拟主机而不重启连接。
  7. SRDS(Scoped Route Discovery Service):管理路由作用域,提供基于不同条件(如请求头部)的动态路由选择。
  8. RTDS(Runtime Discovery Service):提供运行时配置,这些配置可用于实验性功能或精细调整系统行为。
  9. ECDS(Extension Config Discovery Service):为特定过滤器提供动态配置更新的服务。目前,网络过滤器、HTTP 过滤器和监听器过滤器都支持 ECDS。

这些服务共同支持动态配置的分发和更新,使得基于 Envoy 的应用架构能够实时适应变化,提高可扩展性和灵活性。每种服务的实现可以独立进行,也可以通过聚合方式(如 ADS)进行统一管理。CNCF 也成立了 xDS API 工作组来推动 xDS API 为 L4/L7 数据平面配置提供事实上的标准,类似于 SDN 中 OpenFlow 在 L2/L3/L4 中所扮演的角色。

提示
关于 xDS 协议的详细介绍,如 xDS 协议的 RPC 服务和变体方法,以及 xDS 请求流程,请参考 Envoy 代理文档

xDS 协议的变体

xDS 协议主要包括以下变体:

  1. State of the World (SotW):单独的 gRPC 流为每种资源类型提供完整数据,通常在 Envoy 代理初次启动时使用,也是 Istio 最早使用的 xDS 协议类型。
  2. 增量 xDS(Delta xDS):为每种资源类型提供变化的部分数据,从 2021 年开始开发,在 Istio 1.22 版本中开始默认开启。
  3. 聚合发现服务(ADS):一个 gRPC 流聚合所有资源类型的数据。
  4. 增量 ADS(Delta ADS):一个 gRPC 流聚合所有资源类型的增量数据。

下表概述了 xDS 协议的四种变体,包括对每个变体的解释、使用场景以及优缺点的对比。这些变体为不同的网络环境和服务需求提供了多种选择,可以根据具体情况选择最合适的协议变体以优化服务的性能和资源使用。

变体类型 解释 使用场景 优点 缺点
SotW 每次都发送所有配置数据,不论是否有变化。 适用于配置较少变化的稳定环境。 简单易实现,易于理解和维护。 数据传输量大,不适合频繁更新配置的环境。
Delta xDS 只传输变更的配置数据,而不是全部数据。 适用于配置频繁变化,需要快速响应变更的环境。 减少了不必要的数据传输,提高了效率。 实现复杂,需要客户端和服务端管理配置状态。
ADS 通过单一的 gRPC 流来管理所有配置数据,无需为每种资源类型建立独立的连接。 适用于需要同时管理多种类型资源的复杂服务架构。 减少了网络连接数,简化了资源管理。 对于网络或服务质量差的情况,单点故障可能导致所有配置更新失败。
Delta ADS 结合了 ADS 和增量 xDS 的优点,通过一个 gRPC 流聚合并且只传输变化部分的资源。 适用于既需要管理多种资源类型,又需要频繁更新配置的极其动态的环境。 提供了最大的灵活性和效率,适合大规模和高动态的服务架构。 实现最为复杂,对于配置管理的逻辑要求高,需要精确控制资源的变更和传输。
xDS 协议的四种变体介绍

使用 xDS 协议的服务网格可以更灵活地管理微服务之间的通信和配置,减少了配置变更的延迟,提高了系统的响应速度和可靠性。

在 Istio 中,DiscoveryServer 作为 Envoy 的 xDS API 的实现,负责监听 gRPC 接口并根据 Envoy 的需求动态推送配置。它能够处理各种资源类型的请求,并根据服务的变更实时更新 Envoy 配置。此外,它还支持安全特性,如验证客户端证书,确保只有合法的服务实例可以接收配置数据。

xDS 变体的配置示例

使用 xDS 协议的变体通常涉及在 Envoy 代理或与之类似的服务网格配置中指定 xDS 服务器的详细信息。虽然不同的服务网格和代理服务器的配置细节可能有所不同,下面是一些通用的 YAML 配置示例,说明如何指定 xDS 服务器以及如何使用这些协议变体。

State of the World (SotW)

在 Envoy 的配置中,你可以通过静态资源或通过 API 动态获取资源的方式来使用 SotW。这里是一个简单的 Envoy 配置示例,显示了如何静态定义集群和监听器:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static_resources:
  listeners:
    - address:
        socket_address: { address: 0.0.0.0, port_value: 80 }
      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: "/" }
                          route: { cluster: local_service }
                    http_filters:
                      - name: envoy.router
                  clusters:
        - name: local_service
            connect_timeout: 0.25s
            type: STATIC
            lb_policy: ROUND_ROBIN
            hosts: [{ socket_address: { address: 127.0.0.1, port_value: 80 } }]

增量 xDS

增量 xDS 的配置需要在 xDS 服务端支持增量协议,并在客户端配置中指定使用增量 xDS。Envoy 启动配置中需要添加 API 版本来启用增量 xDS:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
dynamic_resources:
  cds_config:
    api_config_source:
      api_type: DELTA_GRPC
      grpc_services:
        envoy_grpc:
          cluster_name: xds_cluster
  lds_config:
    api_config_source:
      api_type: DELTA_GRPC
      grpc_services:
        envoy_grpc:
          cluster_name: xds_cluster

聚合发现服务 (ADS)

使用 ADS 时,所有资源类型的配置通过一个单一的 API 端点聚合。这在 Envoy 配置中指定:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
dynamic_resources:
  cds_config:
    ads: {}
  lds_config:
    ads: {}
  ads_config:
    api_type: GRPC
    grpc_services:
      envoy_grpc:
        cluster_name: xds_cluster

增量 ADS

增量 ADS 通过在 ADS 配置中指定增量 API 类型,可以实现更为细粒度的更新:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
dynamic_resources:
  cds_config:
    ads: {}
    resource_api_version: V3
  lds_config:
    ads: {}
    resource_api_version: V3
  ads_config:
    api_type: DELTA_GRPC
    grpc_services:
      envoy_grpc:
        cluster_name: xds_cluster

这些配置示例需要根据你的具体环境和需求进行调整。更多细节和高级配置,你可以参考 Envoy 文档

Istio 如何发送配置给 Envoy sidecar?

得益于 xDS 协议,如 Istio、Envoy Gateway 等可以通过 API 远程动态分发配置到 Envoy 代理。下图展示了 Istio 的配置分发流程(Sidecar 模式)。

image
Istio 的配置分发流程图

Istio 中配置分发的主要流程说明:

  1. 声明式配置:用户通过 YAML 文件或其他配置管理工具定义服务网格的配置。这些配置可以包括路由规则、安全策略、遥测设置等。
  2. Kubernetes:Istio 配置文件被提交到 Kubernetes 集群中,通常是通过 kubectl apply 命令或其他 CI/CD 工具。Kubernetes 接收到配置文件并将其存储在 etcd 数据库中。
  3. Istiod:Istiod 是 Istio 的控制平面组件,负责管理和分发配置。它监听从 Kubernetes API 服务器中传入的事件,获取相关配置变更,并对其进行处理。Istiod 解析配置文件,生成相应的路由规则和策略,并通过 xDS API 将这些配置分发到数据平面(Envoy 代理)。
  4. xDS API:Istiod 使用 xDS API 将配置下发到各个 Envoy 代理中。
  5. Envoy Proxy:Envoy 是 Istio 的数据平面组件,运行在每个服务的旁路(sidecar)容器中,拦截并管理所有入站和出站流量。Envoy 代理通过 xDS API 接收来自 Istiod 的配置,并根据这些配置进行流量管理、策略执行和遥测数据收集。
  6. Pod:每个服务实例运行在一个 Pod 中,Pod 内部包含一个应用容器和一个 Envoy 代理容器。Envoy 代理拦截应用容器的所有网络流量,并根据配置进行处理。

这个配置分发流程确保了 Istio 能够动态管理和配置服务网格中的所有服务实例,提供一致的流量管理和策略执行。

xDS 的发展与 Istio 中的 Delta xDS 实现

起初,xDS 采用了“全局状态”(State of the World,简称 SotW)的设计,这意味着任何一个配置的更改都需要向 Envoy 发送所有配置的完整状态。这种方法在网络和控制平面上造成了巨大的负担,尤其是在大规模服务部署时。

在 2021 年的 EnvoyCon 上,Aditya Prerepa 和 John Howard 分享了 Istio 如何实现 Delta xDS,这是一种增量式的 xDS 实现。与传统的 SotW xDS 相比,Delta xDS 只发送变更的配置,显著减少了需要通过网络发送的配置数据量,从而提高了效率和性能。这种方法特别适用于那些配置频繁变更的环境,因为它只更新变化的部分而不是整个配置。

在实现 Delta xDS 的过程中,Istio 团队面临了多个挑战,包括如何确保配置更新的正确性以及避免潜在的资源泄漏。他们通过采用干运行(Dry-run)模式来并行运行 SotW 和 Delta 生成器,逐步发现并修复了实现中的缺陷。此外,他们还引入了新的 Envoy 类型,如虚拟主机发现服务(Virtual Host Discovery Service),以支持更细粒度的配置分发。

Delta xDS 增量配置

下图展示了 Delta xDS 增量配置的流程。

image
Delta xDS 增量配置流程图

Delta xDS 配置流程如下:

  1. 初始完整配置:控制平面向代理发送初始完整配置,此时使用的是 StoW 模式。
  2. 订阅配置变更:代理从控制平面订阅配置变更。
  3. 检查配置变更:控制平面检查相对于代理已知状态的配置变更。
  4. 计算差异:控制平面计算当前配置与代理持有的前一配置之间的差异(增量)。
  5. 仅发送差异:控制平面仅发送变更的配置(差异)给代理,代理应用这些差异增量更新其配置。

该流程确保只有必要的变更被传输和应用,提高了效率并减少了网络和代理资源的负载。

SotW vs Delta xDS

虽然 Delta xDS 解决了在大规模网络下的配置分发的性能问题,但是 SotW 模式依然有它存在的意义,比如在初次下发配置的情况下。下表对比了 Istio 中的两种配置分发方式:SotW (State of the World) 和 Delta xDS。

对比项 SotW Delta XDS
数据传输量 每次传输完整的配置数据,不管配置是否有变更。 仅传输发生变化的配置数据,减少了数据传输量。
效率 在小型或变更少的环境中效率可接受。 在大型环境或频繁变更的环境中更高效。
复杂性 实现简单,易于理解和维护。 实现较为复杂,需要精细的变更跟踪和管理。
资源消耗 可能因为重复发送大量未变更的数据而增加服务器和网络负载。 更低的资源消耗,因为只处理变更的部分。
实时性 配置更新后立即发送全量配置,实时性高。 只发送变更部分,响应更快,减少处理时间。
适用场景 适合配置变动不频繁的小型至中型部署。 适合配置频繁变更或大规模部署的场景。
Istio 中的全局状态和增量 xDS 配置分发方式对比

这个表格从数据传输量、效率、复杂性、资源消耗、实时性以及适用场景等多个角度对 SotW 和 Delta XDS 进行了对比,有助于在不同的使用环境中做出合适的选择。

总结

在这篇文章中我分享了 xDS 的组成及 Istio 中配置分发的流程,还有 xDS 的两种模式 SotW 和 Delta xDS。随着 Delta xDS 在 Istio 1.22 版本中成为默认配置,这将有助于用户在大规模网络环境下轻松使用 Istio。

参考

最后更新于 2024/10/08