CoreDNS is Kubernetes’ default DNS provider, and Helm is the standard package manager for Kubernetes. Deploying CoreDNS with Helm gives you a robust, configurable, and easily upgradeable DNS service for your cluster.
Let’s get CoreDNS running in a Kubernetes cluster using Helm. First, ensure you have Helm installed and configured to talk to your cluster.
helm version
If that works, you’re good to go. Now, we’ll add the official coredns chart repository to Helm.
helm repo add coredns https://coredns.github.io/helm-charts
helm repo update
This fetches the latest information about available CoreDNS charts. Next, we’ll install the coredns chart. It’s common to deploy it into the kube-system namespace, as DNS is a core cluster component.
helm install coredns coredns/coredns --namespace kube-system --create-namespace
This command installs the CoreDNS chart from the coredns repository, names the deployment coredns, places it in the kube-system namespace, and creates the namespace if it doesn’t exist.
After a minute or two, you can check the status of the CoreDNS pods:
kubectl get pods -n kube-system -l app.kubernetes.io/name=coredns
You should see one or more pods in a Running state. If they aren’t running, check the logs for the coredns pod:
kubectl logs <coredns-pod-name> -n kube-system
The default configuration is usually sufficient for most clusters. It sets up CoreDNS to resolve cluster-internal DNS names (like kubernetes.default.svc.cluster.local) and forwards external DNS queries to the upstream DNS servers configured on your Kubernetes nodes.
You can verify CoreDNS is working by exec-ing into a pod and performing DNS lookups.
kubectl exec -it <any-app-pod> -- sh
nslookup kubernetes.default
The output should show the ClusterIP of the Kubernetes API server.
The real power of deploying CoreDNS with Helm comes from its configuration. The values.yaml file for the chart allows you to customize nearly every aspect of CoreDNS. You can override the default configuration by creating your own values.yaml file and passing it to helm install or helm upgrade.
For example, to add a custom DNS record for an internal service, you might create a my-values.yaml file like this:
servers:
- zones:
- zone: "mycompany.local"
# This is a simplified example. For more complex configurations,
# you'd use the 'fallthrough' or 'forward' directives.
# Here, we're directly mapping a name to an IP.
records:
- name: "app1.mycompany.local"
type: "A"
ttl: 300
content: "192.168.1.100"
Then, you’d upgrade your existing CoreDNS deployment:
helm upgrade coredns coredns/coredns --namespace kube-system -f my-values.yaml
This would instruct CoreDNS to answer queries for app1.mycompany.local with 192.168.1.100 directly, without querying upstream resolvers.
Another common customization is to change the upstream forwarders. If your cluster nodes are using specific DNS servers, but you want CoreDNS to use different ones (e.g., corporate DNS servers), you can modify the forward plugin configuration:
servers:
- zones:
- zone: "root"
scheme: "dns://"
# Forward all other queries to these specific DNS servers
forward:
- "8.8.8.8:53"
- "8.8.4.4:53"
Applying this with helm upgrade would change where CoreDNS sends queries for domains it doesn’t handle internally.
The coredns/coredns Helm chart also allows fine-grained control over individual CoreDNS plugins. You can enable, disable, or configure plugins like cache, prometheus, kubernetes, acl, auto, and loop directly through the values.yaml. For instance, to enable the prometheus plugin for metrics collection:
servers:
- zones:
- zone: "root"
plugins:
- name: "prometheus"
parameters: ":9153" # Expose metrics on port 9153
This would start a metrics endpoint on port 9153 within the CoreDNS pods, allowing Prometheus to scrape DNS-related statistics.
The kubernetes plugin is crucial; it’s what allows CoreDNS to resolve Kubernetes service and pod names. Its configuration within the Helm chart dictates how it interacts with the Kubernetes API. You can specify CIDR blocks for services and pods, and control whether it watches endpoints.
When troubleshooting, remember that CoreDNS is a highly configurable system. The Corefile that CoreDNS uses is generated by the Helm chart based on your values.yaml. You can inspect the generated Corefile by exec-ing into a CoreDNS pod and viewing the file at /etc/coredns/Corefile.
kubectl exec -it <coredns-pod-name> -n kube-system -- cat /etc/coredns/Corefile
This file is the definitive source of truth for how your CoreDNS is configured.
The next step after getting CoreDNS deployed and customized is typically to monitor its performance and health using metrics or to implement advanced features like DNS-based access control.