If you have ever deployed Kubernetes services, you understand the pain of having to maintain DNS records for an ever-growing number of internal and external services. ExternalDNS helps address this pain and reduces the amount of toil required for manual record keeping by programmatically updating DNS servers. Before we get into the details of how that works, let’s quickly review what functionality the ExternalDNS package provides:
“Inspired by Kubernetes DNS, Kubernetes' cluster-internal DNS server, ExternalDNS makes Kubernetes resources discoverable via public DNS servers. Like KubeDNS, it retrieves a list of resources (services, ingresses, etc.) from the Kubernetes API to determine a desired list of DNS records. Unlike KubeDNS, however, it is not a DNS server itself, but merely configures other DNS providers accordingly—e.g. AWS Route 53 or Google Cloud DNS.”
This guide focuses on using the VMware Tanzu Mission Control Catalog for deploying and configuring the ExternalDNS package, specifically for Route53 on Amazon Web Services (AWS).
Note that these steps are not covered in this post and should be completed before proceeding:
Create a permissions policy that allows external DNS updates
Create a new user in IAM
Create a subdomain on the hosted zone
Have your user API access and secret key available
Create the secret
We first need to create a Kubernetes secret that contains the AWS credentials. ExternalDNS needs the AWS credentials to make modifications to the Route 53 DNS tables. Open a text editor and paste the content below into it:
apiVersion: v1 kind: Secret metadata: name: aws-externaldns namespace: tanzu-system-service-discovery type: Opaque stringData: access-key-id: << ACCESS KEY ID >> secret-access-key: << SECRET ACCESS KEY >>
Modify the name, access-key-id, and secret-access-key to meet your requirements and save the file as “secret.yaml”.
Open a terminal in the same directory where you saved the secret.yaml file, and execute the following to the secret to the tanzu-system-service-discovery namespace:
kubectl apply -f secret.yaml
Deploy the package
Log in to the Tanzu Mission Control console by visiting your organization’s URL:
Click on “Catalog” on the left-side menu and click on the external-dns package.
Click “Install Package” at the top right of the view. Enter the name for the package install and click “Next”.
In step two, leave these values at the default. The namespace selected here is only used to install the package. ExternalDNS will be installed to the tanzu-system-service-discovery namespace. Click “Next”.
Here is an example of an ExternalDNS configuration for Route53. The arguments are going to be similar for any Route53 configuration, but be sure to change the domain-filter, policy, aws-zone-type, and txt-owner-id to the required values. The environment variables are utilizing the Kubernetes secret that was created in an earlier step. After modifying the below YAML config, copy and paste it into the “Your Configured Values” text box in step 3:
deployment: args: - --source=service - --source=ingress - --provider=aws - --domain-filter=<your domain here> - --events - --policy=sync - --aws-zone-type=private - --aws-prefer-cname - --registry=txt - --txt-owner-id=<zone ID> - --txt-prefix=txt env: - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: key: access-key-id name: aws-externaldns - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: key: secret-access-key name: aws-externaldns
Note: You will need to add the following to the deployment args block if you are using service accounts as a role with trust relationships:
Now that the package has been deployed to the cluster, you will see a status of “Reconciling”. Once installation has completed, the status will show “Succeeded” with a green check.
Let’s deploy a sample Nginx service to verify that ExternalDNS is working. The annotation of the service will determine the DNS name that will be configured on the DNS server once the service is available. Copy and paste the below YAML into a file named “nginx-test.yaml” and replace "<your domain here>" with the desired domain:
apiVersion: v1 kind: Service metadata: name: nginx annotations: external-dns.alpha.kubernetes.io/hostname: <your domain here> spec: type: LoadBalancer ports: - port: 80 name: http targetPort: 80 selector: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx ports: - containerPort: 80 name: http
Apply the YAML to your cluster with the following:
kubectl apply –f nginx-test.yaml
Check the AWS Route 53 console to ensure the DNS entries have been added automatically.
Notice the records added by ExternalDNS:
Now let’s remove the test services to make sure deletion works properly. To remove the test service and pods and to confirm the DNS entries have been removed, execute the following:
kubectl delete –f nginx-test.yaml
This demonstration has shown how easy it is to get started using the Tanzu Mission Control Catalog. To learn more about Tanzu Mission Control Catalog, check out the recent launch announcement. You can also get free hands-on experience with Tanzu Mission Control through the Tanzu Standard Pathfinder course. Stay up to date with new features and fixes with the Tanzu Mission Control release notes.