External DNS with Kubernetes¶
This guide explains how to integrate Kubernetes External-DNS with the bnerd CloudAPI DNS service.
Overview¶
External-DNS automatically creates DNS records from Kubernetes Ingress and Service resources. When combined with the bnerd DNS API, your Kubernetes workloads can automatically register their DNS records.
Prerequisites¶
- A Kubernetes cluster with kubectl configured
- A verified domain in bnerd (see Domain Verification)
- A DNS zone created for your domain:
bnerd dns zones create example.com - An API token with DNS management permissions
Step 1: Create a Static Access Token¶
External-DNS needs API credentials to manage DNS records. Create a dedicated token for this purpose.
Store the token as a Kubernetes Secret:
kubectl create secret generic bnerd-dns-credentials \
--namespace external-dns \
--from-literal=token=YOUR_API_TOKEN \
--from-literal=org-id=YOUR_ORG_ID
Step 2: Deploy External-DNS¶
Create the External-DNS deployment configured for the bnerd DNS provider (RFC2136/PowerDNS compatible):
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: external-dns
spec:
replicas: 1
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.0
args:
- --source=ingress
- --source=service
- --provider=pdns
- --pdns-server=https://api.bnerd.net
- --pdns-api-key=$(BNERD_TOKEN)
- --domain-filter=example.com
- --txt-owner-id=my-cluster
- --policy=sync
- --interval=1m
env:
- name: BNERD_TOKEN
valueFrom:
secretKeyRef:
name: bnerd-dns-credentials
key: token
Domain filter
Set --domain-filter to your verified domain to prevent External-DNS from managing records outside your zone.
Step 3: Test with an Ingress¶
Create a test Ingress to verify External-DNS creates the DNS record:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-app
annotations:
external-dns.alpha.kubernetes.io/hostname: test.example.com
spec:
rules:
- host: test.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-app
port:
number: 80
After applying, check that the record was created:
Troubleshooting¶
Records not being created:
- Check External-DNS logs:
kubectl logs -n external-dns -l app=external-dns - Verify the API token is valid:
bnerd whoami - Ensure the domain filter matches your zone
- Check that the zone exists:
bnerd dns zones list
Permission denied errors:
- Verify the token has DNS management permissions
- Check the org-id matches the zone's organization
Duplicate records:
- Set a unique
--txt-owner-idper cluster to prevent conflicts - Use
--policy=syncfor full reconciliation (creates and deletes)