09 Ads
Envoy 的强大功能之一是支持动态配置。到现在为止,我们一直在使用静态配置。我们使用 static_resources 字段将监听器、集群、路由和其他资源指定为静态资源。
当使用动态配置时,我们不需要重新启动 Envoy 进程就可以生效。相反,Envoy 通过从磁盘或网络上的文件读取配置,动态地重新加载配置。动态配置使用所谓的发现服务 API,指向配置的特定部分。这些 API 也被统称为 xDS。当使用 xDS 时,Envoy 调用外部基于 gRPC/REST 的配置供应商,这些供应商实现了发现服务 API 来检索配置。
外部基于 gRPC/REST 的配置提供者也被称为控制平面。当使用磁盘上的文件时,我们不需要控制平面。Envoy 提供了控制平面的 Golang 实现,但是 Java 和其他控制平面的实现也可以使用。
Envoy 内部有多个发现服务 API。所有这些在下表中都有描述。
| 发现服务名称 | 描述 |
|---|---|
| 监听器发现服务(LDS) | 使用 LDS,Envoy 可以在运行时发现监听器,包括所有的过滤器栈、HTTP 过滤器和对 RDS 的引用。 |
| 扩展配置发现服务(ECDS) | 使用 ECDS,Envoy 可以独立于监听器获取扩展配置(例如,HTTP 过滤器配置)。 |
| 路由发现服务(RDS) | 使用 RDS,Envoy 可以在运行时发现 HTTP 连接管理器过滤器的整个路由配置。与 EDS 和 CDS 相结合,我们可以实现复杂的路由拓扑结构。 |
| 虚拟主机发现服务(VHDS) | 使用 VHDS 允许 Envoy 从路由配置中单独请求虚拟主机。当路由配置中有大量的虚拟主机时,就可以使用这个功能。 |
| 宽泛路由发现服务(SRDS) | 使用 SRDS,我们可以把路由表分解成多个部分。当我们有大的路由表时,就可以使用这个 API。 |
| 集群发现服务(CDS) | 使用 CDS,Envoy 可以发现上游集群。Envoy 将通过排空和重新连接所有现有的连接池来优雅地添加、更新或删除集群。Envoy 在初始化时不必知道所有的集群,因为我们可以在以后使用 CDS 配置它们。 |
| 端点发现服务(EDS) | 使用 EDS,Envoy 可以发现上游集群的成员。 |
| 秘密发现服务(SDS) | 使用 SDS,Envoy 可以为其监听器发现秘密(证书和私钥,TLS 会话密钥),并为对等的证书验证逻辑进行配置。 |
| 运行时发现服务(RTDS) | 使用 RTDS,Envoy 可以动态地发现运行时层。 |
聚合发现服务(ADS)
表中的发现服务是独立的,有不同的 gRPC/REST 服务名称。使用聚合发现服务(ADS),我们可以使用一个单一的 gRPC 服务,在一个 gRPC 流中支持所有的资源类型(监听器、路由、集群…)。ADS 还能确保不同资源的更新顺序正确。请注意,ADS 只支持 gRPC。如果没有 ADS,我们就需要协调其他 gRPC 流来实现正确的更新顺序。
增量 gRPC xDS
每次我们发送资源更新时,我们必须包括所有的资源。例如,每次 RDS 更新必须包含每条路由。如果我们不包括一个路由,Envoy 会认为该路由已被删除。这样做更新会导致很高的带宽和计算成本,特别是当有大量的资源在网络上被发送时。Envoy 支持 xDS 的 delta 变体,我们可以只包括我们想添加 / 删除 / 更新的资源,以改善这种情况。
可用于bootstrap中的ADS最小化配置示例
node:
id: <node identifier>
dynamic_resources:
cds_config: {ads: {}}
lds_config: {ads: {}}
ads_config:
api_type: GRPC
grpc_services:
envoy_grpc:
cluster_name: ads_cluster
static_resources:
clusters:
- name: ads_cluster
connect_timeout: { seconds: 5 }
type: STATIC
hosts:
- socket_address:
address: <ADS management server IP address>
port_value: <ADS management server port>
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
upstream_connection_options:
# configure a TCP keep-alive to detect and reconnect to the admin
# server in the event of a TCP socket disconnection
tcp_keepalive:
...
admin:
...
Envoy有着较复杂的初始化流程,但大体上在任何侦听器开始侦听和接受新连接之前,都会进行如下初始化流程
- 启动期间,集群管理器会进行多阶段初始化,首先初始化静态/DNS集群,而后初始化EDS集群;接着,如果定义了CDS,会进行CDS初始化,等待一个响应(或失败),并对 CDS提供的集群进行相同次序的初始化;
- 若集群配置了主动健康状态检查,Envoy会进行一次有效的健康探测;
- 集群管理器初始化完成后,开始进行RDS和LDS初始化,并且在LDS/RDS请求至少有一个响应(或失败)之后,服务器才开始接受连接请求;
- 如果LDS本身返回需要RDS响应的侦听器,则Envoy会等待接收到RDS响应(或失败); 此过程称为侦听器预热;
- 完成前面的所有步骤之后,侦听器开始接受新连接;