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 双向认证配置 |
4.2 xDS 工作流程:从订阅到 ACK/NACK
Envoy 与控制面之间的交互遵循订阅-推送-确认的流式 gRPC 模式。核心步骤包括:
- Stream 建立:Envoy 向控制面发起 gRPC 双向流,携带节点标识(Node ID、Cluster、Metadata)。
- 初始订阅:Envoy 发送 DiscoveryRequest,声明需要订阅的资源类型(如 type.googleapis.com/envoy.config.cluster.v3.Cluster)和资源名列表(或通配符)。
- 控制面推送:控制面根据订阅生成 DiscoveryResponse,包含资源版本号(version_info)和序列化的 protobuf 资源列表。
- Envoy 处理与 ACK:Envoy 反序列化、校验、应用配置。成功后发送 ACK(携带相同的 version_info);失败则发送 NACK(携带 error_detail 和拒绝的版本)。
- 增量更新(Delta xDS):支持仅推送变更的资源,减少全量推送带来的带宽和 CPU 开销。
envoy_cluster_update_rejected)追踪 NACK 原因。
4.3 xDS 交互流程架构图
下图展示了 Envoy 与控制面之间通过 gRPC 双向流进行 xDS 资源订阅、推送与确认的完整生命周期:
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 个服务) |
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 场景)