尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Envoy xDS API 端点全解析:gRPC 流式、REST、ADS 聚合、Delta 增量与资源 TTL

Envoy xDS API 端点全解析:gRPC 流式、REST、ADS 聚合、Delta 增量与资源 TTL Envoy xDS API 端点全解析gRPC 流式、REST、ADS 聚合、Delta 增量与资源 TTL【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoyxDSDiscovery Service是 Envoy 数据面与控制面management server之间的核心通信协议。本文以 Envoy 官方配置文档 xDS API endpoints 为主线系统梳理 v3 传输 API 下的 gRPC 流式端点、REST 端点、聚合发现服务ADS、Delta 增量协议与 xDS 资源 TTL 机制并结合仓库中的 proto 定义与配置示例给出可直接落地的 Bootstrap 配置片段。读完本文你将能准确理解每个 xDS 端点的触发条件、消息模型与配置方式并在自己的控制面实现中正确对接这些端点。1. 认识 xDS 管理服务器与 v3 传输 APIxDS 是一组 API 的统称集群发现服务CDS、端点发现服务EDS、监听器发现服务LDS、路由发现服务RDS、作用域路由发现服务SRDS、密钥发现服务SDS、运行时发现服务RTDS等。一个 xDS 管理服务器control plane需要按需实现上述端点以支持 gRPC 和/或 REST-JSON 两种服务方式。无论是 gRPC 流式还是 REST-JSON 场景交互模型都是一致的Envoy 作为客户端发送 DiscoveryRequest管理服务器返回 DiscoveryResponse交互遵循 xDS 协议规范。从 discovery.proto 的源码可以看到DiscoveryRequest的核心字段字段作用version_info客户端最近一次成功处理的版本号首次请求为空每次响应处理完成后客户端用新版本或旧版本NACK来回执node发起请求的 Envoy 节点标识cluster、id 等resource_names要订阅的资源列表如集群名、路由配置名为空表示订阅该 API 的全部资源type_url请求的资源类型 URL在 ADS 多路复用场景下用于区分资源类型response_nonce对应被 ACK/NACK 的响应 nonceerror_detail上次响应应用失败时的错误详情NACK 时填充DiscoveryResponse则包含version_info、resourcesgoogle.protobuf.Any列表、type_url、nonce、canary与control_plane等字段。下文所有端点均基于这套消息模型只是服务路径与资源类型不同。2. gRPC 流式端点State of the World以下端点均为 gRPC 双向流式接口Stream*对应各自的 service proto。只要在 Bootstrap 配置的对应位置设置api_type: GRPC的api_config_sourceEnvoy 便会以客户端身份建立流订阅。2.1 CDS/envoy.service.cluster.v3.ClusterDiscoveryService/StreamClusters服务定义见 cds.proto。在 Bootstrap 的dynamic_resources.cds_config中配置后即会使用node: cluster: envoy_cluster id: envoy_node dynamic_resources: cds_config: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: xds_cluster完整示例可参考 dynamic-resources.yaml。注意xds_cluster必须作为静态集群存在指向管理服务器地址例如static_resources: clusters: - type: STRICT_DNS typed_extension_protocol_options: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: type: type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicit_http_config: http2_protocol_options: {} name: xds_cluster load_assignment: cluster_name: xds_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: my-control-plane port_value: 18000从 cds.proto 可见ClusterDiscoveryService同时声明了StreamClustersSotW 流式、DeltaClustersDelta 流式与FetchClustersREST三个 RPC这也印证了每种发现服务在三种传输模式下的对应关系。2.2 EDS/envoy.service.endpoint.v3.EndpointDiscoveryService/StreamEndpoints服务定义见 eds.proto。EDS 用于下发集群的端点负载均衡地址信息配置位于 Cluster 的eds_cluster_config字段eds_config: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: some_xds_cluster2.3 LDS/envoy.service.listener.v3.ListenerDiscoveryService/StreamListeners服务定义见 lds.proto。在 Bootstrap 的dynamic_resources.lds_config配置dynamic_resources: lds_config: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: xds_cluster2.4 RDS/envoy.service.route.v3.RouteDiscoveryService/StreamRoutes服务定义见 rds.proto。RDS 通常由 HTTP 连接管理器HCM按需触发配置位于 HttpConnectionManager 的rds字段route_config_name: some_route_name config_source: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: some_xds_clusterroute_config_name指定要订阅的路由配置资源名config_source指向提供 RDS 的管理服务器。2.5 SRDS/envoy.service.route.v3.ScopedRoutesDiscoveryService/StreamScopedRoutes服务定义见 srds.proto。SRDS 用于作用域路由scoped routes配合 HCM 的scoped_routes字段使用name: some_scoped_route_name scoped_rds: config_source: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: some_xds_cluster作用域路由允许按请求属性如来源 IP、Header动态切换路由配置SRDS 下发的正是作用域键 → 路由配置的映射关系。2.6 SDS/envoy.service.secret.v3.SecretDiscoveryService/StreamSecrets服务定义见 sds.proto。SDS 用于动态下发 TLS 证书、私钥等密钥材料配置内嵌于 SdsSecretConfig 消息中而该消息会被 CommonTlsContext 等 TLS 上下文引用。仓库中的 oauth-sds-example.yaml 给出了一个 OAuth2 过滤器通过 SDS 拉取token与hmac密钥的真实示例credentials: client_id: my-client-id token_secret: name: token sds_config: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: sds_server_uds hmac_secret: name: hmac sds_config: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: sds_server_uds在该示例中SDS 服务器通过 Unix domain socket/tmp/uds_path暴露服务对应的sds_server_uds集群使用管道地址pipe而非 IP 端口展示了 UDS 场景下的 xDS 集群配置方式。2.7 RTDS/envoy.service.runtime.v3.RuntimeDiscoveryService/StreamRuntime服务定义见 rtds.proto。RTDS 动态下发运行时覆盖层runtime layer配置位于 RuntimeLayer 的rtds_layer字段name: some_runtime_layer_name config_source: api_config_source: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: some_xds_clusterRTDS 非常适合与 xDS TTL 配合使用见第 6 节用于临时性的运行时配置变更。3. REST 端点除 gRPC 流式外Envoy 还支持 REST-JSON 方式的拉取式发现。REST 端点的路径由 proto 文件中的google.api.http注解声明见各 service proto 中Fetch*RPC 的option (google.api.http).post均为 HTTP POST。以下是 v3 下已确认存在的 REST 端点REST 端点对应服务 / proto触发配置POST /v3/discovery:clustersCDScds.protodynamic_resources.cds_configPOST /v3/discovery:endpointsEDSeds.protoCluster.eds_cluster_configPOST /v3/discovery:listenersLDSlds.protodynamic_resources.lds_configPOST /v3/discovery:routesRDSrds.protoHttpConnectionManager.rds以 CDS 为例将api_type改为REST并使用cluster_names列表指定管理服务器集群即可启用 REST 拉取cds_config: api_config_source: api_type: REST cluster_names: [some_xds_cluster]EDS、LDS、RDS 的 REST 配置结构完全相同api_type: RESTcluster_names。RDS 场景下配置位于 HCM 的rds字段route_config_name: some_route_name config_source: api_config_source: api_type: REST cluster_names: [some_xds_cluster]REST 端点的响应语义重要管理服务器响应这些端点时必须以 HTTP 200 状态码返回 DiscoveryResponse如果配置没有变化以 Envoy 客户端携带的version_info为准管理服务器可以返回空 body 与 HTTP 304 状态码从而节省不必要的传输开销。4. Aggregated Discovery ServiceADS聚合发现服务4.1 为什么需要 ADSEnvoy 本质上采用最终一致性模型而 ADS 的价值在于它让控制面可以对 API 更新推送进行排序并保证一个 Envoy 节点在 API 更新上只对单个管理服务器保持亲和。ADS 允许将一个或多个 API 及其资源在同一条双向 gRPC 流上由管理服务器下发。如果没有 ADS像 RDS 和 EDS 这样的 API 可能需要分别管理多条流、多个连接到不同管理服务器的连接。4.2 ADS 如何实现无中断hitless更新ADS 通过适当的排序实现配置的无中断更新。例如foo.com原本映射到集群X现在要把路由表改成指向集群Y。正确的推送顺序必须是先推送 CDS/EDS 更新其中同时包含集群X和Y再推送 RDS 更新将foo.com指向Y。没有 ADS 时CDS/EDS/RDS 可能指向不同的管理服务器即便在同一台管理服务器上也可能分属不同的 gRPC 流/连接需要跨流协调EDS 的资源请求甚至可能被拆到两条流上一条请求X、一条请求Y这要求分布式同步才能正确排序。而 ADS 将这些请求合并到单条流、单个管理服务器控制面只需在同一条流上依次下发 CDS、EDS、RDS 更新即可从根上规避了分布式同步问题。有关排序的完整约定make-before-break 模型CDS 最先、随后 EDS、LDS、RDS、VHDS最后移除不再引用的旧集群参见 xDS 协议文档 的相关章节。4.3 ADS 端点与配置ADS 仅支持 gRPC 流式不支持 REST端点定义为/envoy.service.discovery.v3.AggregatedDiscoveryService/StreamAggregatedResources服务定义见 ads.proto。ADS 通过DiscoveryRequest.type_url在同一条流上区分不同的资源类型CDS、EDS、LDS、RDS……每种type_url独立维护自己的请求/响应序列。在 Bootstrap 的dynamic_resources.ads_config中配置 ADS 通道dynamic_resources: ads_config: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: xds_cluster配置 ADS 之后前面 第 2 节 列出的任一配置源都可以改为走 ADS 通道。例如把 LDS 从独立 REST 通道lds_config: api_config_source: api_type: REST cluster_names: [some_xds_cluster]改为lds_config: {ads: {}}效果就是 LDS 流被定向到xds_cluster对应的共享 ADS 通道上与 CDS/EDS/RDS 等共用同一条流。完整可运行的 ADS Bootstrap 示例见 dynamic-resources.yaml其中ads_config与cds_config、lds_config并存xds_cluster静态指向my-control-plane:18000。5. Delta 端点增量 xDS5.1 为什么需要 DeltaREST、文件系统以及原始 gRPC xDS 实现的都是State of the WorldSotW全量更新每次 CDS 更新都必须包含全部集群某个集群没出现在更新里就意味着它已被删除。对于资源规模巨大、且存在持续少量变更的 Envoy 部署这种全量更新非常低效——仅仅改一个集群就要把十万个集群全部重发一遍。自Envoy 1.12.0起支持 Delta 变体包括 Delta ADS更新中只包含新增/变更/删除的资源。Delta xDS 是 gRPC 专属协议使用与 SotW 不同的消息类型DeltaDiscoveryRequest/DeltaDiscoveryResponse定义见 discovery.proto。5.2 Delta 的消息模型从 discovery.proto 源码可见 Delta 与 SotW 的关键差异DeltaDiscoveryRequest通过resource_names_subscribe/resource_names_unsubscribe动态增删订阅集合initial_resource_versions在流重连后的首条消息中上报客户端已持有的资源版本从而在同一逻辑会话内无缝续传DeltaDiscoveryResponse只携带变更的resources并通过removed_resources显式声明删除的资源Delta 采用资源级版本Resource.version而非全量响应的单一version_info每个响应必须携带nonce客户端用它配对 ACK/NACK。在源码层面每个 service 都提供了对应的Delta*RPC例如 cds.proto 中的DeltaClusters、lds.proto 中的DeltaListeners等端点路径格式为/envoy.service.type.v3.XxxDiscoveryService/DeltaXxx。5.3 如何启用 Delta启用方式很简单把 ApiConfigSource 的api_type字段设置为DELTA_GRPC。这对普通 xDS 与 ADS 都适用对于 ADS只需设置dynamic_resources.ads_config的api_typedynamic_resources: ads_config: api_type: DELTA_GRPC grpc_services: - envoy_grpc: cluster_name: xds_cluster概念上可以把 Delta 视为一种新的 xDS 传输类型现在共有 static静态、filesystem文件系统、REST、gRPC-SotW、gRPC-Delta 五种传输方式。Envoy 的 gRPC-SotW 与 Delta 客户端实现共享了大部分代码服务端也可以类似复用但两者在协议层互不兼容控制面实现时必须明确区分。Delta 协议的完整行为规范见 xDS 协议文档中的 Incremental xDS 章节。6. xDS TTL资源过期时间6.1 解决的问题某些场景下用户希望临时变更部分 xDS 资源例如通过 RTDS 临时覆盖某个运行时开关以注入故障。如果控制面失联、无法回滚这次变更Envoy 会一直保留临时配置这可能让系统长期处于错误的临时状态。xDS TTL 解决了这个问题管理服务器为资源指定 TTL一旦 TTL 到期Envoy 会删除该资源即使控制面已经不可用。6.2 行为与适用场景需要特别注意TTL 到期后资源是被删除而不是回滚到之前的版本。因此 TTL 主要适用于资源缺失比临时版本更可接受的场景例如通过 RTDS 应用临时运行时覆盖到期后自动移除覆盖、恢复默认值故障注入测试控制面崩溃时自动终止故障注入避免 Envoy 长期停留在故障注入状态。6.3 如何在协议中指定 TTLTTL 定义在 Resource 消息的ttl字段google.protobuf.Duration。从 discovery.proto 源码可以看到其语义每个资源独立启动一个计时器收到带新 TTL 的资源时计时器重置收到不带 TTL 的资源时计时器被移除即取消过期计时器到期后该资源配置被删除。协议层面Delta xDS直接在响应的Resource消息中携带ttlSotW xDS管理服务器可以把响应中的单个资源包裹进Resource消息来指定 TTL该能力由xds.config.supports-resource-in-sotw客户端特性门控。6.4 TTL 的刷新与心跳管理服务器可以通过对同一版本再次下发响应来刷新或修改 TTL此时资源本体不必包含在响应中resource字段可留空仅提供匹配最新版本的version这就是轻量级的心跳heartbeat更新——响应只更新 TTL不视为资源内容变更。详细的 TTL 协议语义参见 xDS 协议文档的 TTL 章节。7. 总结与实践建议传输形态选择gRPC 流式SotW支持完整订阅与 ADS 聚合适合生产控制面REST 适合轻量、低频的拉取场景Delta 适合资源规模大、变更频繁的部署且支持按需订阅控制面实现要点gRPC 端点路径与 service 定义一一对应REST 端点路径由google.api.http注解决定/v3/discovery:*REST 响应必须遵守 HTTP 200 DiscoveryResponse、未变更时 HTTP 304 空 body 的约定更新排序要实现无中断更新遵循CDS → EDS → LDS → RDS/VHDS → 清理旧资源的推送顺序ADS 是保证单流排序的最简方案安全兜底需要临时变更配置时善用 xDS TTL并理解其到期删除而非回滚的语义边界。所有端点的消息类型、字段语义与变更历史均可从 discovery.proto 及各类 service protocds.proto、eds.proto、lds.proto、rds.proto、srds.proto、sds.proto、rtds.proto、ads.proto中直接查阅配合 dynamic-resources.yaml 与 oauth-sds-example.yaml 两份示例即可快速搭建自己的控制面与 Envoy 动态配置链路。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表