From 60d3acc2028d1ceceecc51cae0ad25a03a9ae587 Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Mon, 26 Oct 2026 09:59:37 +0100 Subject: [PATCH] chore(coredns): Talos alone owns the Corefile Step 2 of 2. The coredns ConfigMap is a Talos bootstrap manifest; Flux stops applying its own copy (prune is disabled since the previous commit, so the live ConfigMap stays until talosctl upgrade-k8s writes Talos's version). CoreDNS forwards to the node resolver, which asks k8s-gateway first, so cluster DNS no longer depends on Flux. Co-Authored-By: Claude Opus 5.5 --- .../coredns-config/configmap.yaml | 78 ------------------- .../coredns-config/kustomization.yaml | 3 +- .../k8s-gateway/helmrelease.yaml | 9 ++- 3 files changed, 7 insertions(+), 83 deletions(-) delete mode 100644 kubernetes/infrastructure/coredns-config/configmap.yaml diff --git a/kubernetes/infrastructure/coredns-config/configmap.yaml b/kubernetes/infrastructure/coredns-config/configmap.yaml deleted file mode 100644 index e4d38fe3..00000000 --- a/kubernetes/infrastructure/coredns-config/configmap.yaml +++ /dev/null @@ -1,78 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: coredns - namespace: kube-system - # Talos owns this ConfigMap (bootstrap manifest). Flux must not delete it - # when this file is removed. - annotations: - kustomize.toolkit.fluxcd.io/prune: disabled -data: - Corefile: | - # Delegate renner.uno to the in-cluster k8s_gateway resolver. It - # watches Ingress resources and synthesises A/AAAA records that - # point at the ingress-nginx LB, so pods resolving `auth.renner.uno`, - # `audiobooks.renner.uno`, … stay inside the cluster. Names not - # backed by an in-cluster Ingress fall through inside k8s_gateway - # itself to the UDM (10.2.40.1 / fd00::1), which serves the split-horizon - # renner.uno zone, preserving resolution of LXC/VM + physical services. - # (The old Proxmox DNS VIP 10.2.40.53 is DECOMMISSIONED.) 10.96.0.11 is a - # pinned ClusterIP of the k8s-gateway Service — avoids DNS-name - # resolution during CoreDNS startup. - # Cache tuning mirrors k8s-gateway's (issue #393): the UDM's dnsmasq - # refuses connections in bursts, and because the public renner.uno zone - # has a *.renner.uno wildcard CNAME that matches at every depth, a local - # failure never returns NXDOMAIN — it resolves to the WAN proxy instead. - # Correct answers carry TTL 5 (dnsmasq lease records) while the wrong - # wildcard answer carries TTL 300, so one brief blip pins a wrong answer - # for minutes. `success ... 60` raises the 5s TTL to a 60s floor and - # `serve_stale 1h immediate` keeps serving through an upstream outage. - # NOTE: only cache/serve_stale — the `template` plugin is deliberately NOT - # reintroduced here (it broke cluster DNS in 7a09bad5). - renner.uno:53 { - errors - cache 300 { - success 9984 300 60 - denial 9984 300 30 - serve_stale 1h immediate - } - forward . 10.96.0.11 - loop - reload - } - - .:53 { - errors - health { - lameduck 5s - } - ready - log . { - class error - } - prometheus :9153 - - kubernetes cluster.local in-addr.arpa ip6.arpa { - pods insecure - fallthrough in-addr.arpa ip6.arpa - ttl 30 - } - forward . /etc/resolv.conf { - max_concurrent 1000 - } - # serve_stale mirrors the renner.uno:53 block (issue #393): when the - # upstream resolver browns out, keep answering from expired cache - # instead of SERVFAILing every public name cluster-wide. Seen on - # 2026-07-30 01:22-01:26Z (~1150 SERVFAILs) — it killed a Velero Kopia - # maintenance job, which runs with backoffLimit 0, on the Hetzner S3 - # endpoint (issue #439). cluster.local is exempt from the cache above, - # so in-cluster Service records are never served stale. - cache 30 { - disable success cluster.local - disable denial cluster.local - serve_stale 1h immediate - } - loop - reload - loadbalance - } diff --git a/kubernetes/infrastructure/coredns-config/kustomization.yaml b/kubernetes/infrastructure/coredns-config/kustomization.yaml index 81b80981..dcd5140b 100644 --- a/kubernetes/infrastructure/coredns-config/kustomization.yaml +++ b/kubernetes/infrastructure/coredns-config/kustomization.yaml @@ -1,5 +1,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization +# CoreDNS itself (Deployment, Corefile) is a Talos bootstrap manifest; only +# its LoadBalancer Service lives here. resources: - - configmap.yaml - service.yaml diff --git a/kubernetes/infrastructure/k8s-gateway/helmrelease.yaml b/kubernetes/infrastructure/k8s-gateway/helmrelease.yaml index 39b486f2..2883acd4 100644 --- a/kubernetes/infrastructure/k8s-gateway/helmrelease.yaml +++ b/kubernetes/infrastructure/k8s-gateway/helmrelease.yaml @@ -85,10 +85,11 @@ spec: parameters: "0.0.0.0:9153" serviceType: ClusterIP service: - # Pinned so the main CoreDNS Corefile can forward renner.uno - # here without depending on DNS-based Service resolution during - # CoreDNS startup (chicken-and-egg). Chosen from the low, sparsely - # populated end of the service CIDR (kube-dns is 10.96.0.10). + # Pinned because the nodes' resolver names it by address + # (ResolverConfig in the Talos site patches); CoreDNS forwards to the + # node, so every name reaches k8s-gateway that way. Chosen from the + # low, sparsely populated end of the service CIDR (kube-dns is + # 10.96.0.10). clusterIP: 10.96.0.11 ipFamilyPolicy: PreferDualStack # The site's upstream resolvers (deployment.dnsPolicy/dnsConfig), from the -- 2.54.0