Envoy 上游集群服务发现机制
服务发现定义
集群管理器配置上游集群时需要知道如何解析集群成员,相应的解析机制即为服务发现。
服务发现类型
Static
- 静态是最简单的服务发现类型。配置明确指定每个上游主机的解析网络名称(IP 地址/端口、unix 域套接字等)。
Strict DNS
- 当使用严格的 DNS 服务发现时,Envoy 会持续异步地解析指定的 DNS 目标。DNS 结果中返回的每个 IP 地址都将被视为上游集群中的显式主机。这意味着如果查询返回三个 IP 地址,Envoy 将假定集群有三个主机,并且所有三个主机都应该负载均衡。如果从结果中删除主机,Envoy 会假定它不再存在,并将从任何现有的连接池中耗尽流量。因此,如果成功的 DNS 解析返回 0 个主机,Envoy 将假定集群没有任何主机。请注意,Envoy 从不同步解析转发路径中的 DNS。以最终的一致性为代价,永远不用担心会阻塞长时间运行的 DNS 查询。
- 如果一个 DNS 名称多次解析到同一个 IP,这些 IP 将被重复数据删除。
- 如果多个 DNS 名称解析到同一个 IP,则不会共享运行状况检查。这意味着如果将主动健康检查与解析为相同 IP 的 DNS 名称一起使用,则应小心:如果 IP 在 DNS 名称之间重复多次,则可能会导致上游主机的过度负载。
- 如果启用了respect_dns_ttl,则使用 DNS 记录 TTL 和 dns_refresh_rate来控制 DNS 刷新率。对于严格的 DNS 集群,如果所有记录 TTL 的最小值为 0,则将使用dns_refresh_rate 作为集群的 DNS 刷新率。 如果未指定,dns_refresh_rate默认为 5000 毫秒。dns_failure_refresh_rate控制失败时 的刷新频率,如果没有配置,将使用 DNS 刷新率。
- DNS 解析会发出集群统计信息字段update_attempt、update_success和update_failure。
Logical DNS
- 逻辑 DNS 使用与严格 DNS 类似的异步解析机制。但是,逻辑 DNS 集群并没有严格采用 DNS 查询的结果并假设它们包含整个上游集群,而是仅使用需要启动新连接时返回的第一个 IP 地址。因此,单个逻辑连接池可能包含到各种不同上游主机的物理连接。连接永远不会耗尽,包括返回 0 个主机的成功 DNS 解析。
- 这种服务发现类型最适合必须通过 DNS 访问的大规模 Web 服务。此类服务通常使用循环 DNS 来返回许多不同的 IP 地址。通常,每个查询都会返回不同的结果。如果在这种情况下使用严格的 DNS,Envoy 会假设集群的成员在每个解析间隔内都在发生变化,这会导致连接池耗尽、连接循环等。相反,使用逻辑 DNS,连接会一直保持活动状态,直到它们被循环。在与大规模 Web 服务交互时,这是所有可能的世界中最好的:异步/最终一致的 DNS 解析、长期连接以及转发路径中的零阻塞。
- 如果启用了respect_dns_ttl,则使用 DNS 记录 TTL 和 dns_refresh_rate来控制 DNS 刷新率。对于逻辑DNS集群,如果第一条记录的TTL为0,则使用dns_refresh_rate 作为集群的DNS刷新率。 如果未指定,dns_refresh_rate默认为 5000 毫秒。dns_failure_refresh_rate控制失败时 的刷新频率,如果没有配置,将使用 DNS 刷新率。
- DNS 解析会发出集群统计信息字段update_attempt、update_success和update_failure。
Original destination
- 当传入连接通过 iptables REDIRECT 或 TPROXY 目标或使用代理协议重定向到 Envoy 时,可以使用原始目标集群。在这些情况下,路由到原始目标集群的请求被转发到由重定向元数据寻址的上游主机,而无需任何显式主机配置或上游主机发现。当上游主机的空闲时间超过 cleanup_interval(默认为 5000 毫秒)时,连接到上游主机的连接被池化,并且未使用的主机被刷新。如果原始目标地址不可用,则不打开上游连接。Envoy 还可以从HTTP 标头中获取原始目标。原始目标服务发现必须与原始目标负载均衡器一起使用.
Endpoint discovery service (EDS)
- 端点发现服务是基于 gRPC 或 REST-JSON API 服务器的 xDS 管理服务器,Envoy 使用它来获取集群成员。集群成员在 Envoy 术语中称为“端点”。对于每个集群,Envoy 从发现服务中获取端点。EDS 是首选的服务发现机制,原因如下:
-
Envoy 对每个上游主机都有明确的了解(相对于通过 DNS 解析的负载平衡器进行路由),并且可以做出更智能的负载平衡决策。
-
每个主机的发现 API 响应中携带的额外属性会告知 Envoy 主机的负载平衡权重、金丝雀状态、区域等。这些附加属性由 Envoy 网格在负载平衡、统计收集等期间全局使用。
-
Custom cluster
- Envoy 还支持自定义集群发现机制。自定义集群是使用 集群配置中的cluster_type 字段指定的。
- 通常主动健康检查与最终一致的服务发现服务数据结合使用,以做出负载平衡和路由决策。
最终一致的服务发现
Envoy的服务发现并未采用完全一致的机制,而是假设主机以最终一致的方式加入或离开网格,它结合主动健康状态检查机制来判定集群的健康状态;
-
健康与否的决策机制以完全分布式的方式进行,因此可以很好地应对网络分区
-
当为上游集群配置健康检查时,Envoy 使用 2x2 矩阵来确定是否路由到主机:
主机发现/健康检查OK
- Envoy将路由到目标主机。
主机缺席/健康检查正常:
- Envoy将路由到目标主机。这一点非常重要,因为设计假设发现服务随时可能失败。如果主机即使在发现数据中不存在后仍继续通过健康检查,Envoy 仍将路由。尽管在这种情况下无法添加新主机,但现有主机将继续正常运行。当发现服务再次正常运行时,数据最终会重新收敛。
主机发现/健康检查失败
- Envoy不会路由到目标主机。假设健康检查数据比发现数据更准确。
主机缺席/健康检查失败
Envoy不会路由,会删除目标主机。这是 Envoy 将清除主机数据的唯一状态。
参考文档
https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/service_discovery