Files
matsandClaude Sonnet 5.5 242bcd98d9 migrate: read the live address overrides from the zones ConfigMap, not the seed
The old console kept the zone files and the live address-overrides.rpz in the
same fancy-dns-zones ConfigMap; fancy-dns-rpz was only the static seed the
overrides started from. Reading the live cluster showed the two had diverged
(6 entries against 5, the missing one being stackship.k6n.net), so the default
would have silently dropped a redirect. The default is now fancy-dns-zones, and
the test puts a different stale seed in fancy-dns-rpz so reading the wrong one
fails.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 10:34:31 +02:00

3.7 KiB

Moving a ConfigMap deployment to cluster objects

Until now the console edited zones and address redirects by writing two ConfigMap (fancy-dns-zones: zone files and the live address overrides) through the resolver's service account (fancy-dns-rpz was only the seed the overrides started from), and the domains page rewrote the config file. Those mechanisms are gone. Everything the console edits is now an object:

Was Is
zone--<apex>.zone keys in the fancy-dns-zones ConfigMap DNSZone
the address-overrides.rpz key in the same fancy-dns-zones ConfigMap AddressOverride (one per name)
blocklist.allow_entries / block_entries DomainRule (inline-allow, inline-block)
blocklist.lists with a URL BlockList
acl.groups ClientGroup
listeners, upstreams, cache, default_policy still the resolver's YAML

The old resolver does not read the objects and the new one does not read the ConfigMaps, so the order below matters: create the objects while the old resolver is still serving, switch, then delete the ConfigMaps. Nothing here deletes anything until the last step.

1. Install the definitions and permissions

kubectl apply -f deploy/k8s/crds/crds.yaml
kubectl apply -k deploy/k8s/crds            # lets the resolver's service account read the objects
kubectl apply -f deploy/k8s/console/console.yaml   # the console, which writes them (create its two Secrets first)

2. Convert what you have

The command reads the ConfigMap from the cluster and, if you give it the resolver's config.yaml, its URL lists, inline entries and ACL groups. By default it only prints manifests.

kubectl -n dns get cm fancy-dns-config -o jsonpath='{.data.config\.yaml}' > /tmp/config.yaml

FANCYDNS_API_KEY=unused \
fancy-dns-console migrate -kube-namespace dns -config /tmp/config.yaml > migrated.yaml

(FANCYDNS_API_KEY=unused: the config expands ${VAR} references and refuses an unset one; the value is not used.) Read migrated.yaml, and read what the command printed on stderr:

  • converted: lines say what became an object and what to remove from the config.
  • NOT converted: lines are things it could not represent faithfully (a zone with a record type the console does not write, a list that is a file on the pod, a name that is not a legal object name). Those stay where they are.

Commit migrated.yaml if you manage the cluster with GitOps, or apply it:

fancy-dns-console migrate -kube-namespace dns -config /tmp/config.yaml -apply

It is safe to run again: objects are created or updated, never duplicated.

3. Switch the resolver

  • Start it with -kube (the StatefulSet in deploy/k8s/10-deployment.yaml does).
  • In config.yaml, remove what moved: the edge-router-x-address-overrides list and any other list you converted, acl.groups, the inline entries, blocklist.managed_zones and the fancy-dns-zones glob in local_zones.
  • Roll it out.

4. Check before you delete anything

kubectl -n dns get dnszones,addressoverrides,clientgroups,blocklists,domainrules
curl -s https://<console>/api/status      # components.degraded must not mention kubernetes
dig @<resolver> <a name from each zone and override>

A rejected object is not a silent failure: it is logged by the resolver, the node reports "kubernetes: objects rejected" as degraded, and an object that was valid before keeps its last good version.

5. Delete the old ConfigMaps

Only now:

kubectl -n dns delete cm fancy-dns-zones fancy-dns-rpz

If your GitOps tool prunes, remove them from the repository after step 4, not before: they hold the only copy of the data until the objects exist.