CoreDNS is a DNS server written in Go in which almost every feature is a plugin. A short configuration file, the Corefile, selects which plugins run and in what order for each DNS zone, so the same binary can act as a Kubernetes service-discovery server, a caching resolver, a forwarder to upstream DNS, or an authoritative server for zone files. It addresses the need for dynamic service discovery: in a cluster where pods start, stop and move constantly, applications must find each other by stable names rather than IP addresses, and the DNS server has to follow the cluster’s state. CoreDNS was created in March 2016 by Miek Gieben, then at Google, joined the CNCF in 2017 and reached Incubating in February 2018. It graduated on January 24, 2019, and Kubernetes 1.13 made it the default cluster DNS the year before that. Release 1.14.5 followed in July 2026.
CNCF daily · Sprint 1, day 3 · Coordination & Service Discovery
At a glance
| Category | Coordination & Service Discovery |
| CNCF status | Graduated. Joined in 2017; Incubating February 2018; graduated January 24, 2019 |
| Written in | Go, a single static binary |
| License | Apache 2.0 |
| Configuration | Corefile: server blocks per zone, each with an ordered chain of plugins |
| Plugins | Dozens built in (kubernetes, forward, cache, file, etcd, prometheus, rewrite and more), plus external plugins |
| Transports | DNS over UDP and TCP, TLS (DoT), HTTPS (DoH) and QUIC (DoQ) |
| Latest release | 1.14.5 (July 10, 2026) |
Architecture
flowchart TB
POD[Application pods<br/>resolv.conf points to cluster DNS] --> NLC[NodeLocal DNSCache<br/>optional per-node cache]
NLC --> SVC[kube-dns Service<br/>ClusterIP]
SVC --> CD[CoreDNS pods<br/>Deployment, 2 or more replicas]
subgraph CHAIN[Plugin chain in the Corefile]
P1[errors, health, ready] --> P2[kubernetes<br/>cluster.local zone]
P2 --> P3[prometheus<br/>metrics]
P3 --> P4[cache]
P4 --> P5[forward<br/>upstream resolvers]
end
CD --> CHAIN
API[Kubernetes API<br/>Services, EndpointSlices, Pods] -->|watch| P2
P5 --> UP[Upstream DNS<br/>VPC resolver or corporate DNS]
P3 --> MON[Prometheus and Grafana]
| Component | Responsibility |
|---|---|
| Corefile | Declares server blocks (zones and ports) and the plugins each one runs. Changes are picked up by the reload plugin without a restart. |
| kubernetes plugin | Watches Services, EndpointSlices and Pods through the Kubernetes API and answers names such as orders.payments.svc.cluster.local. |
| forward plugin | Sends every name outside the cluster domain to upstream resolvers, with health checks and load balancing across them. |
| cache plugin | Caches positive and negative answers to reduce latency and upstream load. |
| prometheus plugin | Exposes request counts, latency histograms and response codes on a metrics port. |
| health, ready, loop | Liveness and readiness endpoints, and detection of forwarding loops that would otherwise crash the server. |
| Other plugins | rewrite changes names or responses, file serves zone files, etcd reads records from etcd, and autopath shortens search-path lookups. |
Design principle. CoreDNS is a small core that chains plugins, and a query passes through them in a fixed order until one answers it. Capabilities are added by choosing plugins rather than by running a different server, and teams can write their own. In Kubernetes this means service discovery is a live view of the API server, not a copy that can fall behind.
Production reference design
Cluster DNS on EKS, GKE, AKS or on-premises Kubernetes. Most distributions already install CoreDNS (kubeadm, K3s and EKS and AKS add-ons do), so the work is mainly tuning, scaling and observing it:
- Know where it is installed. In kubeadm clusters it runs as a Deployment named
corednsinkube-system, behind a Service calledkube-dns, configured by a ConfigMap. Check the current state:kubectl -n kube-system get deploy coredns kubectl -n kube-system get configmap coredns -o yaml - Review the Corefile. A typical production configuration looks like this:
Compare it against the default shipped with your distribution before editing, as plugin options differ between versions.apiVersion: v1 kind: ConfigMap metadata: { name: coredns, namespace: kube-system } data: 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 } - Send private domains to the right place by adding a server block, for example forwarding
corp.example.comto internal DNS servers:corp.example.com:53 { errors cache 30 forward . 10.20.0.2 10.20.0.3 } - Scale it with the cluster. Run at least two replicas spread across nodes and zones, add a PodDisruptionBudget, and scale replicas with cluster size using the cluster-proportional-autoscaler, or the autoscaling your managed service provides.
- Add NodeLocal DNSCache on busy clusters. It runs a CoreDNS-based cache on every node, keeps most lookups local and avoids conntrack pressure on UDP DNS traffic.
- Monitor it. Scrape the metrics port and alert on SERVFAIL rate, request latency, cache hit ratio and pod restarts.
For a standalone resolver outside Kubernetes, the official Helm chart (helm repo add coredns https://coredns.github.io/helm) deploys CoreDNS with a custom Corefile. Typical production uses include in-cluster service discovery, conditional forwarding to corporate or cloud private zones, split-horizon DNS and a caching layer in front of slow upstream resolvers.
Operational considerations
- DNS is a shared dependency. Slow or failing cluster DNS shows up as application timeouts. Run multiple replicas across zones and set a PodDisruptionBudget.
- Mind the
ndotsdefault. Kubernetes setsndots:5in pod resolv.conf, so an external name can trigger several failed lookups before it resolves. Use fully qualified names with a trailing dot, lowerndotsper workload, or enableautopath. - Size for query volume, not pod count. Watch queries per second and CPU, and keep the cache enabled. Large clusters benefit from NodeLocal DNSCache and from limiting upstream concurrency.
- Forward carefully. Point
forwardat reliable resolvers, avoid loops withloop, and test failover when an upstream is unreachable. - Keep it patched. CoreDNS releases frequently, and releases such as 1.14.1 included fixes for vulnerabilities in the Go toolchain. Upgrade it with the cluster and test Corefile changes before rolling them out.
Adoption
- The CNCF graduation announcement named Bose, Hellofresh, Skyscanner, SoundCloud, Trainline and Zalando as production users, and Infoblox, which uses CoreDNS in its SaaS DNS service.
- Kubernetes ships CoreDNS as its default cluster DNS, so it runs in a very large share of Kubernetes clusters, including those on managed services.
- The project is maintained by a community of contributors and maintainers, with regular releases through 2026.
Alternatives
| Solution | Model | Best suited to |
|---|---|---|
| kube-dns | Older Kubernetes DNS add-on (dnsmasq and SkyDNS based) | Legacy clusters and GKE’s default cluster DNS |
| Unbound | Recursive, caching, validating resolver | Fast recursive resolution outside Kubernetes |
| BIND | Full authoritative and recursive DNS server | Traditional authoritative DNS with many zone features |
| PowerDNS | Authoritative and recursive servers with database backends | Hosting providers and API-driven zone management |
| Cloud resolvers (Route 53 Resolver, Cloud DNS) | Managed DNS | Teams that want no DNS servers to run |
Strengths and limitations
| Strengths | Limitations |
|---|---|
| Default cluster DNS in Kubernetes, with a well-understood setup | Plugin ordering and Corefile syntax take time to learn |
| Plugin chain allows rewriting, forwarding, caching and custom logic | Not a full-featured authoritative server like BIND or PowerDNS |
| Single static binary with a small footprint | DNS problems in clusters are hard to debug (ndots, conntrack, upstream limits) |
| Built-in metrics, health and readiness endpoints | Cluster DNS becomes a critical shared dependency |
| Modern transports (DoT, DoH, DoQ) and active development | External plugins vary in quality and maintenance |
Recommendation
Adopt CoreDNS as the cluster DNS in Kubernetes, since it is the default and the best-supported option, and invest in its operation: multiple replicas, metrics and alerts, a reviewed Corefile and NodeLocal DNSCache for busy clusters. Use it as a standalone forwarder or conditional resolver where its plugin model fits, and choose BIND or PowerDNS when you need a full authoritative DNS platform.
References: CNCF project page · CNCF: CoreDNS graduation announcement · CoreDNS documentation · CoreDNS 1.14.5 release notes · CoreDNS 1.14.1 release notes · CoreDNS on GitHub