How to Set Up ExternalDNS in Kubernetes
In this tutorial, you'll learn about How to Set Up ExternalDNS in Kubernetes. We cover key concepts, practical examples, and best practices.
The Problem
You installed ExternalDNS, created an Ingress or Service with LoadBalancer type, but no DNS record is created. Your domain remains unreachable despite the LoadBalancer having a public IP. ExternalDNS is not synchronizing Kubernetes resources to your DNS provider.
Quick Fix
Fix 1: Annotations Missing on Ingress/Service
WRONG — creating an Ingress without ExternalDNS annotations:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
# missing external-dns annotation
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port: 80
RIGHT — add the annotation:
metadata:
annotations:
external-dns.alpha.kubernetes.io/hostname: app.example.com
Fix 2: Wrong DNS Provider Configuration
WRONG — ExternalDNS configured for Cloudflare but using AWS Route53:
# Deployment args:
args:
- --provider=aws
# (but the domain is hosted on Cloudflare)
RIGHT — match the provider to your DNS hosting:
args:
- --provider=cloudflare
env:
- name: CF_API_TOKEN
valueFrom:
secretKeyRef:
name: cloudflare-token
key: api-token
Common providers: aws, google, <a href="/web-servers-hosting/cloudflare/">cloudflare</a>, azure, digitalocean, rfc2136.
Fix 3: Zone Not Found
kubectl logs deployment/external-dns
# time="2024-03-15T10:30:00Z" level=error msg="No hosted zones found"
RIGHT — specify the domain filter:
args:
- --domain-filter=example.com
- --zone-id-filter=ZONE123456 # optional, for specific zone
Check that the DNS zone exists in the provider:
# For AWS:
aws route53 list-hosted-zones --query "HostedZones[?Name=='example.com.']"
# For Cloudflare:
curl -H "Authorization: Bearer $CF_TOKEN" https://api.cloudflare.com/client/v4/zones?name=example.com
Fix 4: Source Type Not Specified
WRONG — ExternalDNS does not know which resources to watch:
args:
- --source=service
# (but you are using Ingress — Ingress sources are not watched)
RIGHT — specify all relevant sources:
args:
- --source=service
- --source=ingress
- --source=crd # for custom resources like Ambassador HTTP
Fix 5: Ownership Not Working
# ExternalDNS creates records but also deletes records it should not
RIGHT — use ownership with TXT records:
args:
- --txt-owner-id=my-cluster
- --txt-prefix=external-dns-
Fix 6: Private DNS or VPC
For private hosted zones, set:
args:
- --aws-zone-type=private # for AWS private zones
Fix 7: Dry Run Mode
ExternalDNS runs in dry-run mode by default if you forgot to remove the flag:
args:
- --dry-run # remove this flag to make actual changes
Check the logs for what changes would be made:
kubectl logs deployment/external-dns | grep "CREATE\|UPDATE\|DELETE"
Use DodaTech's DNS Inspector to verify ExternalDNS records, compare desired vs actual DNS state, and troubleshoot synchronization delays.
Prevention
- Add
external-dns.alpha.kubernetes.io/hostnameannotation to all Ingress and LoadBalancer resources. - Verify the DNS provider credentials are correct.
- Use
--domain-filterto limit the scope. - Start with
--dry-runto verify changes before applying. - Monitor ExternalDNS logs for errors.
Common Mistakes with external dns
- Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad - Mixing let bindings with <- bindings in do notation, producing type errors
These mistakes appear frequently in real-world K8S code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro