Kubernetes
Serving cluster DNS (services, pods, SRV and PTR) from the Kubernetes API.
[kubernetes]
enabled = true
cluster_domain = "cluster.local"
# kubeconfig = ""
[kubernetes.ttl]
service = 30
pod = 30
srv = 30
ptr = 30
Answers cluster DNS for services and pods directly from the Kubernetes API, so one resolver serves both cluster names and the public namespace.
Off by default.
Connecting to the API
Leave kubeconfig empty to use the in-cluster service account when running
inside the cluster. Outside it, $KUBECONFIG is used when set (a
colon-separated list is merged), and ~/.kube/config otherwise. Set
kubeconfig to a path to use a specific file; an explicit path wins over the
in-cluster service account. sdns -t checks that an explicit path is a
regular file it can open, so a typo is caught before a restart.
sdns connects once, at startup. If that first connection fails (no usable
config, or the API does not answer), it logs Failed to connect to Kubernetes
API and does not retry: names under cluster_domain get SERVFAIL until sdns
is restarted. Reverse lookups still fall through to normal resolution.
Names served
Under cluster_domain (default cluster.local):
- Service A/AAAA records
- Pod A/AAAA records
- SRV records for named service ports
- PTR records for reverse lookups of cluster addresses
Anything outside cluster_domain falls through to normal resolution, which is
what makes running this alongside recursive resolution useful rather than
requiring a second resolver behind it.
TTLs
The [kubernetes.ttl] block sets per-record-type TTLs in seconds, all 30 by
default. Cluster records change when the cluster changes, so these are short on
purpose; raise them only if you know your workloads are stable and you want to
cut lookup volume.
Watching it
dns_kubernetes_queries_total queries entering the middleware
dns_kubernetes_answered_total queries it answered, SERVFAIL included
dns_kubernetes_errors_total failures writing the response
dns_kubernetes_write_errors_total failures writing the response
Both error counters count only failed writes to the client; they move
together. They do not see the API. Until the informers have synced, and for
the whole run when the startup connection failed, names under cluster_domain
get SERVFAIL, and those replies count as answered. To tell whether the API side
is healthy, read the log: Kubernetes DNS middleware initialized reports
k8s_connected, Kubernetes caches synced marks the first full sync, and
Failed to connect to Kubernetes API or Kubernetes client stopped with error
mark failures.