Traefik ExternalDNS Kubernetes verbindet dein Routing mit dem DNS-Provider: ExternalDNS liest Hostnamen aus Traefik-Ressourcen und gleicht passende DNS-Records über die Provider-API ab. So bleibt der DNS-Eintrag bei neuen oder entfernten Routen nachvollziehbar im Cluster konfiguriert, statt in einer separaten DNS-Oberfläche gepflegt zu werden.
Stand: 07.10.2026
Auf einen Blick
- ExternalDNS erstellt DNS-Einträge nicht selbstständig aus Traefik, sondern aus aktivierten Quellen und Kubernetes-Objekten.
- Für Traefik-CRDs verwendest du die Quelle
traefik-proxyund annotierst die Route mit dem Hostnamen. - Der TXT-Registry-Eintrag verhindert, dass mehrere ExternalDNS-Instanzen dieselben Records verwalten.
- Teste Änderungen zunächst mit
--dry-run;upsert-onlylöscht keine bestehenden Records.
Wie arbeiten Traefik und ExternalDNS zusammen?
Traefik nimmt HTTP-Anfragen entgegen und leitet sie anhand einer IngressRoute an einen Kubernetes-Service weiter. ExternalDNS ist davon getrennt: Der Controller beobachtet konfigurierte Quellen, berechnet gewünschte DNS-Endpunkte und ruft die API des DNS-Providers auf.
Wichtig ist die Reihenfolge: Zuerst muss Traefik von außen erreichbar sein. Anschließend benötigt ExternalDNS ein Ziel, etwa den Hostnamen oder die IP des LoadBalancer-Service von Traefik. Eine Route allein macht einen Hostnamen nicht erreichbar.
| Baustein | Aufgabe |
|---|---|
| Traefik | Routet Anfragen vom EntryPoint zum Service. |
| IngressRoute | Beschreibt Host-Regel, Service und optional TLS. |
| ExternalDNS | Ermittelt gewünschte DNS-Records und gleicht sie mit dem Provider ab. |
| DNS-Provider | Speichert die öffentliche Zone und stellt die API bereit. |
Für klassische Kubernetes-Ingresses ist auch die Ingress-Quelle möglich. Dieser Beitrag nutzt bewusst Traefiks CRD IngressRoute. Die aktuelle Traefik-API lautet dabei traefik.io/v1alpha1; die frühere Domain traefik.containo.us gehört nicht in neue Manifeste. Lies vor einem Upgrade auch die Migration von Traefik v2 zu v3.
Welche Voraussetzungen brauchst du?
- Ein Kubernetes-Cluster mit installiertem Traefik und einem erreichbaren EntryPoint.
- Eine DNS-Zone bei einem Provider, dessen Schnittstelle ExternalDNS unterstützt.
- Ein Kubernetes-Service-Account mit den für die gewählten Quellen nötigen Leserechten.
- Provider-Zugangsdaten als Kubernetes-Secret, nicht als Klartext im Manifest oder Helm-Kommando.
Beschränke den API-Token beim Provider auf die benötigte Zone und DNS-Änderungen. Außerdem sollte das Secret nur im Namespace des Controllers lesbar sein. Für die grundlegende Absicherung von Container-Setups hilft dir auch der Beitrag Dockerfile Best Practices.
So konfigurierst du ExternalDNS für Traefik
- Lege zunächst den Zielnamen fest. Bei einem LoadBalancer ist das üblicherweise dessen externe Adresse oder sein DNS-Name.
- Installiere ExternalDNS mit dem offiziellen Chart oder den offiziellen Release-Manifests deines gewählten Providers. Prüfe die Flags in der Version, die du tatsächlich ausrollst.
- Aktiviere die Quelle
traefik-proxy, begrenze sie auf deine Zone und verwende eine TXT-Registry mit eindeutiger Owner-ID. - Starte den ersten Abgleich mit
--dry-run. Erst wenn die geplanten Records stimmen, entfernst du diese Option.
Die folgenden Argumente zeigen die Kernkonfiguration als Auszug. Wie der Provider authentifiziert wird, hängt vom Anbieter ab und gehört in Secret-Referenzen des jeweiligen Charts oder Deployments.
args:
- --source=traefik-proxy
- --domain-filter=example.com
- --registry=txt
- --txt-owner-id=cluster-prod-1
- --policy=upsert-only
- --dry-run--domain-filter begrenzt den Zuständigkeitsbereich. Deshalb kann ein falsch annotierter Host außerhalb der Zone nicht versehentlich geändert werden. Die TXT-Registry markiert Records als von dieser ExternalDNS-Instanz verwaltet. Wähle die Owner-ID pro Cluster eindeutig, besonders wenn mehrere Cluster dieselbe Zone nutzen.
upsert-only ist ein vorsichtiger Einstieg: ExternalDNS legt Records an und aktualisiert sie, entfernt aber keine alten Einträge. Erst wenn Ownership und Lebenszyklus sauber getestet sind, ist eine löschende Policy eine bewusste Betriebsentscheidung.
Wie sieht eine aktuelle Traefik IngressRoute aus?
Die Annotation verwendet den aktuellen Präfix external-dns.kubernetes.io. ExternalDNS 0.23 kann ältere external-dns.alpha.kubernetes.io-Annotationen nur mit aktivierter Legacy-Option zusätzlich lesen. Für neue Ressourcen solltest du daher den aktuellen Präfix verwenden.
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: hello
namespace: apps
annotations:
external-dns.kubernetes.io/hostname: hello.example.com
spec:
entryPoints:
- websecure
routes:
- match: Host(`hello.example.com`)
kind: Rule
services:
- name: hello-service
port: 80
tls: {}Wende das Manifest erst an, wenn hello-service im selben Namespace existiert. Das leere tls-Objekt aktiviert TLS nicht automatisch: Die konkrete Zertifikatsstrategie konfigurierst du in Traefik, etwa über einen Certificate Resolver oder eine TLSOption. DNS-Automatisierung und Zertifikatsausstellung sind getrennte Aufgaben.
Wann sind CNAME und Wildcards sinnvoll?
Ein CNAME verweist auf einen anderen Namen, nicht auf eine IP-Adresse. Er eignet sich daher, wenn dein Traefik-Endpunkt selbst einen stabilen DNS-Namen hat. Zeigt dein LoadBalancer direkt eine IP, sind A- und AAAA-Records oft die passendere Wahl. Welchen Typ ExternalDNS tatsächlich setzt, hängt vom Ziel und Provider ab.
Eine Wildcard wie *.apps.example.com löst nicht das Routing-Problem. Traefik braucht weiterhin eine passende Host-Regel oder eine bewusst breit gefasste Regel. Prüfe zudem vorab, ob der Provider Wildcard-Records über seine API zulässt und ob dein Zertifikat die benötigte Wildcard abdeckt.
Wie prüfst du den ersten Abgleich sicher?
- Behalte
--dry-runaktiv und lies die Controller-Logs. - Vergleiche den geplanten Namen, das Ziel und den Record-Typ mit deiner DNS-Zone.
- Entferne
--dry-runerst nach diesem Abgleich. - Prüfe danach die Route über den vollständigen Hostnamen und kontrolliere die TLS-Konfiguration getrennt.
kubectl logs -n external-dns deploy/external-dns --follow
kubectl get ingressroute -n apps hello -o yaml
kubectl get svc -n traefikDer Namespace und der Deployment-Name sind Beispiele und müssen zu deiner Installation passen. Taucht kein geplanter Record auf, prüfe zuerst Quelle, Domain-Filter, Annotation und die Berechtigungen des Service-Accounts. Bei einem falschen Ziel prüfst du danach, wie Traefik im Cluster exponiert ist.
Welche Fehler treten häufig auf?
| Symptom | Wahrscheinliche Ursache | Prüfung |
|---|---|---|
| Kein DNS-Record | Quelle oder Domain-Filter passt nicht. | Flags und Annotation kontrollieren. |
| Record zeigt falsch | Traefik-Service liefert nicht das erwartete externe Ziel. | Service-Typ und Status prüfen. |
| Record wird nicht gelöscht | upsert-only verhindert Löschungen. | Gewählte Policy bewusst prüfen. |
| Konflikt mit anderem Cluster | Gemeinsame oder fehlende TXT-Owner-ID. | Owner-ID und Registry prüfen. |
Vermeide außerdem zwei Controller mit überlappenden Filtern und derselben Zuständigkeit. Das führt schnell zu schwer nachvollziehbaren Änderungen. Für reproduzierbare Installationen und Updates sind Helm Charts hilfreich; beobachte DNS- und Router-Verhalten anschließend in deinem Kubernetes-Monitoring mit Grafana und Prometheus.
Fazit
Traefik ExternalDNS Kubernetes spart manuelle DNS-Pflege, wenn Quelle, Ziel und Zuständigkeit klar definiert sind. Nutze für neue Ressourcen die aktuelle Traefik-API und den aktuellen ExternalDNS-Annotationspräfix. Mit Domain-Filter, TXT-Registry, eindeutiger Owner-ID und einem Dry-Run startest du kontrolliert und vermeidest unerwünschte Änderungen in der Zone.
Quellen
- ExternalDNS: Traefik Proxy Source
- ExternalDNS: Annotations
- ExternalDNS v0.23.0 Release Notes
- Traefik: Kubernetes IngressRoute
Häufige Fragen
Nein. ExternalDNS kann unterschiedliche Kubernetes-Quellen auswerten. Für Traefik-CRDs aktivierst du die Quelle traefik-proxy; bei Standard-Ingresses nutzt du stattdessen die Ingress-Quelle.
Für neue Ressourcen nutze external-dns.kubernetes.io/hostname. Der ältere Präfix external-dns.alpha.kubernetes.io ist eine Legacy-Variante und sollte nicht mehr für neue Manifeste verwendet werden.
Das hängt von der gewählten Policy ab. Mit upsert-only werden Records angelegt und aktualisiert, aber nicht gelöscht. Prüfe eine löschende Policy erst nach einem Dry-Run und klarer Ownership.
Die TXT-Registry kennzeichnet die von einer ExternalDNS-Instanz verwalteten Records. Eine eindeutige txt-owner-id verhindert Konflikte, wenn mehrere Cluster dieselbe DNS-Zone verwenden.





1 Pingback