Updated: 2020-06-17
I’ll be using a helm chart to install external-dns on my Kubernetes GKE cluster.
Create zone
Create GCP service account
Create a GCP service account to enable an account to edit Cloud DNS.
export PROJECT_NAME=[YOUR_PROJECT_NAME] # create service account gcloud iam service-accounts create k8s-external-dns \ --display-name="Service Account to support ACME DNS-01 challenge." \ --project=$PROJECT_NAME # create service account key # this will also download the json key gcloud iam service-accounts keys create ./credentials.json \ --iam-account=k8s-external-dns@$PROJECT_NAME.iam.gserviceaccount.com \ --project=$PROJECT_NAME # give dns admin permissions gcloud projects add-iam-policy-binding $PROJECT_NAME \ --member=serviceAccount:k8s-external-dns@$PROJECT_NAME.iam.gserviceaccount.com \ --role=roles/dns.admin
Create secret from GCP service account
kubectl create secret generic external-dns \
--from-file=./credentials.json \
--namespace=itsmetommy
Add repo
helm repo add bitnami https://charts.bitnami.com/bitnami
Update repo
helm repo update
Create namespace
kubectl create ns external-dns
Install
- domainFilters – used for limiting the domains that ExternalDNS can manage
- registry=txt – TXT Registry Identifier
- txtOwnerId=k8s – Prefix to create a TXT record with a name following the pattern prefix.<CNAME record>
- sources – K8s resources type to be observed for new DNS entries by ExternalDNS (I added istio-gateway)
IMPORTANT: Make sure that the txtOwnerId is unique when managing the same zone, otherwise DNS records will be deleted and re-added constantly. Basically external-dns will be syncing from multiple locations.
helm install external-dns \ --set provider=google \ --set google.serviceAccountSecret=external-dns \ --set policy=sync \ --set registry=txt \ --set txtOwnerId=k8s-itsmetommy \ --set rbac.create=true \ --set domainFilters={your-doamin.com} \ --set sources="{ingress,istio-gateway,service}" \ -n external-dns \ bitnami/external-dns
Ingress
Single domain.
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: external-dns.alpha.kubernetes.io/hostname: your-domain.com
Multiple domains.
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: external-dns.alpha.kubernetes.io/hostname: foo.your-domain.com,bar.your-domain.com
Service
kubectl annotate service nginx "external-dns.alpha.kubernetes.io/hostname=tommy.itsmetommy.io."
OR
apiVersion: v1 kind: Service metadata: name: nginx annotations: external-dns.alpha.kubernetes.io/hostname: your-domain.com.
Logs
kubectl logs -f `kubectl get pods -n external-dns -o jsonpath="{.items[0].metadata.name}"` -n external-dns
Uninstall
helm delete external-dns -n external-dns
Errors
Error 1
kubectl logs external-dns-d46d86697-4nxlw time="2019-06-12T04:51:45Z" level=fatal msg="google: error getting credentials using GOOGLE_APPLICATION_CREDENTIALS environment variable: open /etc/secrets/service-account/credentials.json: no such file or directory"
Fix.
Make sure your key name is credentials.json.
kubectl create secret generic external-dns \ --from-file=./credentials.json \ --namespace=external-dns
Or edit the existing secret directly.
kubectl edit secret generic external-dns -n external-dns
Error 2
helm install external-dns \ --set provider=google \ --set google.serviceAccountSecret=external-dns \ --set policy=sync \ --set registry=txt \ --set txtOwnerId=k8s \ --set rbac.create=true \ --set domainFilters=your-domain.com \ --set sources="{ingress,istio-gateway,service}" \ -n external-dns \ bitnami/external-dns Error: render error in "external-dns/templates/deployment.yaml": template: external-dns/templates/deployment.yaml:35:27: executing "external-dns/templates/deployment.yaml" at <.Values.domainFilters>: range can't iterate over your-domain.com
Fix.
Use brackets { }.
--set domainFilters={your-domain.com} \
Comments