Service Discovery with Envoy

Viewed 1566

How does it work with Envoy?

Let's say I have configured an upstream cluster like this:

  clusters:
    - 
      name: "service_a_cluster"
      connect_timeout: "0.25s"
      type: "strict_dns"
      lb_policy: "ROUND_ROBIN"
      hosts:
        - 
          socket_address: 
            address: "service_a"
            port_value: 8786

How is my Envoy instance (ClusterManager?) going to resolve service_a?
To whom is it going to send DNS queries?

2 Answers

Envoy has internal mechanisms for doing resolution, and these are all available through configuration. It looks like you're using Envoy v2 apis, so the relevant high level config is in the cluster object here.

If you read that, you'll notice the hosts field references the type field. This type field tells envoy how to handle discovery/resolution. The full details of that mechanism is here.

The default kubernetes installation have DNS and service discovery built-in. You can find respective pods in kube-system namespace.

$ kubectl get pods -n kube-system

[...]
kube-dns-6c7b8dc9f9-ngdq2                                  4/4     Running   0          25h
kube-dns-6c7b8dc9f9-pctnl                                  4/4     Running   0          26h
kube-dns-autoscaler-844c9d9448-sswll                       1/1     Running   0          27h
[...]

Up to version 1.12 kubernetes used kube-dns for DNS resolving and service discovery (hence the pod's name). Currently it uses CoreDNS.
Note about the naming:

Note: The CoreDNS Service is named kube-dns in the metadata.name field.
This is so that there is greater interoperability with workloads that relied on the legacy kube-dns Service name to resolve addresses internal to the cluster. Using a Service named kube-dns abstracts away the implementation detail of which DNS provider is running behind that common name.

So, all DNS queries are actually going to those pods, and are resolved by those.


When it comes to Istio, things are a bit more involved. The above works for default kubernetes services ,any custom ServiceEntrys (for examplet those added by Istio) will not be recognized.

In addition to capturing application traffic, Istio can also capture DNS requests to improve the performance and usability of your mesh. When proxying DNS, all DNS requests from an application will be redirected to the sidecar, which stores a local mapping of domain names to IP addresses. If the request can be handled by the sidecar, it will directly return a response to the application, avoiding a roundtrip to the upstream DNS server. Otherwise, the request is forwarded upstream following the standard /etc/resolv.conf DNS configuration.

While Kubernetes provides DNS resolution for Kubernetes Services out of the box, any custom ServiceEntrys will not be recognized. With this feature, erviceEntry addresses can be resolved without requiring custom configuration of a DNS server. For Kubernetes Services, the DNS response will be the same, but with reduced load on kube-dns and increased performance.

This functionality is also available for services running outside of Kubernetes. This means that all internal services can be resolved without clunky workarounds to expose Kubernetes DNS entries outside of the cluster.
Source

Related