envoyproxy/envoy
xDS configuration
xDS is the family of gRPC-based discovery APIs Envoy uses to receive dynamic configuration from a control plane. Almost everything an operator might want to change without restarting Envoy — listeners, clusters, routes, secrets, runtime, per-filter config — flows through xDS. The protocol is defined in the api/ tree, and the client code lives in source/extensions/config_subscription/ plus per-resource glue under source/common/.
The xDS family
| API | Resource | Server name | Wire location |
|---|---|---|---|
| LDS | envoy.config.listener.v3.Listener |
envoy.service.listener.v3.ListenerDiscoveryService |
api/envoy/service/listener/v3/lds.proto |
| CDS | envoy.config.cluster.v3.Cluster |
envoy.service.cluster.v3.ClusterDiscoveryService |
api/envoy/service/cluster/v3/cds.proto |
| EDS | envoy.config.endpoint.v3.ClusterLoadAssignment |
envoy.service.endpoint.v3.EndpointDiscoveryService |
api/envoy/service/endpoint/v3/eds.proto |
| RDS | envoy.config.route.v3.RouteConfiguration |
envoy.service.route.v3.RouteDiscoveryService |
api/envoy/service/route/v3/rds.proto |
| VHDS | envoy.config.route.v3.VirtualHost |
embedded in RDS | (same proto package) |
| SRDS | envoy.config.route.v3.ScopedRouteConfiguration |
envoy.service.route.v3.ScopedRoutesDiscoveryService |
(same proto package) |
| SDS | envoy.extensions.transport_sockets.tls.v3.Secret |
envoy.service.secret.v3.SecretDiscoveryService |
api/envoy/service/secret/v3/sds.proto |
| RTDS | envoy.service.runtime.v3.Runtime |
envoy.service.runtime.v3.RuntimeDiscoveryService |
api/envoy/service/runtime/v3/rtds.proto |
| ECDS | per-extension Any config |
envoy.service.extension.v3.ExtensionConfigDiscoveryService |
api/envoy/service/extension/v3/config_discovery.proto |
| HDS | health check assignments | envoy.service.health.v3.HealthDiscoveryService |
api/envoy/service/health/v3/hds.proto |
| LRS | load report streams | envoy.service.load_stats.v3.LoadReportingService |
api/envoy/service/load_stats/v3/lrs.proto |
| ADS | aggregated multiplex | envoy.service.discovery.v3.AggregatedDiscoveryService |
api/envoy/service/discovery/v3/ads.proto |
Two flavours: SotW and Delta
Each xDS API has two RPC styles:
- State-of-the-world (SotW). The server sends the complete set of resources every time anything changes. Missing resources mean "remove". Implemented by
GrpcMuxImpl(source/extensions/config_subscription/grpc/grpc_mux_impl.cc). - Delta. The server sends only added/modified/removed resources. The client tracks a per-resource version. Implemented by
NewGrpcMuxImpl.
Both styles support ADS multiplexing: a single bidirectional gRPC stream carries every xDS subscription instead of one stream per API.
Architecture
graph TB
Server[Envoy server] --> XdsManager[Config::XdsManager]
XdsManager --> AdsMux[GrpcMuxImpl ADS]
XdsManager --> SubsLDS[Subscription LDS]
XdsManager --> SubsCDS[Subscription CDS]
XdsManager --> SubsRDS[Subscription RDS]
XdsManager --> SubsEDS[Subscription EDS]
XdsManager --> SubsSDS[Subscription SDS]
XdsManager --> SubsRTDS[Subscription RTDS]
AdsMux -->|gRPC bidi stream| ControlPlane[Control plane]
SubsLDS -.may share mux.-> AdsMux
SubsCDS -.may share mux.-> AdsMux
SubsLDS --> LM[Listener manager]
SubsCDS --> CM[Cluster manager]
SubsRDS --> Router[Router config]
SubsEDS --> CM
SubsSDS --> Secrets[Secret manager]
SubsRTDS --> Runtime[Runtime loader]The Config::XdsManager (source/common/config/xds_manager_impl.cc) owns the long-lived gRPC mux objects and hands per-resource subscriptions back to consumers.
Subscription lifecycle
sequenceDiagram
participant Sub as Consumer (e.g. ListenerManager)
participant Mux as GrpcMuxImpl
participant CP as Control plane
Sub->>Mux: subscribe(type_url, names, callbacks)
Mux->>CP: send DiscoveryRequest(version, names)
CP-->>Mux: DiscoveryResponse(resources, version)
Mux->>Sub: onConfigUpdate(resources, version)
Sub-->>Mux: ack(version) or nack(error)
Mux->>CP: send next DiscoveryRequest with ack/nack
Note over Sub,Mux: stream stays open; updates flow as neededNACKs are first-class: when a consumer rejects a config, the mux sends an error_detail upstream so the control plane can retry or alarm.
Subscription factories
Subscriptions can come from different transports, abstracted behind Config::SubscriptionFactory:
- gRPC (
source/extensions/config_subscription/grpc/) — the canonical transport. - REST (
source/extensions/config_subscription/rest/) — JSON over HTTP polling. Less performant; rare in production. - Filesystem (
source/extensions/config_subscription/filesystem/) — a directory the control plane writes to.
ADS
ADS is the single-stream variant. Most production deployments use ADS so all resources land on one gRPC stream, ensuring ordering across types — for example, a CDS update referencing a new EDS resource arrives in a known order. The ads_config in Bootstrap controls it.
ECDS and dynamic per-filter config
ECDS lets a control plane push per-filter configuration (e.g. a different ext_authz URL) without rebuilding the listener. It is set up by configuring the filter as ConfigDiscoveryConfig instead of inline typed_config. Implementation: source/common/filter/config_discovery_impl.cc.
On-demand xDS
A few APIs support on-demand discovery:
- VHDS — virtual hosts are not delivered upfront; the router requests one when a request arrives for an unknown vhost.
- ODCDS — clusters are discovered when a route references one. Implementation:
source/common/upstream/cluster_discovery_manager.cc.
Pre-resolution, validation, and decoding
Each subscription is parameterised by a type_url (the protobuf FQN) and a deserialiser. OpaqueResourceDecoder in envoy/config/subscription.h handles the Any → typed message hop. Validation visitors enforce protobuf-validate rules before the resource reaches the consumer.
Bootstrap entry
xDS is wired in via the dynamic_resources and static_resources.layered_runtime fields of Bootstrap:
dynamic_resources:
ads_config:
api_type: GRPC
grpc_services:
- envoy_grpc:
cluster_name: xds_cluster
cds_config:
ads: {}
lds_config:
ads: {}API versioning
The current major version is v3. The policy in api/API_VERSIONING.md describes how vNalpha, additive vs breaking changes, and deprecation work. New features land in v3 (or new v4alpha once introduced); old v2 was removed in 2021. See API versioning.
Integration points
- Server lifecycle. XdsManager is created early; subscriptions register init targets.
- Listener / cluster / runtime / secret managers. Each subscribes for its own resource type and consumes updates.
- HTTP / network filters. ECDS-backed filters subscribe for their config.
- Load reporting. The cluster manager streams LRS reports to the control plane.
Entry points for modification
- Adding an xDS API: add proto messages under
api/envoy/service/<area>/v3/and a subscription consumer. - Modifying ADS multiplexing:
source/extensions/config_subscription/grpc/grpc_mux_impl.cc. - Adding a new transport: implement
Config::SubscriptionFactoryand register it.
See also
- Listener manager — LDS consumer.
- Cluster manager — CDS, EDS, SDS, HDS, LRS consumer.
- Runtime — RTDS consumer.
- API versioning — how
v3evolves.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.