If like me, you have been working with Azure Kubernetes Service (AKS) or any Kubernetes cluster and want to assign a DNS record to an ingress resource you must manually do it or script something using Azure CLI. Yes, I have done this, and it sort of works. But now you don’t must do it manually or use a script. You can use an awesome tool called ExternalDNS (https://github.com/kubernetes-sigs/external-dns)
ExternalDNS runs on your AKS cluster and when you deploy an Ingress object it will update your DNS zone with the correct record. One good thing with this tool is you can actually manage a lot of DNS providers. In this guide I am going to show you how install it and configure it with Azure DNS.
The how to guide
Before you go ahead and install ExternalDNS on to your cluster you need to set some variables that will be used later. First you need to get your tenant ID and subscription ID. If you have not already login to your azure subscription using the following.
Now that you are logged in and in the correct subscription run the following. I am using bash for this. You can use the cloud shell or wsl 2 with your disto of choice.
Next you need to get the managed identity client id of the AKS clusters node pools. Use the following for that, just change out the resource group and cluster name to match yours.
The last variable you need to get is the DNS Zone resource ID. You can use the following for that, again just change the name and resource group to match yours.
Setting permissions
With all the variables set you can go ahead and grant the managed identity of your cluster’s node pools DNS Zone Contributor rights on to your DNS zone. Just use the following command.
Deploying ExternalDNS
It’s time to deploy ExternalDNS. For this you will be using helm. So, if you do not have it installed go ahead and install now. https://helm.sh/docs/intro/install/ With Helm installed run the following to add the bitnami helm repo to your system.
Even though we have just added the repo its best practice to perform an update to ensure you have the latest charts available. This will also update any other repos you may have.
Time to install ExternalDNS using helm. Just make sure to change cluster name to your cluster name (This way you can have multiple clusters talking to the same DNS zone.) You will also need to change the resource group name to your resource group name where you DNS zone lives.
This will create a deployment, service, and secret in the ExternalDNS name space.
This secret (external-dns) will contain the Azure information we provided with the helm command before. So, Tenant ID, Subscription ID etc.
Now that everything is running its time to do a test deployment. You can use the below yaml for this. It will create a deployment using the nginx webserver container image, a service with cluster IP, and then an Ingress object.
You will need an ingress controller for this to work. The example below expects nginx-ingress. You can install using the following.
Change the ingress host names below to match your domain zone name for this to work also.
Save the above to something like deploy.yaml and then apply it to your cluster using kubectl.
Once deployed go and check your DNS zone in the Azure portal. You should see your records a long with some txt ones.
The txt records are used for ExternalDNS to know which instance manages the corresponding record.
What’s really cool is if you remove the ingress objects it will also remove them from the DNS zone. You can actually change this behaviour so it only adds records, but that means your DNZ zone can get messy, so I prefer to let it delete when needed too.
All in All
All in All, I really like this method of updating DNS from within an AKS cluster. It keeps things nice and neat and less admin effort. It is super easy to setup and integrate. I like to use the node pool managed identity due to when I delete the cluster the managed identity no longer has access to the DNS Zone, one less thing to worry about.
Have any of you used this tool? What’s your thoughts? Reach out to me and let’s have a chat about it and all things Kubernetes.
2 Comments
Adam Rush · June 26, 2021 at 8:23 am
Another great article, thanks! I’ve enjoyed using ExternalDNS for a while now, and thought I’d share an example where I use Terraform to configure ExternalDNS for my AKS clusters: https://github.com/adamrushuk/devops-lab/blob/develop/terraform/dns.tf
Deepak · September 6, 2021 at 2:27 pm
Thanks for this wonderful article , we are also planning to have DNS design for the same spefically for Services inside kubernetes hosted in Multi Cloud Environment.
May you pls guide on this , also will this setup also working with Azure Private DNS Zones.