十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Envoy xDS API 与协议全解析:v3 版本支持、四种传输变体、ACK/NACK 与客户端特性

Envoy xDS API 与协议全解析:v3 版本支持、四种传输变体、ACK/NACK 与客户端特性 Envoy xDS API 与协议全解析v3 版本支持、四种传输变体、ACK/NACK 与客户端特性【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy本篇技术指南以 Envoy 官方 API 文档区api.rst 及其下 api_supported_versions.rst、v3 API 参考、xDS REST/gRPC 协议、客户端特性为核心骨架系统讲解 Envoy 动态配置体系 xDS 的版本演进、订阅方式、四种传输协议变体、ACK/NACK 确认机制、资源预热与最终一致性等关键机制并结合仓库中的 proto 定义与官方配置示例discovery.proto、ads.yaml给出底层实现佐证。读完本文你将掌握 xDS 协议在 Envoy 中的完整工作方式能够正确选择 SotW / Delta / ADS 变体并理解管理面control plane需要遵循的交互约定。API 区块导读Envoy 的 API 文档区以docs/root/api/api.rst为入口通过 toctree 组织四块内容支持的 API 版本Supported API versions、v3 API 完整参考v3 API reference、xDS REST 与 gRPC 协议细节xDS REST and gRPC protocol、以及知名客户端特性Well Known Client Features。这四个子文档共同构成了理解 Envoy 动态配置xDS从版本选型 → 消息定义 → 线上协议交互 → 客户端能力声明全链条的权威资料。下文按这一脉络展开并在关键节点引用仓库内源码与示例配置进行印证。支持的 API 版本Envoy 的 API 遵循仓库内的 API 版本化方案当前只支持一个主版本v3 xDS API活跃状态根据 API_VERSIONING.md 的 API 生命周期章节v3 xDS 是最终主版本将永久获得支持。官方明确表示由于 Envoy 与整个 xDS 生态gRPC 等使用面太广主版本号升级已不再现实因此 v3 即为终点未来只会有字段级弃用deprecation提示但任何字段都不会被移除Envoy 也不会移除任何已弃用字段的实现。以下版本已不再被 Envoy 支持v1 xDS API早于 Protobuf 时代的遗留 REST-JSON API是当前 Protobuf 与 REST/gRPC 双通道 xDS API 的前身。v2 xDS API于 2021 年第一季度Q1 2021移除支持。版本化机制要点依据 api/API_VERSIONING.md理解v3的确切含义需要把握以下细节Envoy API 是一族独立版本化的包package例如envoy.admin.v3alpha、envoy.service.trace.v3采用基于 protobuf 的语义化版本方案主版本号写在包名与目录结构中如 v3 的 trace 包为envoy.service.trace.v3proto 位于api/envoy/service/trace/v3且不允许出现envoy.service.trace.v3.somethingelse这类子包。所谓vN xDS API实际指的是根配置资源bootstrap、xDS 资源如 Cluster所处的版本 N。v3 API 的 bootstrap 配置即为envoy.config.bootstrap.v3.Bootstrap整个 Envoy API 本质上是版本化包命名空间构成的有向无环图DAG。在包的主版本内不允许任何破坏性变更字段不可重编号、不可改类型、不可重命名字段重命名会破坏 YAML/JSON 与 text proto 的加载而 YAML/JSON 被视为一等输入单例字段升级为 repeated、将字段包进 oneof、收紧 protoc-gen-validate 注解等通常proto 安全的操作在 Envoy 中被视为破坏性变更。例外情况字段或消息引入 14 天内且未随 Envoy 发布、vNalpha版本内、以及标记了work_in_progress注解的 proto。新功能通常只加入当前稳定主版本vNalpha可由vN机械生成不要求开发者双处维护。v3 API 参考全貌v3 API 参考文档docs/root/api-v3/api.rst是完整 API 的目录入口覆盖十大类消息族bootstrap / listeners / clusters / http_routes / config / admin / data / service / common_messages含 common_messages_xds/ types对应到仓库中这些 proto 实际位于api/envoy/下的config/、service/、type/、data/、admin/等目录如envoy.config.bootstrap.v3.Bootstrap、envoy.config.listener.v3.Listener、envoy.config.cluster.v3.Cluster、envoy.config.route.v3.RouteConfiguration、envoy.config.endpoint.v3.ClusterLoadAssignment等读者可结合 api/envoy/config 目录逐一定位具体消息定义。xDS 协议核心概念Envoy 通过文件系统或一个或多个管理服务器management server发现各类动态资源这些发现服务及其对应 API 被统称为xDS。资源通过订阅subscriptions来请求方式有三种监视指定文件系统路径、发起 gRPC 流、轮询 REST-JSON URL。后两种方式需要携带 DiscoveryRequest 消息负载所有方式的资源投递均使用 DiscoveryResponse 消息负载。资源类型Resource Types每种 xDS 配置资源都有其类型资源类型独立于下文所述传输方式进行版本化。v3 支持的资源类型如下资源类型说明envoy.config.listener.v3.Listener监听器envoy.config.route.v3.RouteConfiguration路由配置envoy.config.route.v3.ScopedRouteConfiguration带作用域的路由配置envoy.config.route.v3.VirtualHost虚拟主机envoy.config.cluster.v3.Cluster集群envoy.config.endpoint.v3.ClusterLoadAssignment集群端点分配EDS 资源envoy.extensions.transport_sockets.tls.v3.SecretTLS 密钥envoy.service.runtime.v3.Runtime运行时配置资源通过type URL在请求/响应中标识形如type.googleapis.com/resource type例如 Cluster 资源的 type URL 为type.googleapis.com/envoy.config.cluster.v3.Cluster。protoc-gen-validatePGV注解各 xDS 资源类型的 protobuf 消息带有 protoc-gen-validatePGV注解用于描述客户端收到资源时应执行的语义约束。需要特别注意的是客户端并非必须使用 PGV 注解做校验例如 Envoy 会做校验但 gRPC 不做PGV 注解也不是客户端应执行校验的穷尽清单。控制面control plane和 xDS 代理通常不应直接依赖 PGV 注解尽管有些控制面会提前用其拦截非法配置。因为 PGV 注解会随 API 演进且收紧 PGV 注解不视为 API 破坏性变更——控制面无法假定所有客户端编译时使用了与其相同版本的 xDS proto从而可能出现服务器拒绝而客户端本可接受的配置。三种订阅方式详解1. 文件系统订阅Filesystem subscriptions最简的动态配置投递方式把配置放在 ConfigSource 指定的已知路径Envoy 使用inotifymacOS 上为kqueue监视文件变更并在更新时解析文件中的 DiscoveryResponse。支持二进制 protobuf、JSON、YAML、proto text四种格式。文件系统订阅没有 ACK/NACK 机制只能依靠统计计数器和日志观察若某次配置更新被拒绝最后一个有效配置会继续生效。2. 流式 gRPC 订阅Streaming gRPC subscriptionsAPI 流程典型 HTTP 路由场景下客户端配置的核心资源类型是Listener、RouteConfiguration、Cluster、ClusterLoadAssignment依赖关系呈树状每个Listener可指向一个RouteConfiguration路由可指向一个或多个Cluster每个Cluster可指向一个ClusterLoadAssignment。Envoy代理启动时抓取全部Listener和Cluster资源再按需抓取这些资源所引用的RouteConfiguration与ClusterLoadAssignment。换言之每个Listener或Cluster都是 Envoy 配置树的一个根。gRPC 等非代理客户端可以只抓取自己关心的Listener再逐级抓取路由、集群、端点资源——最初的Listener是客户端配置树的根。传输协议变体四个维度组合出的四种形态xDS 流式 gRPC 传输协议有两个独立维度维度一State of the WorldSotWvs. 增量incrementalSotW 是 xDS 最初的机制客户端每次请求必须列出全部感兴趣的资源名对 LDS/CDS服务器每次必须返回客户端订阅的全部资源。例如已订阅 99 个资源、想新增 1 个就必须发送含全部 100 个资源名的请求服务器也要重新返回全部 100 个。这一机制存在可扩展性瓶颈因此引入了增量变体。增量变体允许双方只表达相对上一次状态的差值delta客户端只增删订阅的资源名服务器只发送发生变化的资源并提供资源懒加载on-demand机制。维度二每种资源类型独立 gRPC 流 vs. 全部资源类型聚合在单一 gRPC 流上独立流是原始机制提供最终一致性模型聚合流ADS为需要显式控制更新顺序的环境而生。由此组合出四种传输变体State of the WorldBasic xDSSotW 每种资源类型独立流Incremental xDSDelta xDS增量 每种资源类型独立流Aggregated Discovery ServiceADSSotW 全资源类型聚合流Incremental ADS增量 全资源类型聚合流各变体的 RPC 服务与方法非聚合变体下每种资源类型有独立的 RPC 服务且同时提供 SotW 与增量两种方法资源类型发现服务SotW 方法增量方法ListenerLDSListener Discovery ServiceListenerDiscoveryService.StreamListenersListenerDiscoveryService.DeltaListenersRouteConfigurationRDSRoute Discovery ServiceRouteDiscoveryService.StreamRoutesRouteDiscoveryService.DeltaRoutesScopedRouteConfigurationSRDSScoped Route Discovery ServiceScopedRouteDiscoveryService.StreamScopedRoutesScopedRouteDiscoveryService.DeltaScopedRoutesVirtualHostVHDSVirtual Host Discovery Service无VirtualHostDiscoveryService.DeltaVirtualHostsClusterCDSCluster Discovery ServiceClusterDiscoveryService.StreamClustersClusterDiscoveryService.DeltaClustersClusterLoadAssignmentEDSEndpoint Discovery ServiceEndpointDiscoveryService.StreamEndpointsEndpointDiscoveryService.DeltaEndpointsSecretSDSSecret Discovery ServiceSecretDiscoveryService.StreamSecretsSecretDiscoveryService.DeltaSecretsRuntimeRTDSRuntime Discovery ServiceRuntimeDiscoveryService.StreamRuntimeRuntimeDiscoveryService.DeltaRuntime聚合变体ADS / Incremental ADS将所有资源类型复用在同一 gRPC 流上每种资源类型在聚合流内视为一个独立逻辑子流服务与方法为SotWAggregatedDiscoveryService.StreamAggregatedResources增量AggregatedDiscoveryService.DeltaAggregatedResources所有 SotW 方法的请求/响应类型为 DiscoveryRequest / DiscoveryResponse所有增量方法使用 DeltaDiscoveryRequest / DeltaDiscoveryResponse。如何配置选用哪种变体xDS API 中ConfigSource 消息说明如何获取特定类型的资源若 ConfigSource 内含 gRPC ApiConfigSource则指向管理服务器的上游集群每种 xDS 资源类型会建立一条独立的双向 gRPC 流可指向不同的管理服务器。若 ConfigSource 内含 AggregatedConfigSource则指示客户端使用 ADS。通常客户端需要一份本地配置告知如何获取 Listener 与 Cluster 资源Listener 资源内部可携带 ConfigSource 说明 RouteConfiguration 如何获取Cluster 资源内部可携带 ConfigSource 说明 ClusterLoadAssignment 如何获取。Envoy 客户端配置bootstrap 文件中含两个 ConfigSource分别说明 Listener、Cluster 资源的获取方式另含一个独立的 ApiConfigSource 说明如何连接 ADS 服务器——只要任何 ConfigSourcebootstrap 中的或管理服务器下发的 Listener/Cluster 中的包含 AggregatedConfigSource 消息就会走这个 ADS 配置。一个已知限制bootstrap 的static_resources中任何被其他静态集群依赖的 xDS 集群必须排在最前面否则 Envoy 初始化会变慢。例如某个集群依赖 xDS 集群做 SDS 来配置传输套接字密钥则该 xDS 集群必须先于使用该密钥的集群声明。gRPC 客户端使用 xDS 的 gRPC 客户端只支持 ADSbootstrap 中含 ADS 服务器名称所有资源都通过它获取Listener/Cluster 中的 ConfigSource 必须包含 AggregatedConfigSource。xDS 传输协议The xDS transport Protocol传输 API 版本除资源类型版本外xDS 线缆协议还有自己的传输版本为 DiscoveryRequest / DiscoveryResponse 这类消息提供类型版本化并且编码在 gRPC 方法名中——服务器仅凭客户端调用哪个方法即可判断其协议版本。基本协议流程每条 xDS 流以客户端发出的 DiscoveryRequest 开始包含订阅资源列表、订阅资源对应的 type URL、节点标识node identifier、可选的资源类型实例版本客户端已见过的最新版本。服务器随后发送 DiscoveryResponse内含自客户端上次指示的实例版本以来发生变化的已订阅资源此后订阅资源发生变化时服务器可随时追加响应。客户端每次收到新响应后会再发一个请求说明响应中的单个资源孤立地看是否有效即 ACK/NACK。所有服务器响应都带nonce字段客户端后续请求必须将response_nonce设为同一条流上最近收到的 nonce用于让服务器把请求与特定响应关联规避 SotW 变体中的竞态。nonce 只在单条 xDS 流上下文内有效流重启即失效聚合变体中 nonce 按资源类型分别跟踪。只有流上的第一个请求保证携带节点标识后续请求可带空 node若携带则必须与首次一致因此检查第一个消息的 node 即可。在 discovery.proto 中可以看到这些字段的实际定义DiscoveryRequest含version_infoL68、resource_namesL79、type_urlL97、response_nonceL107、error_detailL113DiscoveryResponse含version_infoL121、type_urlL148、nonceL158。ACK/NACK 与资源类型实例版本每种 xDS 资源类型都有一个版本字符串只要该类型的任一资源发生变化版本就更新。服务器在 DiscoveryResponse 的version_info中给出该类型当前版本客户端随后在请求的version_info中回传自己看到的最近有效版本服务器据此判断何时发送了客户端认为无效的版本。增量变体中该信息由服务器在 DeltaDiscoveryResponse 的system_version_info字段发送但客户端并不用其表达资源有效性——增量 API 有独立机制。资源类型实例版本按资源类型独立聚合变体下同一条流上的每种类型各有版本也按 xDS 服务器独立以唯一 ConfigSource 标识。版本属于资源本身而非某条流流断开重连后新流上的首个请求应携带旧流上见过的最新版本服务器可据此不重发客户端已见过的资源仅在能确定客户端订阅集合不变的场景下安全例如 LDS/CDS 的通配订阅。一个 EDS 请求示例YAML 形式即 DiscoveryRequest 的字段结构version_info: node: { id: envoy } resource_names: - foo - bar type_url: type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment response_nonce:管理服务器可能立即回复也可能等到请求的资源就绪后再回复 DiscoveryResponse例如version_info: X resources: - foo ClusterLoadAssignment proto encoding - bar ClusterLoadAssignment proto encoding type_url: type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment nonce: A处理完该响应后Envoy 会在流上发送新请求携带最后一次成功应用的版本与服务器给出的 nonce——版本为 Envoy 和管理服务器提供了当前已应用配置的共同认知也即 ACK/NACK 机制。ACK如果更新中所有资源均有效则version_info为X。注意 ACK 只表示客户端认为响应中每个资源孤立地看是有效的不代表配置已成功应用——客户端发出 ACK 后仍可能应用失败。NACK如果发现更新X中有资源无效客户端会回复填充了error_detail且携带上一个版本的请求上例中为空初始版本。NACK 并不表示所有资源都被拒绝——error_detail的 message 字段含具体错误信息。时序图中消息简写约定为DiscoveryRequest(Vversion_info, Rresource_names, Nresponse_nonce, Ttype_url)DiscoveryResponse(Vversion_info, Rresources, Nnonce, Ttype_url)。NACK 之后API 更新可能在新的版本Y上成功。服务器检测 NACK 的推荐方式是查看请求中是否存在error_detail字段较老的服务器会同时比对版本与 nonce版本与 nonce 对应服务器响应不一致即视为拒绝但该方法对 LDS/CDS 之外的 API 不适用客户端可能动态改变订阅集合除非服务器保证每次任一客户端新订阅资源时都递增资源类型实例版本。ACK/NACK 语义总结xDS 客户端应对管理服务器发来的每个 DiscoveryResponse 做出 ACK 或 NACKresponse_nonce告诉服务器该 ACK/NACK 对应哪个响应。ACK 表示单个资源有效且客户端意图应用它们但不代表应用成功包含来自 DiscoveryResponse 的version_info。NACK 表示响应中至少一个资源被认为无效以error_detail字段存在为标志version_info表示客户端正在使用的最新版本在客户端从既有版本新订阅了一个无效资源的场景下该版本可能并不比新版本更旧。何时发送更新管理服务器只在 DiscoveryResponse 中的资源发生变化时才应发送更新。Envoy 对每个 DiscoveryResponse 都会在接收接受或拒绝后立即回 ACK/NACK 请求若服务器不等待变化而重复下发相同资源集会造成双方无谓工作甚至带来严重性能影响。流内同资源类型的新 DiscoveryRequest 会取代先前所有同类型请求——服务器只需响应每条流上每个资源类型的最新请求且 Envoy 并不期待每个请求都有对应响应。客户端如何指定需要返回的资源资源提示SotW 变体通过 DiscoveryRequest 的resource_names字段给出感兴趣的资源名集合增量变体通过 DeltaDiscoveryRequest 的resource_names_subscribe/resource_names_unsubscribe字段。常规情况下请求必须指明资源名集合服务器必须提供存在且被请求的资源客户端会静默忽略未被显式请求的多余资源。当请求改变资源集合时服务器必须重发新请求的资源即使此前未请求时就发过且未变化。资源名列表为空表示客户端对该类型不再感兴趣。通配订阅wildcardListener 与 Cluster 资源类型支持订阅特殊名称*此时服务器应依据站点业务逻辑通常基于客户端的 node 标识决定客户端的完整资源集合。历史遗留语义若客户端对某资源类型从未显式订阅过任何资源名SotW 中该类型所有请求的resource_names均为空增量中从未用非空resource_names_subscribe发过请求服务器应将其视同订阅*但一旦客户端显式订阅过某个名字*或其它该遗留语义即失效此后清空订阅列表被解释为退订。SotW 下举例resource_names未设置 → 服务器解释为订阅*resource_names为*和A→ 继续订阅*并新增订阅Aresource_names为A→ 退订*继续订阅Aresource_names未设置第二次 → 退订A已全部退订。该请求与第一个相同但因该流上该类型此前设置过resource_names不再被解释为通配订阅。增量下对应resource_names_subscribe未设置 → 订阅*置A→ 继续*并新增Aresource_names_unsubscribe置*→ 退订*继续Aresource_names_unsubscribe置A→ 退订A集合再次为空但同样不再解释为通配订阅。客户端行为Envoy 对 Listener 与 Cluster 资源始终使用通配订阅而 gRPC 等其它 xDS 客户端可能显式订阅具体资源名例如它只有单一监听器且通过带外配置已知其名字。资源如何分组进响应增量变体中服务器每个资源单独一个响应已发过 100 个资源、只有 1 个变化时只需发送那 1 个客户端不得删除未变化的资源。SotW 变体中除 Listener/Cluster 外的资源类型与增量一致但Listener 与 Cluster 必须是完整的世界状态——即使只有 1 个资源变化也必须重发全部 100 个。所有变体都以整条命名资源为单位操作不存在对命名资源内 repeated 字段做增量更新的机制最典型的是目前无法对 EDS 响应中的单个端点做增量更新。重复资源名服务器在单个响应中包含同一资源名两次是错误行为客户端应 NACK 这类响应。删除资源增量变体服务器通过 DeltaDiscoveryResponse 的removed_resources字段对应 proto 中 L311另有removed_resource_names于 L316指示客户端删除资源。SotW 变体Listener/Cluster 类型中新响应里缺失的既有资源即表示已被删除客户端必须删除空响应表示删除该类型全部资源。其它资源类型没有显式删除机制——删除通过父资源不再引用子资源来隐式表达例如 LDS 更新移除某 Listener 后若没有其它 Listener 再指向 RouteConfiguration A客户端可删除 A。对这些类型而言空 DiscoveryResponse 从客户端视角是 no-op。判断请求的资源不存在SotW 变体没有任何显式机制判断请求的资源不存在LDS/CDS 响应必须包含全部请求资源但由于更新是最终一致的客户端无法仅凭资源缺席就断定其不存在响应可能是基于先前的旧请求生成的。其它资源类型由于每个资源独立成包下个响应可能是无关的更新同样无从判断。因此客户端应在发送新资源请求后使用超时推荐 15 秒判定资源不存在Envoy 在 RouteConfiguration 与 ClusterLoadAssignment 的资源预热 阶段就是这么做的。同时即使请求时资源不存在它也可能在任意时刻被创建——管理服务器必须记住客户端的请求集合并在资源诞生后主动推送更新。退订资源增量变体通过resource_names_unsubscribe退订。SotW 变体每次请求必须携带完整订阅列表退订某资源即发送不包含它的新请求例如从订阅A、B退订B需发送仅含A的请求。使用通配订阅的 Listener/Cluster订阅集合由服务器决定客户端无法单独退订其中某个资源只能整体退订通配符。单条流上请求多个资源对 EDS/RDSEnvoy 既可以为每个资源生成独立流例如每个 ConfigSource 都有独立的管理服务器上游集群也可以在目标为同一管理服务器时把多个资源请求合并到一条流。两种方式对服务器都合法——服务器应能处理每个请求中一个或多个resource_names。下图分别为同一流上请求两个 EDS 资源{foo, bar}、以及两条独立流各请求一个资源。资源更新与 nonce 竞态Envoy 除了在 ACK/NACK 每个 DiscoveryResponse 时更新resource_names外还可能在某个version_info下额外发出 DiscoveryRequest 以更新资源提示。例如 Envoy 处于 EDS 版本X且只知道集群foo随后收到 CDS 更新得知bar它可能会发一个X版本、resource_names为{foo,bar}的额外请求。这里存在竞态若 Envoy 在X发出资源提示更新、管理服务器在处理前已回复新版本Y则该提示更新可能因携带X版本而被误判为对Y的拒绝。为此服务器用 nonce 标明每个 DiscoveryResponse 对应的请求。服务器不应对携带过期 nonce 的 DiscoveryRequest 发送响应nonce 在服务器向 Envoy 呈现更新 nonce 后即过期服务器无需在确定新版本就绪前发送更新先前版本的请求也随之过期同一版本上可处理多个 DiscoveryRequest。资源预热Resource warmingCluster 与 Listener 在能提供服务前要经历预热warming该过程既发生在 Envoy 初始化期间也发生在 Cluster/Listener 被更新时Cluster 的预热只有在管理服务器提供了 ClusterLoadAssignment 响应后才算完成即使端点没有变化也要求提供新的 ClusterLoadAssignment 响应预热超时后 Envoy 会使用缓存的 ClusterLoadAssignment。Listener 的预热在其引用了 RDS 配置时只有拿到 RouteConfiguration 后才完成但若管理服务器不发送 RouteConfiguration 响应Listener 仍可完成预热——Envoy 会使用之前发送过的 RouteConfiguration管理服务器只需在路由发生变化或从未发送过时下发。管理服务器被期望在预热期间提供 EDS/RDS 更新。若预热阶段拿不到 EDS/RDS 响应Envoy 在初始化阶段将无法完成初始化通过 CDS/LDS 发送的更新也不会生效直到 EDS/RDS 响应到达。最终一致性考量xDS API 是最终一致的更新期间可能出现短暂流量中断。例如仅通过 CDS/EDS 知道集群X一条 RouteConfiguration 引用X并在 CDS/EDS 提供Y之前被调整为引用Y则流量会被黑洞直到 Envoy 得知Y。若应用能容忍短暂流量中断客户端重试或其它 Envoy sidecar 可掩盖可直接推送更新。若不能容忍应先提供同时包含X和Y的 CDS/EDS 更新再做 RDS 更新把路由从X指向Y最后做移除X的 CDS/EDS 更新。一般原则是遵循make before break先建后断的更新顺序CDS 更新若有必须最先推送EDS 更新必须晚于对应集群的 CDS 更新到达LDS 更新必须晚于对应 CDS/EDS 更新与新增监听器相关的 RDS 更新必须晚于 CDS/EDS/LDS 更新与新增 RouteConfiguration 相关的 VHDS 更新若有必须晚于 RDS 更新之后才可移除陈旧的 CDS 集群及其 EDS 端点不再被引用的。注意LDS 更新后监听器在接收流量前会先预热若配置了 RDS 会先拉取路由Cluster 在增删改时会预热但路由不预热——管理面必须在推送路由更新前确保其引用的集群已就位。TTL资源过期默认情况下管理服务器不可达时 Envoy 会保留最后已知配置直到连接恢复但某些场景如故障注入服务不希望如此。TTL 设置允许 Envoy 在失去与管理服务器联系一段时间后移除一组资源例如管理服务器不可达时终止故障注入测试。支持xds.config.supports-resource-ttl客户端特性的客户端可在每个 Resourceproto 中Resource消息的ttl字段位于 L434上指定 TTL 字段每个资源有各自的过期时间。更新 TTL 的方式是服务器用新 TTL 重发该资源移除 TTL 则是重发资源但 TTL 字段不设置。心跳heartbeat为支持轻量级 TTL 刷新服务器可发送一个resource未设置、版本与最近发送版本一致的 Resource 来仅更新 TTL——这类资源不被视为资源更新。SotW 下的 TTL需要把相关资源包装进 Resource 消息从而复用 Delta xDS 的 TTL 字段而不改变 SotW API心跳同样支持。该能力由xds.config.resource-in-sotw客户端特性门控。ADSAggregated Discovery Service当管理服务器分布式部署时要满足上述防流量中断的顺序保证很困难。ADS 允许单个管理服务器、通过单条 gRPC 流投递所有 API 更新从而精心编排更新顺序。ADS 中一条流内通过 type URL 多路复用多条独立的 DiscoveryRequest/DiscoveryResponse 序列对任意给定 type URL上述请求/响应顺序语义仍然适用。每个 Envoy 实例只有一条 ADS 流。官方最小 ADS 配置bootstrap.yaml 片段来源 docs/root/_include/ads.yamlnode: # set cluster identifier cluster: envoy_cluster # set node identifier id: envoy_node dynamic_resources: ads_config: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: ads_cluster cds_config: ads: {} lds_config: ads: {} static_resources: clusters: - name: ads_cluster type: STRICT_DNS load_assignment: cluster_name: ads_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: # set ADS management server address address: my-control-plane # set ADS management server port port_value: 777 # It is recommended to configure either HTTP/2 or TCP keepalives in order to detect # connection issues, and allow Envoy to reconnect. TCP keepalive is less expensive, but # may be inadequate if there is a TCP proxy between Envoy and the management server. # HTTP/2 keepalive is slightly more expensive, but may detect issues through more types # of intermediate proxies. 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: connection_keepalive: interval: 30s timeout: 5s upstream_connection_options: tcp_keepalive: {}要点dynamic_resources.ads_config指定 ADS 服务器这里指向静态集群ads_clustercds_config/lds_config均声明ads: {}ads_cluster本身作为静态集群预先定义并建议配置 HTTP/2 或 TCP keepalive 以便及时发现连接问题并让 Envoy 重连。增量 xDSIncremental xDS / Delta xDS增量 xDS 是独立的 xDS 端点价值有二线上以资源/资源名差值通信Delta xDS支持 xDS 资源的可扩展性目标——100k 个集群中只修改 1 个时服务器只需投递被修改的那 1 个集群而非全部。允许 Envoy 按需/懒加载资源例如只在请求到达时才请求相应集群。增量 xDS 会话总在 gRPC 双向流上下文中进行服务器可跟踪连接客户端的状态目前没有 REST 版本。Delta 线缆协议中 nonce 字段是必需的用于将 DeltaDiscoveryResponse 与 DeltaDiscoveryRequest 的 ACK/NACK 配对响应级system_version_info仅用于调试。DeltaDiscoveryRequest 可发送的场景xDS 双向流中的首条消息对先前 DeltaDiscoveryResponse 的 ACK/NACKresponse_nonce设为响应中的 nonce以error_detail是否存在区分 ACK/NACK客户端自发请求动态增删跟踪的资源名集合此时必须省略response_nonce。即使请求上设置了response_nonce服务器必须尊重订阅状态的变化nonce 可能过期nonce 仅用于关联 ACK/NACK不应用来拒绝过期请求。此外即使服务器认为客户端已订阅且持有最新版本客户端resource_names_subscribe中的名字服务器仍必须提供资源客户端可能因实现细节忘记了资源。重连重连时增量客户端可把已知资源版本填入initial_resource_versions对应 proto 中 L277告知服务器避免重新传输因为旧流状态不保留重连客户端必须提供全部感兴趣的资源名。通配订阅的请求必须在resource_names_subscribe中显式给出*或按遗留行为subscribe/unsubscribe 均为空。资源名与别名资源由资源名或别名标识DeltaDiscoveryResponse 的资源中 alias 字段标识别名name 字段返回资源名。订阅时resource_names_subscribe可填别名或名字服务器需同时检查名字与别名判断是否已订阅。退订通过resource_names_unsubscribe可填别名或名字。字段中可能包含服务器认为客户端本就没订阅的多余名字——服务器应干净地忽略这些幻影退订。一般情况下仅退订不改变其它内容的请求无需响应例外当客户端同时有通配订阅*和某个具体资源名订阅时由于该具体名字可能同时被通配覆盖客户端无法自行判断是否继续缓存——服务器必须响应将该资源放入removed_resources不在通配内或resources在通配内。判断资源不存在增量变体中客户端订阅的资源不存在时服务器会在removed_resources字段中发送该资源名——客户端可据此快速判断而无需像 SotW 那样等超时不过仍建议客户端保留超时保护以防管理服务器迟迟不响应。3. REST-JSON 轮询订阅xDS 单例 API 也支持通过 REST 端点的同步长轮询。消息时序与上述类似但不维持到管理服务器的持久流任何时刻只允许一个未完成的请求因此 REST-JSON 中响应 nonce 是可选的。DiscoveryRequest/DiscoveryResponse 使用proto3 的 JSON 规范转换JSON canonical transform编码。REST-JSON 轮询不支持 ADS。当轮询周期设得很小意图做长轮询时还必须避免在底层资源未发生变化时发送 DiscoveryResponse。知名客户端特性Well Known Client Features客户端通过 node 的client_features字段对应envoy.config.core.v3.Node.client_features声明支持的特性列表使用反向 DNS 命名如com.acme.feature。目前定义的特性如下envoy.config.require-any-fields-contain-struct要求google.protobuf.Any类型的配置项只包含xds.type.v3.TypedStruct或历史原因下的udpa.type.v1.TypedStruct消息。envoy.lb.does_not_support_overprovisioning客户端不支持按 ClusterLoadAssignment.Policy.overprovisioning_factor 字段配置的优先级故障转移与 locality 加权的超量供应overprovisioning如需优雅故障转移功能须由管理服务器提供。envoy.lrs.supports_send_all_clusters客户端支持 LRSLoad Reporting Service响应中的LoadStatsResponse.send_all_clusters字段。xds.config.supports-resource-ttl客户端支持按资源或按 SotW 的 TTL。xds.config.resource-in-sotw客户端能够在 SotW DiscoveryResponse 中解包 Resource 包装器即支持把资源包装进 Resource 消息以复用 TTL 字段。之所以需要这些显式声明是因为存在无法仅靠 protobuf 语义表达的客户端能力差异依据 api/API_VERSIONING.md例如路由匹配器的合取条件不能被静默忽略可能导致路由策略绕过或客户端期望服务器以特定格式/编码如Struct-in-Any的 JSON 编码返回不透明扩展配置。这些场景下client_features字段就是控制面判断客户端能力边界的权威依据。关键消息定义速查源码佐证上述协议消息在仓库 api/envoy/service/discovery/v3/discovery.proto 中有完整定义核心字段位置如下消息关键字段行号DiscoveryRequestL58version_infoL68、resource_namesL79、type_urlL97、response_nonceL107、error_detailL113DiscoveryResponseL117version_infoL121、type_urlL148、nonceL158DeltaDiscoveryRequestL207type_urlL217、initial_resource_versionsL277、response_nonceL283、error_detailL288DeltaDiscoveryResponseL292system_version_infoL297、type_urlL307、removed_resourcesL311、removed_resource_namesL316、nonceL320ResourceL386ttlL434同时ConfigSource / ApiConfigSource / AggregatedConfigSource 是决定走独立流还是 ADS的配置载体Node 的client_features字段承载能力声明二者与本文协议描述一一对应是深入阅读源码时的最佳起点。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表