Skip to main content

Understand in-cluster DNS (CoreDNS)

CoreDNS provides in-cluster DNS for every pod in your cluster. It runs as a Deployment in kube-system behind the kube-dns service, resolving cluster-internal queries and forwarding external requests to upstream resolvers. This page explains how CoreDNS resolves names, how to resolve private names through your own resolvers, why the API endpoint name must resolve publicly, how ndots lookups impact query performance, and how Syself Autopilot manages and scales the deployment. For CoreDNS itself, see the CoreDNS docs⁠.

In-cluster resolution and forwarding 

CoreDNS answers two kinds of in-cluster names:

  • Service names. my-svc.my-namespace.svc.cluster.local resolves to the Service's cluster IP. cluster.local is the cluster's DNS suffix, set by serviceDomain when the cluster is created. The full naming scheme is in the Kubernetes DNS for Services and Pods⁠ reference.
  • Pod-backed names. A headless Service (clusterIP: None) resolves to the individual pod IPs behind it, which is how StatefulSets get stable per-pod names.

Any query outside the cluster domain such as a public endpoint or internal network address is forwarded to the node's upstream resolver. You configure these resolvers using the dnsServers cluster variable. It sets the node's resolver and the kubelet's resolver file, which CoreDNS inherits.

Resolve private names through the cluster's upstream 

To resolve private hostnames, such as on-premises databases or VPC resources, set dnsServers on the Cluster object to your internal name servers:

cluster.yamlyaml
				spec:
  topology:
    variables:
      - name: dnsServers
        value: ["10.100.0.53"]
			

Because CoreDNS is managed by Syself Autopilot, per-zone techniques that require a Corefile edit, such as a stub-domain forward block for one internal zone, are not available. All non-cluster DNS traffic routes through the servers in dnsServers.

Point dnsServers at a DNS resolver that can serve both internal and external zones such as an on-premises nameserver reached over your VPN. See . This resolver must answer queries for your private domains directly and recursively forward all other requests to the public internet.

The API endpoint must resolve publicly 

The cluster's API endpoint name is where split DNS matters most. That name must resolve to the control-plane load balancer from Syself's side, not only from your own machine, because the controllers that manage your cluster connect through the same name.

Warning

Never give the API endpoint a name that only you can resolve, an /etc/hosts entry, or a split-horizon view that answers differently inside your own network. If the name does not resolve to the load balancer from the management side, the cluster never finishes provisioning and the control plane remains unavailable. Publish a real, public A record for the endpoint name. See for the endpoint DNS setup.

Restricting who may reach the API is a separate concern from resolving its name; that is the allowlist's responsibility, not DNS's. See .

How ndots affects lookup performance 

By default, Kubernetes configures /etc/resolv.conf inside pods with ndots: 5. If a queried domain contains fewer than five dots, the resolver appends each local search domain (<namespace>.svc.cluster.local, svc.cluster.local, cluster.local) before attempting the name as written. Looking up an external endpoint such as api.example.com (which has only two dots) therefore sends api.example.com.<namespace>.svc.cluster.local, api.example.com.svc.cluster.local, and api.example.com.cluster.local first, each returning NXDOMAIN, before the resolver finally queries api.example.com against upstream DNS.

To eliminate this query overhead on high-throughput workloads, configure the pod specification directly:

  • Use fully qualified domain names (FQDN): Append a trailing dot (api.example.com.) to external names to bypass the search list.
  • Lower ndots: Set a custom ndots value (for example, ndots: 2) in the pod's dnsConfig⁠.

How Syself scales CoreDNS 

CoreDNS sits on the path of nearly every connection, so its replica count must grow with the cluster. Syself Autopilot runs the cluster-proportional-autoscaler⁠ against the CoreDNS Deployment and sizes it from the cluster's node and core counts:

Setting Value Effect
nodesPerReplica 8 one CoreDNS replica for every 8 nodes
coresPerReplica 256 one replica for every 256 vCPUs across the cluster
preventSinglePointFailure true at least 2 replicas once the cluster has more than one node

The autoscaler takes the higher of the node-based and core-based counts, so CoreDNS scales up as you add nodes and back down as you remove them. You do not set a replica count, and you do not edit the Corefile. Both are reconciled by the platform, and a manual change is overwritten on the next reconciliation.

Where to go next