How Do You Configure CoreDNS in Kubernetes?

intermediate|dnsdevopssreplatform engineerCKA
TL;DR

CoreDNS is configured via a ConfigMap called 'coredns' in the kube-system namespace. The configuration uses a Corefile format with plugins for Kubernetes service discovery, caching, forwarding external queries, logging, and health checks. You can customize DNS behavior by editing this ConfigMap.

Detailed Answer

CoreDNS is the default DNS server in Kubernetes since version 1.13. Its configuration is stored in a ConfigMap and uses a plugin-based architecture defined in a Corefile.

Viewing the Default Configuration

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

Default Corefile:

.:53 {
    errors
    health {
        lameduck 5s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    prometheus :9153
    forward . /etc/resolv.conf {
        max_concurrent 1000
    }
    cache 30
    loop
    reload
    loadbalance
}

Plugin Breakdown

| Plugin | Purpose | |---|---| | errors | Logs errors to stdout | | health | Provides health check endpoint at :8080/health | | ready | Provides readiness endpoint at :8181/ready | | kubernetes | Serves DNS for Kubernetes Services and Pods | | prometheus | Exposes metrics at :9153/metrics | | forward | Forwards non-cluster queries to upstream DNS | | cache | Caches DNS responses (30 seconds default) | | loop | Detects and stops forwarding loops | | reload | Auto-reloads Corefile on ConfigMap changes | | loadbalance | Randomizes DNS response order for round-robin |

Customizing CoreDNS

Forward Specific Domains to Custom DNS

Route corporate domain lookups to an internal DNS server:

.:53 {
    errors
    health
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

# Custom domain forwarding
internal.corp:53 {
    errors
    cache 30
    forward . 10.0.0.53 10.0.0.54
}

staging.mycompany.com:53 {
    errors
    cache 30
    forward . 10.10.0.53
}

Add Static DNS Entries

Use the hosts plugin for static entries:

.:53 {
    errors
    health
    ready
    hosts {
        10.0.0.100 legacy-app.internal
        10.0.0.101 legacy-db.internal
        fallthrough
    }
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

The fallthrough directive is important — it allows queries not matched by the hosts plugin to continue to the next plugin.

Enable DNS Logging

Add the log plugin for query logging (useful for debugging but adds overhead):

.:53 {
    log
    errors
    health
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

Applying Changes

Edit the ConfigMap:

kubectl edit configmap coredns -n kube-system

The reload plugin automatically detects changes and reloads the configuration. You can verify by checking CoreDNS logs:

kubectl logs -n kube-system -l k8s-app=kube-dns -f
# [INFO] Reloading
# [INFO] plugin/reload: Running configuration SHA changed

Scaling CoreDNS

For large clusters, CoreDNS may need scaling:

# Scale manually
kubectl scale deployment coredns -n kube-system --replicas=4

# Or use the dns-autoscaler addon
kubectl get deployment dns-autoscaler -n kube-system

The DNS autoscaler adjusts CoreDNS replicas based on the number of nodes and cores in the cluster.

CoreDNS Performance Tuning

Increase Cache TTL

cache 60    # Cache for 60 seconds instead of 30

Prefetch Popular Records

cache 30 {
    prefetch 10 60s 10%    # Prefetch when a record is requested 10+ times
}

Node-Local DNS Cache

For large clusters, deploy NodeLocal DNSCache to reduce CoreDNS load:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml

NodeLocal DNSCache runs a DaemonSet that caches DNS queries on each node, reducing latency and CoreDNS load.

Monitoring CoreDNS

# Check CoreDNS Pod health
kubectl get pods -n kube-system -l k8s-app=kube-dns

# View metrics
kubectl port-forward -n kube-system svc/kube-dns 9153:9153
curl http://localhost:9153/metrics

# Key metrics to monitor:
# coredns_dns_requests_total - Total DNS requests
# coredns_dns_responses_total - Total responses by rcode
# coredns_dns_request_duration_seconds - Latency histogram
# coredns_cache_hits_total - Cache hit rate

Why Interviewers Ask This

Interviewers ask this to test whether you can troubleshoot DNS issues and customize DNS behavior in production clusters — a common operational requirement.

Common Follow-Up Questions

How do you forward specific domains to custom DNS servers?
Add a server block in the Corefile for the domain with a forward plugin pointing to your custom DNS server. For example, forward .internal.corp 10.0.0.53.
How do you add custom DNS entries?
Use the hosts plugin in the Corefile to define static DNS entries, or deploy ExternalDNS to sync with external DNS providers.
What is the impact of changing the CoreDNS ConfigMap?
CoreDNS automatically detects ConfigMap changes and reloads its configuration without restarting, thanks to the reload plugin.

Key Takeaways

  • CoreDNS configuration lives in the 'coredns' ConfigMap in kube-system.
  • The kubernetes plugin handles Service and Pod DNS records.
  • Forward plugin routes external DNS queries to upstream resolvers.

Related Questions

You Might Also Like