CoreDNS
Purpose
CoreDNS provides in-cluster DNS resolution for Lumie. This page is a reference document for the repo-managed CoreDNS workload override, the boundary between Git-managed and k3s-managed DNS configuration, and the operational assumptions behind node-local DNS pods.
Source Paths
| Path | Role |
|---|---|
lumie-infra/platform/coredns-config/argocd.yaml | Argo CD application for the CoreDNS override |
lumie-infra/platform/coredns-config/daemonset.yaml | Repo-managed CoreDNS DaemonSet replacement |
live kube-system/coredns ConfigMap | Supplies the Corefile and NodeHosts consumed by the DaemonSet |
Public Surface
The repo does not define a new DNS API. It changes how the existing cluster DNS service runs:
| Surface | Contract |
|---|---|
| Pod type | DaemonSet, not the k3s default Deployment |
| Namespace | kube-system |
| Image | rancher/mirrored-coredns-coredns:1.13.1 |
| Ports | 53/udp, 53/tcp, metrics on 9153/tcp |
| Config source | Existing ConfigMap named coredns in kube-system |
Why Lumie Uses A DaemonSet
The key design choice is documented directly in the manifest:
# platform/coredns-config/daemonset.yaml
# Deployed as DaemonSet (not the k3s default Deployment) to guarantee one
# CoreDNS replica per node including the control-plane.
dnsPolicy: Default
This gives the cluster one CoreDNS pod per node and avoids a bootstrap dependency loop by making the pods use the node resolver instead of waiting on cluster DNS to resolve cluster DNS.
Runtime Flow
Config Boundary
This slice has an important ownership split:
- The repo manages the CoreDNS workload shape through
daemonset.yaml. - The repo does not currently version the
Corefile. - The live cluster still carries the
kube-system/corednsConfigMap, owned by the k3s addon machinery, and the DaemonSet mounts that ConfigMap directly.
The live ConfigMap inspected on June 14, 2026 included:
- the
kubernetes cluster.localplugin; hosts /etc/coredns/NodeHosts;prometheus :9153;forward . /etc/resolv.conf.
That means DNS behavior can change outside Git if the addon-owned ConfigMap changes, even while the pod topology remains Git-managed.
Operational Notes
- The DaemonSet tolerates the control-plane taint so the master runs a DNS pod too.
priorityClassName: system-cluster-criticalkeeps CoreDNS in the critical system tier.readOnlyRootFilesystem: trueand a reduced capability set tighten the pod security posture while still allowing binding to port53.
Failure Modes
| Failure point | Impact |
|---|---|
| DaemonSet and ConfigMap drift apart | Pods start but fail readiness or serve unexpected DNS behavior |
dnsPolicy: Default removed | CoreDNS can deadlock during bootstrap waiting on itself |
| Control-plane toleration removed | The master loses its local DNS pod and cross-node lookups increase |
| ConfigMap changed outside Git | DNS answers shift with no matching repo diff |
Verification
kubectl get ds -n kube-system coredns
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
kubectl get configmap -n kube-system coredns -o yaml
rg -n "coredns|dnsPolicy: Default|system-cluster-critical" \
lumie-infra/platform/coredns-config