openova/platform/external-dns
hatiyildiz 5834daec14 docs(pass-10): banners on 7 more components + opentofu active-active drift fix
7 more component READMEs got role-in-Catalyst banners:

- vpa, keda, reloader → per-host-cluster scaling/ops layer (§3.4).
  Reloader specifically calls out its role in Catalyst's secret-
  rotation flow (rolling deploy on K8s Secret hash change).
- external-dns → per-host-cluster DNS-sync (§3.1); pairs with k8gb
  for the GSLB zone separation.
- coraza → DMZ-block WAF on every host cluster (§3.1).
- crossplane → per-Sovereign on the management cluster (§3.2);
  banner explicitly emphasizes the agreed "never a user-facing
  surface" rule (Users don't write Compositions in Application
  configs; Blueprint authors and advanced contributors do). Cross-
  references the no-fourth-surface clause in ARCHITECTURE §4/§7
  and the Crossplane Composition section in BLUEPRINT-AUTHORING §8.
- opentofu → repositioned as Phase-0-only, runs on `catalyst-
  provisioner` only, NOT installed on host clusters at runtime.

opentofu drift fixes (uncovered by line-by-line read):
- Section 5 line 182: "Bootstrap Wizard prompts for cloud credentials"
  → "Catalyst Bootstrap (Phase 0) prompts for cloud credentials"
  (banned term).
- Same section line 186: "ESO PushSecrets sync to both regional
  OpenBao instances" — the active-active drift Pass 7 corrected
  elsewhere, still here. Replaced with "writes go to the primary
  OpenBao region only; replicas pick up via async perf replication".

VALIDATION-LOG: Pass 10 entry added.

Refs #37
2026-04-27 21:43:45 +02:00
..
README.md docs(pass-10): banners on 7 more components + opentofu active-active drift fix 2026-04-27 21:43:45 +02:00

ExternalDNS

DNS synchronization (registers/deletes records via cloud DNS APIs). Per-host-cluster infrastructure (see docs/PLATFORM-TECH-STACK.md §3.1) — runs on every host cluster, primarily on the DMZ block. Pairs with k8gb (which serves the GSLB zone authoritatively) — ExternalDNS handles non-GSLB records and the parent zone delegation.

Status: Accepted | Updated: 2026-04-27


Overview

ExternalDNS synchronizes Kubernetes resources (Gateway, Service, Ingress) with external DNS providers, enabling automatic DNS record management.


Architecture

flowchart TB
    subgraph K8s["Kubernetes"]
        GW[Gateway API]
        Svc[Services]
        ExtDNS[ExternalDNS]
    end

    subgraph DNS["DNS Providers"]
        CF[Cloudflare]
        R53[Route53]
        HDNS[Hetzner DNS]
    end

    subgraph GSLB["Global LB"]
        k8gb[k8gb]
    end

    GW --> ExtDNS
    Svc --> ExtDNS
    ExtDNS --> CF
    ExtDNS --> R53
    ExtDNS --> HDNS
    k8gb --> ExtDNS

Supported DNS Providers

Provider Availability
Cloudflare Always
Hetzner DNS If Hetzner chosen
AWS Route53 If AWS chosen
GCP Cloud DNS If GCP chosen
Azure DNS If Azure chosen

Configuration

ExternalDNS Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
  namespace: external-dns
spec:
  template:
    spec:
      containers:
        - name: external-dns
          image: registry.k8s.io/external-dns/external-dns:v0.14.0
          args:
            - --source=gateway-httproute
            - --source=gateway-grpcroute
            - --source=service
            - --provider=cloudflare
            - --cloudflare-proxied
            - --txt-owner-id=openova
            - --txt-prefix=_externaldns.
          env:
            - name: CF_API_TOKEN
              valueFrom:
                secretKeyRef:
                  name: cloudflare-credentials
                  key: api-token

k8gb Integration

ExternalDNS works with k8gb for GSLB:

flowchart LR
    subgraph Region1["Region 1"]
        App1[Application]
        k8gb1[k8gb]
    end

    subgraph Region2["Region 2"]
        App2[Application]
        k8gb2[k8gb]
    end

    subgraph DNS
        ExtDNS[ExternalDNS]
        NS[NS Records]
    end

    k8gb1 -->|"Delegate"| ExtDNS
    k8gb2 -->|"Delegate"| ExtDNS
    ExtDNS --> NS

k8gb delegates a subdomain (e.g., gslb.<domain>) and handles health-based DNS responses within that zone.


Record Types

Source Record Type Example
Gateway A/CNAME api.<domain>
Service (LoadBalancer) A svc.<domain>
k8gb GslbHttpRoute NS delegation gslb.<domain>

TXT Registry

ExternalDNS uses TXT records to track ownership:

_externaldns.api.<domain> TXT "heritage=external-dns,external-dns/owner=openova"

This prevents ExternalDNS from modifying records it doesn't own.


Part of OpenOva