Back to Blog
Lesson 36 of the Kubernetes: Kubernetes Concepts & Your First Pod course
KubernetesAugust 24, 20264 min read

Understanding Service DNS in Kubernetes: A Practical Guide

Learn how Kubernetes uses CoreDNS for service discovery. Master internal DNS resolution to replace hardcoded IPs with stable, reliable service names.

KubernetesDNSCoreDNSDiscoveryNetworking
Man in Seattle's iconic visitor booth offering tourist information and brochures.

Previously in this course, we explored the role of Services and how to create a ClusterIP Service to provide stable networking. While those services provide a stable IP, managing IPs manually is a recipe for failure. In this lesson, we will look at how Kubernetes automates discovery using DNS, allowing your pods to talk to each other using simple, human-readable names.

How Kubernetes Resolves Service Names

In a dynamic environment, Pod IPs change constantly as they are created and destroyed. You cannot rely on them. Kubernetes solves this by running an internal DNS server, CoreDNS, which is itself a set of pods running in your cluster.

When you create a Service, the Kubernetes API server creates a DNS entry for it in CoreDNS. Because CoreDNS is configured as the upstream DNS resolver for every pod in the cluster, your applications don't need to know where a service lives—they just need to know its name.

The standard format for a service name is: service-name.namespace.svc.cluster.local

  • service-name: The name you defined in your Service manifest.
  • namespace: The namespace where the service resides.
  • svc.cluster.local: The cluster domain suffix.

If your pod is in the same namespace as the service, you can often just use service-name. However, using the Fully Qualified Domain Name (FQDN) is a best practice for cross-namespace communication.

CoreDNS: The Engine of Discovery

CoreDNS acts as the phonebook of your cluster. When a process inside a container attempts to connect to a service name, the request hits the CoreDNS pod. CoreDNS looks up the service's current virtual IP (ClusterIP) and returns it to the requester.

Flow diagram: Pod A -- "DNS Query: my-svc" → CoreDNS; B -- "Returns ClusterIP: 10.96.0.5" → Pod A; A -- "Traffic to 10.96.0.5" → Service my-svc; C -- "Load Balances" → Pod B

Worked Example: Testing DNS Resolution

To verify this, we will deploy a simple "busybox" container to act as our testing client and a standard Nginx service.

  1. Create the target service: Assuming you have an Nginx deployment named nginx-app, create a service manifest nginx-svc.yaml:
YAML
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - port: 80
  1. Deploy the test pod: Run an interactive busybox shell to test the connection:
Bash
kubectl run dns-test --rm -it --image=busybox -- sh
  1. Perform the lookup: Once inside the shell, use the nslookup command to resolve the service name:
Bash
nslookup nginx-service

You should see an output showing the address of nginx-service.default.svc.cluster.local pointing to your ClusterIP.

Hands-on Exercise

  1. Create a second namespace called testing.
  2. Move your nginx-service into that namespace (or create a new one there).
  3. From your dns-test pod in the default namespace, attempt to resolve the service using the full FQDN: nslookup nginx-service.testing.svc.cluster.local.
  4. Verify that the resolution succeeds.

Common Pitfalls

  • Namespace Isolation: A common mistake is trying to reach a service in another namespace using only its short name. Always use the FQDN when crossing namespace boundaries.
  • Firewalls and Network Policies: If DNS resolution works (the IP is returned) but the connection fails, the issue is likely a NetworkPolicy blocking traffic, not a DNS issue.
  • CoreDNS Issues: If nslookup returns a timeout or "server failure," check the status of your CoreDNS pods: kubectl get pods -n kube-system -l k8s-app=kube-dns.

FAQ

Does CoreDNS handle external domains? Yes. If a query doesn't match an internal service, CoreDNS forwards the request to your cloud provider's DNS (like AWS Route53 or Google Cloud DNS).

Can I use custom names for services? The DNS name is strictly bound to the metadata.name field of your Service resource.

Does DNS work for Pods directly? Yes, but you must create a "Headless Service" (setting clusterIP: None in the manifest). Otherwise, DNS only points to the stable Service IP, not individual Pod IPs.

Recap

We've moved beyond hardcoded IPs by leveraging CoreDNS. By using service names like my-service.default.svc.cluster.local, your applications remain decoupled from the volatile nature of Pod lifecycles. This is a foundational step toward building resilient, scalable systems that behave predictably in production.

Up next: We will look at how to manage Environment-Specific Configuration to ensure our manifests are portable across dev, staging, and production.

Similar Posts