ConfigsApr 15, 2026·3 min read

ExternalDNS — Automate DNS Records from Kubernetes

Kubernetes controller that syncs Ingress, Service, and CRD objects with 40+ DNS providers — Route 53, Cloudflare, Google, Azure, and more.

Introduction

ExternalDNS closes the gap between Kubernetes and DNS: instead of hand-editing zone files every time a Service or Ingress changes, the controller watches the API server and reconciles records with whichever DNS provider you run. It supports dozens of providers — Route 53, Cloudflare, Google Cloud DNS, Azure DNS, PowerDNS, RFC 2136 — through a single CRD-free interface.

What ExternalDNS Does

  • Creates, updates, and deletes DNS records from Ingress, Service, and CRD objects
  • Uses TXT ownership records so multiple clusters can share a zone safely
  • Supports 40+ DNS providers via a pluggable backend interface
  • Reconciles on a configurable interval (default 60s) with a --once CI mode
  • Integrates with cert-manager and Gateway API for end-to-end HTTPS automation

Architecture Overview

ExternalDNS is a single Go controller that subscribes to Kubernetes source events, builds a desired-state graph from annotations, and diffs it against what the provider has. Each provider implements Records(), ApplyChanges(), and AdjustEndpoints() — so adding Hetzner DNS or a private UltraDNS backend is a matter of a few hundred lines of Go. The TXT registry layer stores owner=cluster-x metadata on each record to prevent cross-cluster interference.

Self-Hosting & Configuration

  • provider=aws|google|cloudflare|azure|... selects the backend
  • domainFilters restrict which zones the controller will touch
  • policy=sync|upsert-only controls deletion behavior; default upsert-only is safest
  • txtOwnerId tags records so multiple clusters can coexist in one zone
  • IAM credentials via IRSA (EKS), Workload Identity (GKE), or service principals (AKS)

Key Features

  • First-class support for Ingress, Service type=LoadBalancer, and Gateway API HTTPRoute
  • CRDs: DNSEndpoint lets any operator publish records without modifying source objects
  • Cloudflare proxy mode toggle via annotation
  • Multi-target records (geo, weighted) where the provider supports them
  • Metrics endpoint exposing reconcile counts, errors, and zone sizes

Comparison with Similar Tools

  • cert-manager — complementary; cert-manager issues certs, ExternalDNS points DNS at them
  • route53-kubernetes (deprecated) — AWS-only predecessor; superseded by ExternalDNS
  • Terraform DNS modules — static, not reactive to cluster changes
  • ingress-nginx annotations — no DNS automation built in
  • Knative Net — includes its own DNS integration but tied to serverless

FAQ

Q: Can I scope it to one namespace? A: Yes — --namespace flag restricts which sources the controller watches.

Q: What happens if two clusters manage the same record? A: With unique txtOwnerId values each cluster only touches records it owns. Without them, they fight.

Q: Does it support wildcards? A: Yes via external-dns.alpha.kubernetes.io/hostname: "*.foo.example.com" (provider-dependent).

Q: Is there a dry-run mode? A: Set dryRun=true and the controller logs intended changes without applying them.

Sources

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets