Skip to content

DNS

external-dns watches Traefik's IngressRoutes (the traefik-proxy source) and writes to Cloudflare. It takes each hostname from the Host(...) matchers in a route's rules; a route without one, such as the outpost callback, publishes nothing. The chart grants the RBAC for Traefik's CRDs itself. Only the traefik.io API group is watched — the legacy traefik.containo.us group is off by default.

domainFilters must name the Cloudflare zone, not the subdomain in use. A zone matches only if it equals the filter or is a subdomain of it, so cbc.gewis.nl excludes the gewis.nl zone — external-dns then finds no zone to write into and reports the very misleading "All records are already up to date". The filter is gewis.nl; scoping comes from ownership instead:

Setting Effect
txtOwnerId: cbc-test only touches records carrying its own ownership TXT
policy: upsert-only creates and updates its own records, never deletes them
txtPrefix: edns- keeps the ownership TXT off the CNAME's name, which Cloudflare forbids

upsert-only, not sync. Under sync a record disappears the moment its route does — and a route can vanish for reasons that have nothing to do with the hostname being retired, such as Traefik's CRDs being replaced, which takes every IngressRoute with them. Recreating the record afterwards is not symmetric: the gewis.nl SOA minimum is 1800 s, so every downstream resolver serves NODATA for up to half an hour after the name comes back, and the CNAME is correct in Cloudflare the whole time. A stale record left behind by a retired route is cheap in comparison — it is deletable by hand, and its ownership TXT says which cluster wrote it.

The DNS target is the external-dns.alpha.kubernetes.io/target annotation on each IngressRoute, set to router02.net.gewis.nl. The target is a hostname, so records are CNAMEs onto the router, which owns the public address; Traefik's own address, 10.82.50.200, is private and useless from outside. A new route that forgets the annotation gets no usable record.

--cloudflare-record-comment tags every managed record; ownership itself is still the TXT, not the comment.