openova/platform/external-dns/README.md
hatiyildiz f5daac52af refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171)
PowerDNS lua-records (`ifurlup`, `pickclosest`, `ifportup`) cover everything
k8gb was doing — geo-aware response selection, health-checked failover,
weighted round-robin — at the authoritative DNS layer. Eliminates a
separate K8s controller, CRD set, and CoreDNS plugin from every Sovereign.

Changes:
- platform/k8gb/ deleted (Chart.yaml, values.yaml, blueprint.yaml never
  authored — only README existed)
- products/catalyst/bootstrap/ui/public/component-logos/k8gb.svg deleted
- componentGroups.ts: remove k8gb component (PowerDNS already there)
- componentLogos.tsx: drop logo_k8gb + k8gb map entry
- model.ts DEFAULT_COMPONENT_GROUPS spine: replace k8gb with powerdns
- StepInfrastructure.tsx: copy refers to PowerDNS lua-records, not k8gb
- provision.html: replace k8gb tile and edges with powerdns
- catalog.generated.ts regenerated (now includes bp-powerdns)
- docs sweep — every k8gb reference in PLATFORM-TECH-STACK, NAMING-
  CONVENTION, SOVEREIGN-PROVISIONING, SRE, ARCHITECTURE, GLOSSARY,
  COMPONENT-LOGOS, IMPLEMENTATION-STATUS, BUSINESS-STRATEGY,
  TECHNOLOGY-FORECAST, README, infra/hetzner/README, platform READMEs
  (cilium, external-dns, failover-controller, litmus, flux, opentofu)
  rewritten to point at PowerDNS lua-records / MULTI-REGION-DNS.md.
  Historical entries in VALIDATION-LOG.md preserved as audit trail.
- New docs/MULTI-REGION-DNS.md — canonical reference for the lua-record
  patterns (ifurlup all/pickclosest/pickfirst, ifportup, pickwhashed),
  Application Placement → lua-record selector mapping, when to add a
  second Sovereign region, operational checks.

Closes #171.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 08:51:09 +02:00

3.7 KiB

ExternalDNS

DNS synchronization (registers/deletes records via the PowerDNS REST API and external cloud DNS APIs where applicable). Per-host-cluster infrastructure (see docs/PLATFORM-TECH-STACK.md §3.1) — runs on every host cluster, primarily on the DMZ block. PowerDNS (see docs/PLATFORM-POWERDNS.md) is the authoritative server for every Sovereign zone; ExternalDNS uses the webhook provider (external-dns-pdns) to write A/AAAA/CNAME records into PowerDNS. Health-checked geo-failover lives in PowerDNS lua-records — see docs/MULTI-REGION-DNS.md.

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"]
        PDNS[PowerDNS<br>(authoritative — every Sovereign zone)]
        CF[Cloudflare]
        R53[Route53]
        HDNS[Hetzner DNS]
    end

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

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

PowerDNS Integration (geo + health-checked failover)

ExternalDNS writes plain A/AAAA/CNAME records into PowerDNS via the REST API. Geo-aware and health-checked failover responses are owned by PowerDNS lua-records, written by the catalyst-dns controller — ExternalDNS does NOT manage lua-record content.

flowchart LR
    subgraph Region1["Region 1"]
        App1[Application]
        ExtDNS1[ExternalDNS]
    end

    subgraph Region2["Region 2"]
        App2[Application]
        ExtDNS2[ExternalDNS]
    end

    subgraph PDNS["PowerDNS Authoritative"]
        ZoneAPI[REST API]
        Lua[lua-records (ifurlup, pickclosest)]
    end

    ExtDNS1 -->|"plain A/AAAA"| ZoneAPI
    ExtDNS2 -->|"plain A/AAAA"| ZoneAPI
    ZoneAPI --- Lua

See docs/MULTI-REGION-DNS.md for the lua-record patterns.


Record Types

Source Record Type Example
Gateway A/CNAME api.<domain>
Service (LoadBalancer) A svc.<domain>
catalyst-dns (lua-record author) LUA A app.<domain> (geo + health-checked)

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