DNS Architecture and External DNS

Relevant source files

This page details the split-brain DNS design implemented in the home-ops cluster. The architecture leverages three distinct external-dns instances to manage public, local override, and internal infrastructure records. It further describes the integration of Cloudflare Tunnels for secure ingress and the role of DNSEndpoint custom resources in automating record management.

Split-Brain DNS Design

The cluster utilizes a “split-brain” approach where different DNS providers handle the same domain (cloudjur.com) depending on the network context (external vs. internal). This is managed by three separate HelmRelease instances of external-dnskubernetes/apps/network/external-dns/ks.yaml1-74

DNS Provider Matrix

Instance NameProvider / TargetPurposeKey Source Types
external-dnsCloudflarePublic DNS records with proxying enabled.crd, gateway-httproute
external-dns-adguard-homeAdGuard Home (Webhook)Local DNS overrides for internal LAN clients.gateway-httproute, service
external-dns-opnsense-unboundOPNsense Unbound (Webhook)Internal infrastructure records for node-level resolution.gateway-httproute, service

Data Flow: DNS Record Lifecycle

The following diagram illustrates how a single HTTPRoute or DNSEndpoint resource triggers updates across different DNS providers.

DNS Reconciliation Flow

[Flowchart Diagram]

Sources: kubernetes/apps/network/external-dns/app/helmrelease.yaml31-42kubernetes/apps/network/external-dns/adguard-home/helmrelease.yaml65-78kubernetes/apps/network/external-dns/unbound/helmrelease.yaml75-96

External DNS Instances

1. Public Cloudflare Instance

The primary external-dns instance manages public-facing records. It is configured with --cloudflare-proxied to ensure traffic flows through Cloudflare’s edge kubernetes/apps/network/external-dns/app/helmrelease.yaml33 It specifically watches for Gateway resources labeled for envoy-externalkubernetes/apps/network/external-dns/app/helmrelease.yaml36

2. AdGuard Home Override

For local clients within the home network, external-dns-adguard-home provides DNS overrides. It uses a webhook provider (ghcr.io/muhlba91/external-dns-provider-adguard) to communicate with the AdGuard Home API kubernetes/apps/network/external-dns/adguard-home/helmrelease.yaml23-27 This allows local devices to resolve cluster services directly to internal IPs, bypassing the Cloudflare Tunnel for reduced latency.

3. OPNsense Unbound Integration

The external-dns-opnsense-unbound instance targets the Unbound DNS service running on the OPNsense router. It uses a specialized webhook (ghcr.io/crutonjohn/external-dns-opnsense-webhook) kubernetes/apps/network/external-dns/unbound/helmrelease.yaml26 and targets the envoy-internal gateway kubernetes/apps/network/external-dns/unbound/helmrelease.yaml83

Cloudflare Tunnel and Ingress

The cluster uses cloudflared to establish a secure, outbound-only connection to Cloudflare, eliminating the need for open inbound firewall ports.

Tunnel Configuration

The cloudflare-tunnel deployment runs the cloudflared binary kubernetes/apps/network/cloudflare-tunnel/app/helmrelease.yaml27-28 Its configuration routes traffic for cloudjur.com and its subdomains to the internal envoy-external service kubernetes/apps/network/cloudflare-tunnel/app/resources/config.yaml2-11

Ingress Architecture

[Flowchart Diagram]

Sources: kubernetes/apps/network/cloudflare-tunnel/app/resources/config.yaml1-12kubernetes/apps/network/cloudflare-tunnel/app/helmrelease.yaml34

CoreDNS and Internal Resolution

Within the cluster, coredns serves as the primary resolver for cluster.local domains kubernetes/apps/kube-system/coredns/app/helmrelease.yaml48-49 It is configured with the kubernetes plugin to provide service discovery and forward to upstream resolvers (typically the node’s /etc/resolv.conf) for non-cluster queries kubernetes/apps/kube-system/coredns/app/helmrelease.yaml55-57

DNSEndpoint CRD Pattern

While external-dns can automatically discover records from Ingress or HTTPRoute resources, the DNSEndpoint CRD is used for manual record definitions or for resources that do not natively support DNS annotations.

Automation and Maintenance

Sources: