Internal dns lookup in k8s using CoreDNS

DNS in Kubernetes is handled by CoreDNS. It runs as a pod in kube-system and automatically creates DNS records for every Service you create.

Internal DNS in our Voting App

All internal communication uses DNS service names — no hardcoded IPs:

voting-app → redis:6379      (resolves to 10.43.28.68)
voting-app → db:5432         (resolves to 10.43.34.195)
worker     → redis:6379      (resolves to 10.43.28.68)
worker     → db:5432         (resolves to 10.43.34.195)
result-app → db:5432         (resolves to 10.43.34.195)

If a pod restarts and gets a new IP — the Service ClusterIP stays the same, DNS still works, nothing breaks. That’s the whole point of Services and CoreDNS.

The format is always:

<service-name>.<namespace>.svc.cluster.local

Automatic DNS Records

When you apply a Service, CoreDNS automatically registers a DNS name so extra no config needed.

When we ran:

kubectl apply -f redis-service.yaml

CoreDNS automatically registered:

redis.voting.svc.cluster.local → 10.43.28.68

The format is always:

<service-name>.<namespace>.svc.cluster.local

Breaking it down:

redis          ← metadata.name in your service YAML
voting         ← metadata.namespace in your service YAML
svc            ← hardcoded, means it's a Service object
cluster.local  ← cluster domain, set at install time

Short Names Also Work

Within the same namespace you can use just the service name — CoreDNS appends the rest automatically via the search domain:

redis                            ← works inside voting namespace
redis.voting                     ← works from any namespace
redis.voting.svc.cluster.local   ← fully qualified, always works

This is why voting-app can connect to redis by name and it doesn’t need an IP address. CoreDNS resolves it to the ClusterIP.


Verify DNS from Inside a Pod

Exec into any pod and run nslookup:

k exec -it redis-7c84479b6c-8fzqw -n voting -- /bin/bash
nslookup db
nslookup redis

Output:CoreDNS IP is always 10.43.0.10 — that’s the ClusterIP of the kube-dns service.


resolv.conf Inside a Pod

Every pod gets this automatically injected:

cat /etc/resolv.conf
search voting.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.43.0.10
  • nameserver 10.43.0.10 — CoreDNS ClusterIP
  • search voting.svc.cluster.local — allows short names like redis to resolve

CoreDNS Config

The CoreDNS configuration lives in a ConfigMap:

k get configmap coredns -n kube-system -o yaml

Key sections in the Corefile:

.:53 {
    kubernetes cluster.local in-addr.arpa ip6.arpa {
      pods insecure
      fallthrough in-addr.arpa ip6.arpa
    }
    forward . /etc/resolv.conf
}
  • kubernetes cluster.local — handles all .cluster.local DNS lookups, reads from k8s API
  • forward . /etc/resolv.conf — forwards external DNS queries (google.com etc) to the node’s DNS

Node hostnames are also registered:

NodeHosts: |
    172.16.77.10 k3s-cp-01
    172.16.77.11 k3s-worker-01
    172.16.77.12 k3s-worker-02

External DNS

CoreDNS handles internal cluster DNS only. For external DNS we start pointing real domain names at your services we need

  • ExternalDNS — watches Services and Ingresses, creates records in Route53/Cloudflare/Azure DNS automatically
  • Technitium — manually add mealie.ash.local → 172.16.77.10
  • Ingress + cert-manager — routes external traffic and handles TLS
  • Host file – add to our local host file to acesss mealie.ash.local

Quick Reference

# check CoreDNS is running
k get pods -n kube-system | grep coredns

# check CoreDNS config
k get configmap coredns -n kube-system -o yaml

# test DNS from inside a pod
k exec -it <pod> -n <namespace> -- nslookup <service-name>
k exec -it <pod> -n <namespace> -- cat /etc/resolv.conf

# CoreDNS ClusterIP
k get svc kube-dns -n kube-system

(Visited 21 times, 1 visits today)

By Ash Thomas

Ash Thomas is a seasoned IT professional with extensive experience as a technical expert, complemented by a keen interest in blockchain technology.