4. 动态配置与 xDS 协议:CDS、EDS、LDS、RDS、SDS 的工作原理与控制面交互流程

在 Envoy 生产集群中,静态配置文件仅适用于原型验证。一旦进入动态配置时代,Envoy 通过 xDS 协议族(Discovery Service APIs)从控制面(如 Istio Pilot、Kratos、Go Control Plane)实时拉取路由、监听器、集群和端点信息。xDS 是 Envoy 实现热更新、零停机、声明式流量治理的核心通信契约。

4.1 xDS 协议族总览

xDS 并非单一协议,而是由多个子协议组成的发现服务集合。每个子协议负责一类配置资源的动态下发:

协议缩写 全称 管理资源 典型更新场景
CDS Cluster Discovery Service 集群定义(Cluster) 新增/删除上游服务集群、修改连接池、负载均衡策略
EDS Endpoint Discovery Service 集群端点(Endpoint/LB Endpoint) Pod IP 变更、金丝雀权重调整、主动健康检查结果
LDS Listener Discovery Service 监听器(Listener) 新增/修改入站端口、TLS 终止、Filter 链变更
RDS Route Discovery Service 路由配置(RouteConfiguration) 流量切分、Header 匹配规则、超时/重试策略调整
SDS Secret Discovery Service 证书与私钥(Secret) 证书轮换、mTLS 双向认证配置
关键依赖顺序:LDS 引用的路由名称必须由 RDS 提供;RDS 引用的集群名称必须由 CDS 定义;CDS 引用的端点发现类型若为 EDS,则必须由 EDS 提供端点。控制面必须按此拓扑顺序推送,否则 Envoy 会因资源缺失而拒绝配置。

4.2 xDS 工作流程:从订阅到 ACK/NACK

Envoy 与控制面之间的交互遵循订阅-推送-确认的流式 gRPC 模式。核心步骤包括:

  1. Stream 建立:Envoy 向控制面发起 gRPC 双向流,携带节点标识(Node ID、Cluster、Metadata)。
  2. 初始订阅:Envoy 发送 DiscoveryRequest,声明需要订阅的资源类型(如 type.googleapis.com/envoy.config.cluster.v3.Cluster)和资源名列表(或通配符)。
  3. 控制面推送:控制面根据订阅生成 DiscoveryResponse,包含资源版本号(version_info)和序列化的 protobuf 资源列表。
  4. Envoy 处理与 ACK:Envoy 反序列化、校验、应用配置。成功后发送 ACK(携带相同的 version_info);失败则发送 NACK(携带 error_detail 和拒绝的版本)。
  5. 增量更新(Delta xDS):支持仅推送变更的资源,减少全量推送带来的带宽和 CPU 开销。
生产实践:控制面必须实现 NACK 监控。Envoy 在 NACK 中会保留上一个有效版本继续运行,不会因推送失败而中断流量。SRE 应通过控制面日志或 Prometheus 指标(如 envoy_cluster_update_rejected)追踪 NACK 原因。

4.3 xDS 交互流程架构图

下图展示了 Envoy 与控制面之间通过 gRPC 双向流进行 xDS 资源订阅、推送与确认的完整生命周期:

xDS 控制面交互流程 xDS 控制面交互流程(gRPC 双向流) Envoy Sidecar xDS 订阅客户端 配置缓存 & 版本管理 配置校验 & 热加载 ACK / NACK 生成 流量处理 Worker 控制面(Pilot / Kratos) xDS 聚合服务 资源版本管理 K8s / 注册中心 监听 Diff 计算 & 推送决策 gRPC Stream 管理 DiscoveryRequest(订阅 + 版本) DiscoveryResponse(资源 + version_info) ACK(version_info 确认) NACK(error_detail + 拒绝版本) 关键行为 Envoy 始终保留上一个有效版本;NACK 不会导致流量中断,控制面需监控 NACK 并重试推送

4.4 各 xDS 子协议详解

4.4.1 LDS(Listener Discovery Service)

LDS 是 Envoy 的流量入口。控制面通过 LDS 下发 Listener 配置,定义 Envoy 在哪个端口监听、使用什么 Filter 链(HTTP 连接管理器、TLS 检查器等)。

  • 资源类型:envoy.config.listener.v3.Listener
  • 典型字段:address、filter_chains、listener_filters、traffic_direction
  • 更新影响:修改 Listener 会导致 Envoy 关闭旧监听器并新建,但已建立的连接不受影响(通过 SO_REUSEPORT 和优雅关闭)。

4.4.2 RDS(Route Discovery Service)

