ExternalDNS

In this demo we present ExternalDNS, a tool allowing to control DNS records dynamically via Kubernetes resources.

logo

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.

Role

Next we create an API Key associated with this role.

API Key

We save the Key and Secret in the API_KEY and API_SECRET environment variables. We’ll use them in a next section.

API Key

export EXOSCALE_API_KEY=...
export EXOSCALE_API_SECRET=...
The API Key and API Secret in the screenshot above are dummy ones

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
We selected Traefik in this example, but there are many other Ingress Controller implementations including Nginx, HAProxy, Kong.

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.

values.yaml
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.

A Record
screenshot from Exoscale DNS

The web interfaces of the VotingApp are now available at http://vote.votingapp.cc and http://result.votingapp.cc

Vote

Result

⚠️
It may take a few minutes for the DNS propagation to be done.

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.

ℹ️
Feel free to explore ExternalDNS features in more details.