CoreDNS itself is a DNS server, but it can also act as a DNS client, and when it does, it has a concept called "autopath" that can drastically reduce the number of DNS lookups your applications make.
Let’s see this in action. Imagine you have a simple application that needs to talk to a service named my-service.
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: ubuntu
command: ["sleep", "3600"]
ports:
- containerPort: 80
If you were to exec into this pod and try to ping my-service, it would fail. Your application, by default, doesn’t know how to resolve my-service. It needs a DNS server, and in Kubernetes, that’s usually CoreDNS.
The default Kubernetes DNS setup for a pod looks something like this in /etc/resolv.conf:
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
Notice the search directive. This tells the DNS resolver to try appending different domain suffixes to your query if the initial lookup fails. So, if you query my-service, the resolver will try:
my-service.default.svc.cluster.localmy-service.svc.cluster.localmy-service.cluster.localmy-service(ifndots:5is met, meaning 5 dots or more in the name, which is not the case here, so it might not even try this depending on the resolver implementation)
This is where CoreDNS’s autopath plugin comes in. When enabled, CoreDNS, acting as the upstream resolver for your pods, can intelligently shorten these search paths based on the context of the query.
Here’s how CoreDNS is typically configured in Kubernetes. You’ll find a ConfigMap named coredns in your kube-system namespace. The Corefile within this ConfigMap is what dictates CoreDNS’s behavior. A typical Corefile might look like this:
.: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
cache 30
loop
reload
loadbalance
}
The key part for autopath is within the kubernetes plugin. When you enable autopath, you’re telling CoreDNS: "If a pod queries for a short name (like my-service), and that name could be a service within the cluster, try to resolve it directly as a cluster-internal name first, before falling back to external lookups or the full search path."
The autopath plugin isn’t explicitly named in the Corefile like kubernetes or forward. Instead, its behavior is controlled by specific options within the kubernetes plugin itself, primarily related to how it handles short names and the search directive. The kubernetes plugin, when configured with pods insecure, fallthrough, and appropriate ttl values, implicitly uses logic similar to what autopath provides by trying to resolve names within the cluster’s DNS zone first.
Let’s assume your CoreDNS deployment has been configured to optimize for this. A more modern or optimized Corefile might look like this, with autopath effectively baked into the kubernetes plugin’s behavior for short names:
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
# The autopath logic is implicitly handled here when querying short names
# It prioritizes cluster-internal resolution.
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
When your my-app pod queries for my-service, and the kubernetes plugin is active, CoreDNS will perform a lookup for my-service.default.svc.cluster.local (assuming my-app is in the default namespace). If it finds it, it returns the IP address of my-service. Crucially, it doesn’t need to go through the entire search list defined in /etc/resolv.conf.
This significantly reduces the number of DNS queries your applications make, especially in environments with many microservices. Instead of multiple sequential queries for service.namespace.svc.cluster.local, service.svc.cluster.local, etc., CoreDNS can often resolve it with a single, intelligently constructed query.
The "autopath" behavior is really about how the kubernetes plugin interprets short names and leverages the cluster.local domain. When a pod makes a query for a name that doesn’t contain any dots (e.g., my-service), the kubernetes plugin intercepts it. It then tries to resolve it as my-service.<pod-namespace>.svc.cluster.local. If this lookup succeeds, it returns the IP. If it fails, then it might fall through to other mechanisms, including the search list in the pod’s resolv.conf. The key is that the cluster-internal resolution is prioritized for these short names.
The real magic happens with how CoreDNS caches these results and how the kubernetes plugin is configured to prioritize cluster-internal lookups for unqualified names. It’s not a separate plugin you add; it’s a behavioral optimization within the kubernetes plugin’s handling of short names.
The next thing you’ll want to investigate is how to make your services discoverable using FQDNs and the implications for network policies.