ARTICLE DETAIL

资讯详情

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

Envoy 增量 xDS(Delta xDS)与按需 xDS(On-demand xDS)支持现状全解析

Envoy 增量 xDS(Delta xDS)与按需 xDS(On-demand xDS)支持现状全解析 Envoy 增量 xDSDelta xDS与按需 xDSOn-demand xDS支持现状全解析【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy导读本文围绕 Envoy 官方 FAQ 中关于增量 xDS 支持到什么程度这一核心问题展开系统梳理 Delta xDS增量传输与 On-demand xDS按需加载两大机制在 Envoy 中的落地现状当前所有 xDS 协议含 ADS均已支持 Delta xDS而按需 xDS 仅由虚拟主机发现服务 VHDS 提供。读完本文你将掌握增量 xDS 与状态全量SotW协议在 wire 层的行为差异、DeltaDiscoveryRequest/Response的关键字段语义、如何通过api_type: DELTA_GRPC启用增量传输以及 VHDS 的资源命名规范、订阅/退订流程与配置方式。增量 xDS 支持现状FAQ 的直接回答官方 FAQ见 incremental.rst对该问题的回答非常明确增量 xDSIncremental xDS协议旨在通过两种机制提升 xDS 更新的效率、可扩展性与功能使用体验Delta xDS按资源增量delta交付而非世界状态全量state-of-the-world。On-demand xDS根据请求内容对资源进行懒加载lazy load。当前支持状态可以概括为两句话所有 xDS 协议包括 ADS都已支持 Delta xDS。即无论你是用独立的 LDS/CDS/RDS/EDS 流还是把全部资源类型复用到一条 ADS 流上都可以使用增量传输语义。On-demand xDS 目前仅由 VHDS虚拟主机发现服务支持。即在路由配置场景下可以按需拉取某个 host 对应的虚拟主机资源而其他资源类型暂不支持按需加载。为什么需要增量 xDS与 SotW 的对比在理解增量 xDS 之前需要先回顾它要解决的痛点。xDS 传输协议沿两个维度划分出四种变体详见 xds_protocol.rst维度取值一取值二交付语义State of the WorldSotW原始机制Incremental增量流组织方式每种资源类型独立 gRPC 流所有资源类型聚合到单条流ADS两两组合得到四种变体基本 xDSSotW 每种资源类型独立流Incremental xDS增量 每种资源类型独立流ADSSotW 全资源类型聚合流Incremental ADS增量 全资源类型聚合流。SotW 的痛点在于客户端每次请求都必须携带它关心的全部资源名且对 LDS/CDS 而言服务端必须把客户端订阅的全部资源都随响应返回。例如客户端已订阅 99 个资源想再新增 1 个就必须发送包含全部 100 个资源名的请求服务端即便其中 99 个未变化也要全部重发。这在大规模集群场景下构成明显的扩展性瓶颈。增量协议则允许客户端与服务端只表达相对上一次状态的差异客户端可以只声明新增订阅或退订某个资源名无需重发未变化的资源名服务端只需发送发生变化的资源增量协议还提供了懒加载机制On-demand xDS为按需拉取资源奠定协议基础。协议细节定义在 xds_protocol.rst 的 Incremental xDS 一节。增量 xDS 的 wire 协议DeltaDiscoveryRequest 与 DeltaDiscoveryResponse增量 xDS 是一个独立的 xDS 端点它有两大设计目标与 FAQ 中的两个机制一一对应在 wire 上以资源/资源名增量进行通信Delta xDS。例如拥有 10 万个集群时只修改了其中一个管理服务器只需交付那一个集群而不是全部 10 万个允许 Envoy 按需/懒请求额外资源。例如只有在某个集群的请求真正到达时才去请求该集群。增量 xDS 会话总是处于一条 gRPC 双向流bidirectional stream的上下文中这使得 xDS 服务器可以持续跟踪连接它的客户端状态。需要注意目前还没有 REST 版本的增量 xDS它是纯 gRPC 协议。与 SotW 使用DiscoveryRequest/DiscoveryResponse不同增量变体使用独立的 protobuf 消息DeltaDiscoveryRequest/DeltaDiscoveryResponse其定义位于 discovery.protoenvoy.service.discovery.v3包v2 时代的旧类型为envoy.api.v2.DeltaDiscoveryRequest/Response。DeltaDiscoveryRequest 的关键字段字段含义node客户端节点标识仅流的首个请求保证携带type_url订阅的资源类型 URL如type.googleapis.com/envoy.config.cluster.v3.Clusterresource_names_subscribe要加入跟踪列表的资源名列表增量协议没有全量重发资源名的要求resource_names_unsubscribe要移出跟踪列表的资源名列表initial_resource_versions重连时告知服务器客户端已知资源的版本 mapmapstring, string用于避免重连后服务器重复下发未变化的资源response_nonce当本请求是对某个DeltaDiscoveryResponse的 ACK/NACK 时必须回填该响应的 nonceerror_detailNACK 时填充携带具体错误信息resource_names_subscribe与resource_names_unsubscribe可以出现在任意DeltaDiscoveryRequest中包括 ACK 消息和携带initial_resource_versions的首条消息。这体现了增量协议请求即状态变更的设计哲学。DeltaDiscoveryResponse 的关键字段字段含义system_version_info可选的消息级版本信息仅用于调试目的客户端并不用它判断资源有效性resources本次变更涉及的资源Resource消息列表每个资源通常单独发送removed_resources需要从客户端本地缓存中删除的资源名列表nonce必须存在的字段用于把响应与客户端的 ACK/NACK 请求配对增量协议中的 nonce 语义在 Delta xDS 中nonce字段是必须的用于将DeltaDiscoveryResponse与DeltaDiscoveryRequest的 ACK/NACK 配对。ACK 或 NACK 由请求中error_detail的缺失或存在决定。DeltaDiscoveryRequest可以在以下三种场景发送gRPC 双向流中的首条消息作为对先前DeltaDiscoveryResponse的ACK/NACK 响应——此时response_nonce被设置为响应中的 nonce 值客户端自发发送的请求——用于动态增删跟踪的资源名集合此时response_nonce必须省略。一个值得注意的细节即使请求中带有response_nonce服务器也必须尊重订阅状态的变更即使 nonce 已过期。nonce 只用于关联 ACK/NACK 与响应不应被用于拒绝过期请求。ACK 与 NACK 语义与 SotW 协议类似增量 xDS 客户端对每个收到的响应都应回复 ACK 或 NACKACK响应的每个资源单独评估均有效。请求回填响应的nonceNACK响应中至少一个资源无效。请求填充error_detail字段服务器应优先通过检查该字段来检测 NACK。增量 xDS 的订阅、退订与通配符订阅资源Subscribing客户端通过在resource_names_subscribe中发送资源的名称或别名来订阅。服务器在判断某个实体是否已被订阅时应同时检查资源名与别名。值得注意resource_names_subscribe中可能包含服务器认为客户端已经订阅且已持有最新版本的资源名但服务器仍然必须在响应中再次下发这些资源——因为存在对服务器不可见的实现细节客户端可能虽然表面上仍处于订阅状态但实际上已经遗忘了这些资源。退订资源Unsubscribing客户端通过resource_names_unsubscribe表达失去兴趣的资源同样支持名称或别名。该字段可能包含多余的、服务器认为客户端本来就没订阅的资源名服务器应干净地处理这类幽灵退订可直接忽略。大多数情况下如果请求只做了退订服务器无需发送任何响应特别是通常不需要在removed_resources中回传被退订的资源名。但有一个例外当客户端同时拥有通配符订阅*与对某个具体资源名的订阅时该具体资源名可能同时被通配符覆盖客户端无法自行判断退订后是否还应继续缓存该资源。此时服务器必须发送响应把该资源放入removed_resources若不被通配符覆盖或resources若仍被通配符覆盖。通配符订阅Wildcard对于 Listener 与 Cluster 资源类型存在特殊的通配符订阅当订阅特殊名称*时服务器应基于站点自身业务逻辑通常结合客户端node标识确定客户端关心的完整资源集合。增量协议下触发通配符订阅有两种方式在resource_names_subscribe中明确指定*兼容旧行为请求的resource_names_subscribe与resource_names_unsubscribe均为空。但注意历史语义陷阱一旦客户端在该流上对某资源类型显式订阅过任何资源名包括*此后清空订阅列表将被解释为退订全部而非通配符订阅。重连与 initial_resource_versions由于增量协议不假设流之间保留任何状态重连后的客户端必须向服务器提供它关心的全部资源名。同时客户端可以通过initial_resource_versions告知服务器自己已知的资源及版本避免服务器把这些资源重新通过网络下发一次前提是客户端订阅集合与断流前一致。资源不存在与删除的快速判定资源不存在当客户端订阅的资源不存在时服务器会发送一条DeltaDiscoveryResponse把该资源名放入removed_resources字段使客户端能快速判定无需像 SotW 那样等待超时。客户端仍建议使用超时保护以应对管理服务器响应不及时的情况。资源删除服务器通过响应的removed_resources字段通知客户端删除某资源。分组与重复名约束增量协议中服务器将每个资源放在各自的响应中发送若先前发了 100 个资源、现在只有 1 个变化只需发送这 1 个客户端不得删除未变化的 99 个。服务器在单条响应中重复包含同一资源名属于错误客户端应对包含重复资源名的响应执行 NACK。所有协议变体都按完整命名资源为操作单位不存在对命名资源内部 repeated 字段做增量更新的机制最典型的是目前无法对 EDS 响应中的单个 endpoint 做增量更新。如何启用增量 xDSapi_type: DELTA_GRPC从 Envoy 1.12.0 起Envoy 支持 xDS含 ADS的 delta 变体。启用方式非常简单把ApiConfigSource的api_type字段设为DELTA_GRPC即可参见 xds_api.rst。该配置对普通 xDS 和 ADS 均适用对 ADS 而言设置的是dynamic_resources.ads_config的api_type。概念上delta 应被视为一种新的 xDS 传输类型目前存在 static静态、filesystem、REST、gRPC-SotW、gRPC-delta 等传输方式。虽然 Envoy 的 gRPC-SotW 与 delta 客户端实现共享大部分代码但二者是互不兼容的协议。一个典型的 ADS DELTA_GRPC 的 bootstrap 配置片段完整示例见 ads.yamlnode: cluster: envoy_cluster id: envoy_node dynamic_resources: ads_config: api_type: DELTA_GRPC # 增量 ADSapi_type 设为 DELTA_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: address: my-control-plane port_value: 777 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: {}几点使用建议源自 ads.yaml 注释与协议文档建议为与 ADS 服务器的连接配置HTTP/2 keepalive 或 TCP keepalive以尽早发现连接问题并触发重连。TCP keepalive 开销较小但若 Envoy 与管理服务器之间存在 TCP 代理可能不够用HTTP/2 keepalive 开销略高但能穿透更多类型的中间代理。ADS 仅在 gRPC 流式模式下可用REST-JSON 轮询不支持 ADS。在静态配置中xDSCluster资源应先于依赖它的静态 Cluster 声明否则会拖慢 Envoy 初始化例如依赖 xDS Cluster 做 SDS 拉取证书的 Cluster其 xDS Cluster 必须排在前。On-demand xDSVHDS 详解按需 xDS 是增量 xDS 的第二个机制目前仅落地在VHDSVirtual Host Discovery Service虚拟主机发现服务上。完整说明见 vhds.rst。为什么需要 VHDS默认情况下RDS 会把一个集群的所有路由配置RouteConfiguration推送给网格中的每个 Envoy 实例。随着集群规模增长这会造成扩展性问题——而复杂度主要来自虚拟主机VirtualHost配置其中大部分对单个代理实例而言是不需要的。VHDS 使用 delta xDS 协议使路由配置可以被订阅且按需请求必要的虚拟主机不再把全部虚拟主机随路由配置下发而是允许单个 Envoy 实例从 xDS 管理服务器维护的内部虚拟主机列表中订阅/退订。管理服务器监视该订阅列表并用它过滤发给该 Envoy 实例的配置仅包含其已订阅的虚拟主机。虚拟主机资源命名规范VHDS 中的虚拟主机由所属路由配置名 HTTP host 头HTTP/2 下即:authority共同标识资源命名规则为route configuration name/host entry例如路由配置my_route下的www.example.com对应资源名my_route/www.example.com。注意匹配应从右向左进行因为 host entry 不能包含斜杠而路由配置名可以从而可唯一拆分。订阅与懒加载流程订阅 VHDS 资源时客户端发送DeltaDiscoveryRequest其中type_url设置为type.googleapis.com/envoy.config.route.v3.VirtualHostresource_names_subscribe设置为想要获取配置的虚拟主机资源名列表。关键的处理流程在 source/common/router/vhds.cc 等路由层实现中落地当无法依据请求的 host/authority 头解析出路由时当前活跃流被暂停paused同时发送一条DeltaDiscoveryRequest订阅所需虚拟主机当收到DeltaDiscoveryResponse且其中某个资源的aliases或name与请求中的resource_names_subscribe条目精确匹配时路由配置被更新、流被恢复过滤器链继续处理。虚拟主机的更新途径遵循从哪来、回哪去原则若某个虚拟主机最初是通过 RDS 下发的则后续更新走 RDS若是通过 VHDS 订阅获得的则后续更新走 VHDS。此外当路由配置条目被更新且其vhds字段发生变化时该路由配置对应的虚拟主机表会被清空需要服务器重新下发全部虚拟主机。与 Scoped RDS 的兼容性VHDS 与 Scoped RDS 不存在兼容性问题路由配置名仍可用于虚拟主机匹配但配置了 scoped RDS 时它指向的是 scoped route configuration。需要注意的是若同时使用按需 scoped RDS与 VHDS每个路由作用域routing scope将需要两条按需订阅。VHDS 统计信息VHDS 的统计树根植于http.stat_prefix.vhds.virtual_host_name.其中虚拟主机名中的:会被替换为_。统计项如下名称类型说明config_reloadCounter因配置不同而触发配置重载的 API 获取总次数empty_updateCounter收到的空更新总数源码级佐证增量协议与 VHDS 的实现落点上述协议语义并非纸面设计在仓库中均有明确落点协议定义discovery.proto 定义了DeltaDiscoveryRequest含resource_names_subscribe、resource_names_unsubscribe、initial_resource_versions、response_nonce等字段、DeltaDiscoveryResponse含system_version_info、resources、removed_resources、nonce与Resource消息。proto 注释明确说明Delta 响应不需要包含跟踪资源的完整快照而是包含增量变更。VHDS 客户端实现路由层 vhds.cc 与 vhds.h 实现了 VHDS 订阅逻辑构建目标为//source/common/router:vhds_librds_impl.cc 中通过resourceIdsInLastVhdsUpdate()结合 RDS 更新处理 VHDS 相关的资源 IDconfig_impl.h 中uses_vhds_标志标明某路由配置是否启用了 VHDS。各资源类型的增量 RPC 方法每种资源类型的 Discovery Service 都同时提供 SotW 与 Delta 两个 RPC 方法例如ListenerDiscoveryService.StreamListeners/DeltaListeners、ClusterDiscoveryService.StreamClusters/DeltaClusters、EndpointDiscoveryService.StreamEndpoints/DeltaEndpoints等聚合变体对应AggregatedDiscoveryService.StreamAggregatedResources/DeltaAggregatedResources参见 xds_protocol.rst。配套能力与注意事项与增量 xDS 相关的几个周边机制值得一并了解详见 xds_protocol.rst资源类型版本每个 xDS 资源类型有独立的版本字符串任一资源变化即变更版本。增量协议中服务器通过system_version_info下发版本但客户端判断资源有效性使用的是独立机制ACK/NACK nonce版本仅作调试。非增量流的资源提示在 SotW 变体中客户端通过resource_names表达资源兴趣一旦在流上显式订阅过资源名后续空列表即视为退订而非通配符订阅语义与增量协议一致。资源预热warmingCluster 需在收到ClusterLoadAssignment响应后才完成预热Listener 若引用 RDS 配置则在收到RouteConfiguration后完成预热。若管理服务器在预热期间不提供 EDS/RDS 响应Envoy 将无法完成初始化。这是使用增量 xDS 时管理服务器侧必须配合的协议行为。xDS TTL对于支持xds.config.supports-resource-ttl客户端特性的场景每个Resource可携带独立的 TTL管理服务器失联到期后资源被移除增量协议下 TTL 直接在响应内的Resource上指定心跳式 TTL 刷新仅更新 TTL 不更新资源内容也得到支持。最终一致性xDS 更新是最终一致的更新期间可能出现短暂流量黑洞如需零中断应遵循 make-before-break 的推送顺序CDS → EDS → LDS → RDS → VHDS → 清理过期 CDS/EDS而 ADS/增量 ADS 的单流复用特性正是为了简化这种顺序编排而设计的参考 xds_api.rst。小结回到 FAQ 的原始问题Envoy 对增量 xDS 的支持已经全面铺开——Delta xDS 覆盖所有资源类型的独立流与 ADS 聚合流且从 1.12.0 起仅需把api_type改为DELTA_GRPC即可启用按需 xDS 则仍处于 VHDS 专属阶段通过增量订阅协议按 host 懒加载虚拟主机缓解大规模路由配置下的推送压力。理解这两层机制的分工增量传输解决带宽与规模按需加载解决单点配置冗余有助于在构建大规模控制面时做出正确的协议选型。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表