3. Envoy 动态配置:控制面与数据面分离、xDS API 详解
Envoy 之所以能成为云原生时代的“通用数据平面”,核心在于其控制面与数据面分离的架构设计。数据面(Envoy 代理)负责处理实际流量,而控制面(如 Istiod、xDS 管理服务器)负责下发配置。两者通过 xDS API 进行通信,实现配置的动态下发与热更新,无需重启代理。
核心价值:动态配置使得 Envoy 可以在运行时调整路由、监听器、集群、端点甚至 TLS 证书,这是实现服务网格弹性、灰度发布、故障恢复的基础。
3.1 控制面与数据面分离架构
在传统代理(如 Nginx)中,配置变更通常需要重载进程。Envoy 则通过 xDS API 将配置决策权上移至控制面,数据面只负责执行。这种分离带来了以下优势:
- 无中断更新:配置变更通过 gRPC 流推送,Envoy 热加载,不影响现有连接。
- 集中管理:控制面可以聚合全局视图,统一下发策略,避免逐台修改。
- 可观测性:控制面可以追踪每个 Envoy 实例的配置版本与状态。
3.2 xDS API 详解
xDS 是“X Discovery Service”的缩写,X 代表不同的配置资源类型。Envoy 通过订阅这些 API 来获取动态配置。核心的 xDS API 包括以下五种:
| API 名称 | 全称 | 配置资源 | 核心作用 |
|---|---|---|---|
| LDS | Listener Discovery Service | 监听器(Listener) | 定义 Envoy 监听的端口、协议、过滤器链 |
| RDS | Route Discovery Service | 路由配置(RouteConfiguration) | 定义虚拟主机、路由规则、匹配条件与转发目标 |
| CDS | Cluster Discovery Service | 集群(Cluster) | 定义上游服务集群的连接池、负载均衡策略、健康检查 |
| EDS | Endpoint Discovery Service | 端点(Endpoint) | 定义集群中具体的后端实例 IP:Port 列表 |
| SDS | Secret Discovery Service | 密钥(Secret) | 动态下发 TLS 证书、私钥、验证 CA |
配置依赖链:LDS 引用的路由名称需要 RDS 提供;RDS 引用的集群名称需要 CDS 提供;CDS 引用的端点名称需要 EDS 提供。SDS 则独立用于证书管理。
3.3 xDS 配置依赖与数据流
Envoy 启动时,会先向控制面发起 LDS 请求,获取监听器配置。监听器中的过滤器链会引用路由配置,进而触发 RDS 请求。路由规则中指定的集群会触发 CDS 请求,而集群中的端点信息则通过 EDS 获取。整个过程形成一个自上而下的依赖链。
3.4 关键 xDS 协议特性
- SotW(State of the World):控制面每次推送全量配置,Envoy 全量替换。简单但网络开销大。
- Delta(增量):只推送变更的资源,减少带宽与 CPU 消耗,适合大规模集群。
- gRPC 流式订阅:Envoy 通过 gRPC 双向流订阅配置,控制面可以实时推送更新。
- 版本控制:每次响应携带版本号,Envoy 通过 ACK/NACK 机制反馈配置生效状态。
生产建议:在 Istio 环境中,默认使用 Delta xDS 以减少控制面负载。如果自定义控制面,务必实现 ACK/NACK 处理逻辑,避免配置不一致导致流量中断。
3.5 配置示例:xDS 资源结构
以下是一个简化的 xDS 配置片段,展示 LDS 如何引用 RDS,RDS 如何引用 CDS:
# LDS 配置片段
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 80 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config_name: my_route # 引用 RDS 中的路由名称
http_filters:
- name: envoy.filters.http.router
# RDS 配置片段
route_configurations:
- name: my_route
virtual_hosts:
- name: backend_service
domains: ["*"]
routes:
- match: { prefix: "/api" }
route: { cluster: my_cluster } # 引用 CDS 中的集群名称
# CDS 配置片段
clusters:
- name: my_cluster
connect_timeout: 0.25s
type: EDS # 使用 EDS 动态发现端点
lb_policy: ROUND_ROBIN
eds_cluster_config:
eds_config:
resource_api_version: V3
ads: {} # 通过 ADS 聚合发现服务获取 EDS 配置
3.6 与云原生运行基线的关联
在云原生运行基线核验中,xDS 配置的正确性直接影响安全与合规:
| 基线要求 | 对应 xDS 配置项 | 核验点 |
|---|---|---|
| 最小权限监听 | LDS | 只暴露必要端口,禁止监听 0.0.0.0:443 等敏感端口 |
| 路由安全 | RDS | 禁止通配符域名滥用,确保路由规则不泄露内部服务 |
| 集群健康检查 | CDS | 必须配置主动健康检查,避免流量打到异常端点 |
| 端点准入 | EDS | 端点列表必须经过控制面校验,防止恶意端点注入 |
| 证书轮换 | SDS | 证书必须通过 SDS 动态下发,禁止挂载静态证书文件 |
核验自动化:可以通过 Envoy 的 admin 接口(
/config_dump)获取当前生效的 xDS 配置,与基线策略进行对比校验,实现持续合规。