Skip to main content
Service discovery ensures that microservices within a Kubernetes cluster can locate and communicate with each other without hard-coding IP addresses or hostnames. Kubernetes automates this process using environment variables and DNS, backed by EndpointSlices that track pod membership.
The image illustrates service discovery in a Kubernetes cluster, showing communication between Service A and Service B without hardcoding IP addresses or hostnames.

How Service Discovery Works

When pods are created, scaled, or terminated, Kubernetes updates EndpointSlices to record which pods back each Service. Although you can query these slices via the API server, Kubernetes provides higher-level abstractions to hide this complexity.
The image explains how service discovery works in Kubernetes, highlighting the use of EndpointSlices for automation, updates with pod changes, and the complexity of querying the Kubernetes API.

Service Discovery Mechanisms

MechanismDescriptionProsCons
Environment VariablesKubelet injects service host/port as env varsImmediate access
Zero additional deps
Static at pod start
Namespace-scoped
DNSCoreDNS (or kube-dns) auto-creates service recordsDynamic updates
Cross-namespace
Requires DNS service
Potential lookup latency

Environment Variables

When a pod is launched, the Kubelet generates environment variables for each Service in the same namespace. These include the service’s ClusterIP, ports, and protocol:
MY_APP_SERVICE_HOST=10.0.0.11
MY_APP_SERVICE_PORT=80
MY_APP_PORT=tcp://10.0.0.11:80
MY_APP_PORT_80_TCP=tcp://10.0.0.11:80
MY_APP_PORT_80_TCP_PROTO=tcp
MY_APP_PORT_80_TCP_PORT=80
MY_APP_PORT_80_TCP_ADDR=10.0.0.11
Example Service manifest that produces these variables:
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      name: my-app
      port: 80
      targetPort: 80
  type: ClusterIP
Service names are uppercased and dashes become underscores when generating environment variables. The Service must exist before the pod starts, since variables are injected at launch time.

DNS-Based Service Discovery

Deploy a DNS add-on (e.g., CoreDNS) to enable DNS lookups for Services. CoreDNS watches the Kubernetes API and automatically creates DNS records whenever Services change.
The image features the CoreDNS logo and mentions "New services" and "Creates a DNS record" alongside an API icon.
The image illustrates concepts related to DNS in Kubernetes, showing a network diagram with the Kubernetes logo and a symbol representing service discovery. It includes text about accessing services across namespaces and service discovery.

DNS Records

By default, Kubernetes creates both A and SRV records for each Service:
A record:
my-app.default.svc.cluster.local

SRV record:
_my-app._tcp.my-app.default.svc.cluster.local
Both records resolve to the service’s ClusterIP.

Shortened DNS Names

Depending on the client’s namespace and search path, you can drop portions of the full DNS name:
  • Outside the namespace: my-app.default
  • Inside the namespace: my-app
The pod’s /etc/resolv.conf (configured by the kubelet) controls this:
search backup-system.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5
DNS resolution first tries the pod’s namespace domain, then svc.cluster.local, and finally cluster.local.
If ndots is set too low, lookups may skip qualified names. Ensure options ndots:5 (or higher) to allow short names in-cluster.

Let’s launch a Service on our cluster to see service discovery in action.

References