How does Envoy handle service discovery and what cluster types are available?
Quick Answer
Envoy supports multiple service discovery mechanisms through its cluster type configuration: STATIC (hardcoded endpoints), STRICT_DNS (DNS resolution with all IPs used), LOGICAL_DNS (DNS with single IP used), EDS (Endpoint Discovery Service for dynamic environments), and ORIGINAL_DST (transparent proxying using original destination addresses).
Detailed Answer
Think of service discovery as the way Envoy builds its phone book of available backend services. Just like you can have a printed phone book (static), look up numbers through directory assistance (DNS), or use a constantly updated contact app that syncs across devices (EDS), Envoy provides multiple methods for discovering where upstream services are located.
The cluster type configuration in Envoy determines how it discovers and maintains the list of endpoints (IP addresses and ports) for each upstream service. The simplest type is STATIC, where you hardcode the endpoint addresses directly in the configuration file. This is straightforward and works well for infrastructure services with fixed addresses, like a database server or an external API endpoint. However, static configuration does not adapt to dynamic environments where services scale up and down.
STRICT_DNS resolves a DNS hostname and uses all returned IP addresses as endpoints. Envoy continuously re-resolves the DNS name at a configurable interval and updates the endpoint list when the DNS response changes. If the DNS query for order-service.default.svc.cluster.local returns three IP addresses, Envoy creates three endpoints and load-balances across all of them. When a pod is removed and the DNS response changes to two IP addresses, Envoy automatically removes the stale endpoint. LOGICAL_DNS is similar but only uses the first IP address from the DNS response, creating a single logical connection. This is useful for services behind a load balancer where you want DNS-based resolution but do not want Envoy to track individual backend instances.
EDS (Endpoint Discovery Service) is the most powerful and dynamic service discovery mechanism. Instead of relying on DNS, Envoy communicates with an external management server that provides endpoint information through a gRPC or REST API. The management server pushes endpoint updates to Envoy in real-time as services scale, deploy, or fail health checks. This is the mechanism used by service mesh control planes like Istio's istiod, Consul Connect, and AWS App Mesh. EDS provides richer information than DNS, including endpoint metadata, health status, load balancing weights, and locality information for zone-aware routing. ORIGINAL_DST is used for transparent proxying, where Envoy uses the original destination address from the connection metadata (set by iptables redirection) to determine the upstream endpoint.
In production Kubernetes environments, EDS is the standard discovery mechanism because it integrates with the Kubernetes API to track pod lifecycle events in real-time. When a new payments-api pod starts and passes its readiness check, the control plane pushes an EDS update to all Envoy sidecars, immediately making the new endpoint available for load balancing. When a pod is terminating, the endpoint is removed before the pod shuts down, preventing requests from being sent to a dying instance. This real-time synchronization is far more responsive than DNS-based discovery, which has inherent TTL delays.
A common mistake is choosing STRICT_DNS in Kubernetes and assuming it will work like EDS. While DNS-based discovery works, it has limitations: DNS TTLs introduce propagation delays, DNS responses may be truncated for large clusters, and DNS does not provide health status or weighting information. For any environment with more than a handful of services, EDS is the recommended approach because it provides real-time updates, richer metadata, and better integration with the overall service mesh architecture.