Skip to main content
RunBook Academy

KubernetesCXIII · Kubernetes DNS Advanced TroubleshootingDNS advanced troubleshooting

CoreDNS advanced configuration — Corefile, plugins, and tuning

Advanced⏱ ~17 minkubectl

What you'll learn

  • Configure CoreDNS with custom Corefile
  • Apply plugins (cache, forward, prometheus, ready)
  • Tune CoreDNS for performance and reliability
  • Apply the operational discipline of testing Corefile changes

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

CoreDNS is the cluster DNS. This lesson walks the Corefile format, the plugins, the tuning, and the operational discipline.

The Corefile

flowchart LR
    A[Corefile] --> B[Server blocks]
    B --> C["Plugins: chain of middleware"]
    C --> C1[cache]
    C --> C2[forward]
    C --> C3[kubernetes]
    C --> C4[log]
    C --> C5[errors]
    C --> C6[prometheus]
    C --> C7[ready]
    C --> C8[loop]
    C --> C9[reload]

The Corefile is CoreDNS’s configuration file. It defines:

  • Server blocks. Zones the server is authoritative for.
  • Plugins. A chain of middleware that processes each query.
.: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 {
       prefer_health
    }
    cache 30
    loop
    reload
    loadbalance
}

This is the default Corefile. Each plugin has a specific role.

The plugins

flowchart LR
    A[Plugins] --> B[cache]
    B --> B1[In-memory cache with TTL]
    B --> B2[Reduces upstream queries]
    A --> C[forward]
    C --> C1[Forwards to upstream DNS]
    A --> D[kubernetes]
    D --> D1[Cluster service records]
    A --> E[log]
    E --> E1[Query logging]
    A --> F[errors]
    F --> F1[Error logging]
    A --> G[prometheus]
    G --> G1["Metrics on :9153"]
    A --> H[ready]
    H --> H1[Health endpoint]
    A --> I[loop]
    I --> I1[Loop detection]
    A --> J[reload]
    J --> J1[Corefile reload]

The plugin roles:

  • cache. In-memory cache with TTL. Reduces upstream DNS queries.
  • forward. Forwards queries to upstream DNS (cloud DNS, corporate DNS).
  • kubernetes. Watches the Kubernetes API; serves service records (A, SRV, PTR).
  • log. Logs each query.
  • errors. Logs errors.
  • prometheus. Exposes metrics on :9153.
  • ready. Reports ready status; used by the Service’s readinessProbe.
  • loop. Detects forwarding loops.
  • reload. Allows hot-reloading of the Corefile.

Tuning: cache TTL

cache 30 {
    success  30
    denial   30
    prefetch 10
}

The cache TTL:

  • success. How long to cache successful responses.
  • denial. How long to cache denial (NXDOMAIN).
  • prefetch. How long before expiry to prefetch (refresh the cache).

A higher TTL reduces upstream load but serves stale records. A lower TTL is fresh but increases upstream load. 30 seconds is a reasonable default.

Tuning: forward upstreams

forward . 8.8.8.8 8.8.4.4 {
    prefer_health
    max_fails 3
    expire 10s
}

The forward configuration:

  • Upstream DNS. 8.8.8.8 8.8.4.4 (Google DNS), or cloud DNS, or corporate DNS.
  • prefer_health. Try the upstream with better health first.
  • max_fails. Mark upstream as down after 3 failures.
  • expire. After 10 seconds, retry the down upstream.

In production, point to the cloud’s DNS (e.g., AWS VPC DNS at 169.254.169.253) for service discovery within the cloud.

Tuning: replicas

apiVersion: apps/v1
kind: Deployment
metadata:
  name: coredns
  namespace: kube-system
spec:
  replicas: 3  # default is 2

CoreDNS replicas:

  • 2 replicas (default). Sufficient for small clusters.
  • 3+ replicas. For high DNS query rates; HA across nodes.
  • autoscaling. HPA on CPU for variable load.

For production, 3+ replicas is recommended.

Tuning: node-local cache

flowchart LR
    A[Pod] -->|DNS query| B[Node-local cache]
    B -->|cache miss| C[CoreDNS]
    C -->|query| D[Upstream DNS]
    D -->|response| C
    C -->|response| B
    B -->|cache| A

Node-local DNS cache (nodelocaldns) runs a DNS cache on every node. Pods query the node-local cache first; cache misses go to CoreDNS.

The benefits:

  • Reduced CoreDNS load.
  • Lower DNS latency for cached queries.
  • Resilience to CoreDNS failures (cached queries still resolve).

The installation:

kubectl apply -f https://k8s.io/examples/admin/dns/nodelocaldns.yaml

Quiz

Knowledge check · 4 questions

  1. Q1. What does the CoreDNS `cache` plugin change for a repeated cluster lookup?

  2. Q2. Increasing the CoreDNS cache TTL delays how quickly clients see endpoint changes.

  3. Q3. Recover cluster DNS after a Corefile edit stops CoreDNS from starting.

    An operator edits the coredns ConfigMap to add an upstream and both CoreDNS replicas enter CrashLoopBackOff within a minute of each other. Name resolution fails cluster-wide. `kubectl logs -n kube-system -l k8s-app=kube-dns --previous` ends with `Corefile:12 - Error during parsing: Unknown directive 'foward'`. The cluster has no node-local cache installed.

  4. Q4. Which CoreDNS plugin exposes metrics and on which port, and which plugin prevents a forwarding loop from taking CoreDNS down at startup?

Passing score: 75%. Answers are checked in this browser.

The operational discipline

CoreDNS tuning in production rests on five non-negotiable elements:

  • Test Corefile changes. A missing brace breaks CoreDNS startup.
  • Tune cache TTL. Based on query patterns.
  • Use node-local cache. Reduces CoreDNS load.
  • Monitor CoreDNS metrics. prometheus plugin exposes key metrics.
  • Document the Corefile. Comments in the Corefile; runbook entry.

CoreDNS is the cluster DNS; its availability is critical. The discipline is to test changes in staging and monitor in production.