From e030f079861c9b0b00f883de9d5407eb901a58e4 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 5 Jul 2026 16:37:49 +1000 Subject: [PATCH] Add primary (write) Services to authoritative + externaldns (#229) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Stacked on #228** (needs operator v0.1.5). Merge #228 first; the diff collapses to just this after. ## Why Writes (RFC2136/nsupdate) must go to pod-0 — the round-robin read Service would land them on a secondary (rejected). Adds a dedicated write endpoint per cluster (operator v0.1.5 `primaryService`). ## Changes - `bind-authoritative`: LoadBalancer write endpoint on **198.18.200.9** (`bind-authoritative-primary`) - `bind-externaldns`: ClusterIP write endpoint (`bind-externaldns-primary`, for in-cluster writers) - regenerate the bindcluster kubeconform schema (primaryService + externalTrafficPolicy) ## Deferred external-dns is **not** repointed at `bind-externaldns-primary` yet: it authenticates with the existing TSIG key, which the operator-generated key won't match until the planned Vault-sync + secret-reflection features exist. Until then external-dns keeps writing to the puppet externaldns. ## Validated kustomize build + kubeconform (3 BindClusters valid against the v0.1.5 schema). --------- Co-authored-by: BenVincent Reviewed-on: https://git.unkin.net/unkin/argocd-apps/pulls/229 Co-authored-by: Ben Vincent Co-committed-by: Ben Vincent --- .../bind-internal/authoritative/cluster.yaml | 7 ++++ .../bind-internal/externaldns/cluster.yaml | 3 ++ .../base/bind-internal/resolvers/cluster.yaml | 1 + .../bind.unkin.net/bindcluster_v1alpha1.json | 36 +++++++++++++++++++ 4 files changed, 47 insertions(+) diff --git a/apps/base/bind-internal/authoritative/cluster.yaml b/apps/base/bind-internal/authoritative/cluster.yaml index ea08a66..639d780 100644 --- a/apps/base/bind-internal/authoritative/cluster.yaml +++ b/apps/base/bind-internal/authoritative/cluster.yaml @@ -18,10 +18,17 @@ spec: - "allow-query { auth-acl-main; 10.42.0.0/16; }" service: type: LoadBalancer + externalTrafficPolicy: Local annotations: purelb.io/service-group: common purelb.io/addresses: 198.18.200.6 external-dns.alpha.kubernetes.io/hostname: bind-authoritative.k8s.syd1.au.unkin.net + primaryService: + type: LoadBalancer + annotations: + purelb.io/service-group: common + purelb.io/addresses: 198.18.200.9 + external-dns.alpha.kubernetes.io/hostname: bind-authoritative-primary.k8s.syd1.au.unkin.net resources: requests: cpu: 100m diff --git a/apps/base/bind-internal/externaldns/cluster.yaml b/apps/base/bind-internal/externaldns/cluster.yaml index 14b0fb5..5b2a0ca 100644 --- a/apps/base/bind-internal/externaldns/cluster.yaml +++ b/apps/base/bind-internal/externaldns/cluster.yaml @@ -14,10 +14,13 @@ spec: storageSize: 1Gi service: type: LoadBalancer + externalTrafficPolicy: Local annotations: purelb.io/service-group: common purelb.io/addresses: 198.18.200.8 external-dns.alpha.kubernetes.io/hostname: bind-externaldns.k8s.syd1.au.unkin.net + primaryService: + type: ClusterIP resources: requests: cpu: 100m diff --git a/apps/base/bind-internal/resolvers/cluster.yaml b/apps/base/bind-internal/resolvers/cluster.yaml index f99b8b9..e6c8231 100644 --- a/apps/base/bind-internal/resolvers/cluster.yaml +++ b/apps/base/bind-internal/resolvers/cluster.yaml @@ -13,6 +13,7 @@ spec: storageSize: 1Gi service: type: LoadBalancer + externalTrafficPolicy: Local annotations: purelb.io/service-group: common purelb.io/addresses: 198.18.200.7 diff --git a/schemas/bind.unkin.net/bindcluster_v1alpha1.json b/schemas/bind.unkin.net/bindcluster_v1alpha1.json index 1aaa072..abecc82 100644 --- a/schemas/bind.unkin.net/bindcluster_v1alpha1.json +++ b/schemas/bind.unkin.net/bindcluster_v1alpha1.json @@ -692,6 +692,35 @@ }, "type": "object" }, + "primaryService": { + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "externalTrafficPolicy": { + "enum": [ + "Cluster", + "Local" + ], + "type": "string" + }, + "loadBalancerIP": { + "type": "string" + }, + "type": { + "enum": [ + "ClusterIP", + "LoadBalancer", + "NodePort" + ], + "type": "string" + } + }, + "type": "object" + }, "recursion": { "type": "boolean" }, @@ -765,6 +794,13 @@ }, "type": "object" }, + "externalTrafficPolicy": { + "enum": [ + "Cluster", + "Local" + ], + "type": "string" + }, "loadBalancerIP": { "type": "string" },