Skip to content

Wave 6 — DNS (in-cluster)

This wave only deploys external-dns (RFC2136). It updates BIND. It is not a nameserver.

If laptops cannot already resolve k8s.home.example.com via your LAN resolver → BIND setup, this Deployment will write records that nobody asks for. Do the local DNS page first (zone, TSIG, Unbound/router forward, dig from a laptop).

Validation

Do not sync this Application until a laptop (not a cluster pod) already resolves the zone:

dig +short dummy.k8s.home.example.com   # or your wildcard
# must be the ingress VIP (10.0.0.30 in the examples). NXDOMAIN / public IP = stop.

Wave 6 only writes updates. It cannot invent a nameserver.

What this repo ships

One Deployment, RFC2136, one zone. Args live in values/external-dns/deployment.yaml.

Must change:

Flag / object Example
--rfc2136-host BIND LAN IP (10.0.0.2)
--rfc2136-zone k8s.home.example.com
--domain-filter same zone
--rfc2136-tsig-keyname externaldns-key
Secret tsig / key secret Sealed TSIG secret (see secrets)

The pod will CrashLoop until that Secret exists. Wave 1 must be Healthy before you seal it.

Skip: delete applications/external-dns.yaml and use a wildcard A record on the router, as described in the DNS page.

Cloudflare instead

Replace the args with --provider=cloudflare and a sealed API token. Do not leave RFC2136 flags pointing at example IPs. That path updates public DNS; it does not create *.k8s.home.example.com on the LAN.

Validation

After the first Ingress exists:

kubectl -n external-dns logs deploy/external-dns   # not CrashLoop; TSIG errors = wrong Secret
# BIND log should show UPDATE; then from a laptop:
dig +short grafana.k8s.home.example.com

CrashLoop usually means the TSIG Secret is missing (wave 1 + secrets). Empty dig after a Healthy pod: router/Unbound is not forwarding the zone — that is a DNS problem, not Argo.

Ownership TXT records use prefix external-dns- and owner-id homelab. Leave those unique if a second cluster ever shares the zone.