RDS 为 HTTP 连接管理器提供路由表。控制面根据 VirtualService、DestinationRule 等 CRD 生成 RouteConfiguration。

  • 资源类型:envoy.config.route.v3.RouteConfiguration
  • 典型字段:virtual_hosts、routes、validate_clusters
  • 更新影响:路由变更立即生效,不影响已有请求;新请求按新路由表转发。

4.4.3 CDS(Cluster Discovery Service)

CDS 定义 Envoy 如何连接上游服务,包括连接池大小、负载均衡算法、主动健康检查、断路器阈值等。

  • 资源类型:envoy.config.cluster.v3.Cluster
  • 典型字段:name、type(STATIC/STRICT_DNS/EDS)、connect_timeout、lb_policy、circuit_breakers
  • 更新影响:修改 Cluster 定义(如切换负载均衡算法)会重建连接池,但已有请求继续使用旧连接池直至完成。

4.4.4 EDS(Endpoint Discovery Service)

EDS 是最动态的 xDS 子协议,负责下发集群的端点列表。在 Kubernetes 环境中,每个 Pod IP 变更都会触发 EDS 更新。

  • 资源类型:envoy.config.endpoint.v3.ClusterLoadAssignment
  • 典型字段:cluster_name、endpoints(LbEndpoint)、locality
  • 更新影响:端点变更仅影响新连接;Envoy 通过 panic threshold 机制在端点大量丢失时仍保持可用性。

4.4.5 SDS(Secret Discovery Service)

SDS 解决证书轮换的难题。控制面将 TLS 证书和私钥作为 Secret 资源下发,Envoy 在证书过期前自动加载新证书。

  • 资源类型:envoy.extensions.transport_sockets.tls.v3.Secret
  • 典型字段:name、tls_certificate、validation_context
  • 更新影响:证书更新不中断现有 TLS 连接;新连接使用新证书,旧连接继续使用旧证书直至关闭。

4.5 xDS 版本协商与资源类型

Envoy 与控制面通过 type URL 协商资源类型。Envoy 3.x 使用 envoy.config.*.v3 命名空间,2.x 使用 envoy.api.v2。控制面必须根据 Envoy 版本选择对应的 proto 文件。

Envoy 版本 API 版本 典型 type URL 前缀 备注
1.18 - 1.22 v2 envoy.api.v2 已弃用,建议迁移
1.23+ v3 envoy.config.*.v3 当前主流版本
1.28+ v3 + Delta envoy.config.*.v3 支持增量 xDS

4.6 增量 xDS(Delta xDS)与全量 xDS 对比

全量 xDS(SotW, State of the World)每次推送都包含所有资源;增量 xDS(Delta)只推送变更部分,显著降低大规模集群下的控制面与网络开销。

对比维度 全量 xDS(SotW) 增量 xDS(Delta)
推送内容 全部资源列表 仅变更的资源
带宽消耗 高(随资源数线性增长) 低(仅变更部分)
Envoy 处理开销 高(全量反序列化 + 校验) 低(增量合并)
版本管理 全局 version_info 每个资源独立版本
推荐场景 小规模集群(< 100 个服务) 大规模集群(> 500 个服务)
避坑提示:控制面同时支持全量和增量 xDS 时,Envoy 会在 DiscoveryRequest 中通过 type_url 和 resource_names 声明能力。控制面必须正确识别 Envoy 的 Delta 支持标志,否则可能导致推送格式不匹配,Envoy 持续 NACK。

4.7 控制面交互的故障排查要点

SRE 在排查 xDS 交互问题时,应重点关注以下指标和日志:

  • Envoy 指标:
    • envoy_cluster_update_success / envoy_cluster_update_failure:CDS/EDS 更新成功/失败计数
    • envoy_listener_manager_listener_added / envoy_listener_manager_listener_removed:LDS 变更事件
    • envoy_config_internal_delta_xds_ack / envoy_config_internal_delta_xds_nack:增量 xDS 确认状态
  • 控制面日志:搜索 NACK、resource does not exist、type URL mismatch 等关键词。
  • 常见 NACK 原因:
    • 引用的集群/路由/监听器不存在(依赖顺序错误)
    • 资源 protobuf 序列化格式不匹配(v2 vs v3)
    • 资源版本号冲突或回退
    • 证书格式错误或过期(SDS 场景)
生产级建议:在控制面实现 xDS 推送的 canary 发布——先向少量 Envoy 实例推送新配置,观察 NACK 率和流量错误率,确认稳定后再全量推送。同时为每个 xDS 流设置超时和重试,避免控制面故障导致 Envoy 配置停滞。