ExternalDNS
In this demo we present ExternalDNS, a tool allowing to control DNS records dynamically via Kubernetes resources.
Prerequisites
We need a Kubernetes cluster, which can be created following these instructions. We also need the kubectl binary configured with the cluster’s kubeconfig, and the helm binary.
Creating an IAM role
Since ExternalDNS requires access to DNS records, we must provide the necessary credentials. From the Exoscale portal, we first create a role giving access to the DNS service.
Next we create an API Key associated with this role.
We save the Key and Secret in the API_KEY and API_SECRET environment variables. We’ll use them in a next section.
export EXOSCALE_API_KEY=...
export EXOSCALE_API_SECRET=...
Installing Traefik
Since we’ll expose applications to the outside, we install Traefik Ingress Controller:
helm repo add traefik https://traefik.github.io/charts
helm install traefik traefik/traefik --version 33.2.1 -n traefik --create-namespace
Installing ExternalDNS
Before installing ExternalDNS, we create a Secret containing the API Key and Secret in the external-dns namespace.
kubectl create ns external-dns
kubectl -n external-dns create secret generic exo \
--from-literal=exoscale_api_key=$EXOSCALE_API_KEY \
--from-literal=exoscale_api_token=$EXOSCALE_API_SECRET
Next we install the ExternalDNS Helm Chart. We provide the Secret created above, as ExternalDNS will need to manipulate records in Exoscale DNS provider.
helm install -n external-dns external-dns \
--set provider=exoscale \
--set exoscale.secretName=exo \
--version "8.7.1" \
oci://registry-1.docker.io/bitnamicharts/external-dns
Deploying a sample application
We consider the VotingApp demo application.
First, we create a values.yaml file which ensures the application is exposed on specific subdomains.
ingress:
enabled: true
hosts:
vote: vote.votingapp.cc
result: result.votingapp.cc
Next, we deploy the application.
helm install vote oci://registry-1.docker.io/voting/app --version v1.0.36 --namespace vote --create-namespace -f values.yaml
Then, we verify the application Pods are running.
$ kubectl get po -n vote
NAME READY STATUS RESTARTS AGE
db-67f8c9c997-j9lp2 1/1 Running 0 15s
redis-7f746b589b-6dvv7 1/1 Running 0 15s
result-7f4b9fc65f-vd965 1/1 Running 0 15s
result-ui-6f58969896-jcc67 1/1 Running 0 15s
vote-7d74bd574c-wbg44 1/1 Running 0 15s
vote-ui-866b66996f-q4qkz 1/1 Running 0 15s
worker-6bf5f5f988-28rrj 1/1 Running 0 15s
Through the Ingress resource, we see the application’s web interfaces are exposed on vote.votingapp.cc and result.votingapp.com as we requested.
$ kubectl get ingress -n vote
NAME CLASS HOSTS ADDRESS PORTS AGE
vote traefik vote.votingapp.cc,result.votingapp.cc 89.145.166.61 80 53s
The IP address associated with the Ingress resource corresponds to the Load balancer Service exposing the Traefik Ingress Controller:
$ kubectl get svc -n traefik
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.110.147.184 89.145.166.61 80:30718/TCP,443:30763/TCP 5m
Thanks to ExternalDNS, a new DNS A record was automatically created, mapping both subdomains to this specific IP address. This record was created because ExternalDNS continuously watches Ingress resources (as well as other Kubernetes resources) and manages DNS records based on the annotations and content of these resources.
The web interfaces of the VotingApp are now available at http://vote.votingapp.cc and http://result.votingapp.cc
Cleanup
We remove our demo application, ExternalDNS, cert-manager and Traefik Ingress Controller:
helm uninstall -n vote vote
helm uninstall -n external-dns external-dns
helm uninstall -n traefik traefik
We should also remove the vote and result subdomains.