In this article, we are going to learn how to setup external dns in your cluster. External DNS helps you to automatically manages the DNS records of your ingresses and services, saving you so much time!. In a nutshell, external DNS is a pod that runs in your EKS cluster and monitors all of your ingresses. When it detects an ingress with a defined host, it automatically retrieves the hostname as well as the endpoint and generates a record in Route53 for that resource. If the host is updated or destroyed, external DNS will immediately update Route53. Let's get started.
Create IAM Policy
First, we need to create an IAM policy that allows external DNS to access Route53. Go to IAM -> Policies -> Create Policy. Then click on Create Policy. Select the JSON tab and paste the following policy.
or you can create the following policy using AWS CLI also. First, create a file called external-dns-policy.json and paste the above policy.
Then run the following command to create the policy.
1
aws iam create-policy --policy-name <your-policy-name> --policy-document file://external-dns-policy.json
You can check whether the policy is created using the following command.
1
aws iam list-policies --scope Local
Now we have finished creating the policy. Next, we need to create a service account for external DNS by attaching the policy we created earlier.
Create Service Account
Now we need to create a service account for the external-dns to use. This service account will be assigned the IAM policy we created in the previous step. To create a service account, run the following command.
Note: Replace the following values in the above command:
SERVICE_ACCOUNT_NAME: The name of the service account you want to create. For example, external-dns.
NAMESPACE: The namespace you want to create the service account in. For example, default.
CLUSTER_NAME: The name of the EKS cluster you want to create the service account in.
IAM_POLICY_ARN: The ARN of the IAM policy you created in the previous step.
To check if the service account was created successfully, run the following command:
1
kubectl get sa -n NAMESPACE
Create Role and RoleBinding
Now we need to create a role and role binding for the service account we created in the previous step. To create a role and role binding you can use the following YAML file.
apiVersion:rbac.authorization.k8s.io/v1 kind:ClusterRole metadata: name:external-dns rules: -apiGroups: [""] resources: ["services","endpoints","pods"] verbs: ["get","watch","list"] -apiGroups: ["extensions","networking.k8s.io"] resources: ["ingresses"] verbs: ["get","watch","list"] -apiGroups: [""] resources: ["nodes"] verbs: ["list","watch"] --- apiVersion:rbac.authorization.k8s.io/v1 kind:ClusterRoleBinding metadata: name:external-dns-viewer roleRef: apiGroup:rbac.authorization.k8s.io kind:ClusterRole name:external-dns subjects: -kind:ServiceAccount name:SERVICE_ACCOUNT### Service Account Name which we created in previous step namespace:NAMESPACE### Namespace where we created the service account
Then run the following command to create the role and role binding.
1
kubectl apply -f <your-file-name>.yaml
Install External DNS
Now we are ready to install external DNS. To install external DNS, we need to create a deployment. To create a deployment, you can use the following YAML file.
apiVersion:apps/v1 kind:Deployment metadata: name:external-dns spec: strategy: type:Recreate selector: matchLabels: app:external-dns template: metadata: labels: app:external-dns spec: serviceAccountName:external-dns containers: -name:external-dns image:registry.k8s.io/external-dns/external-dns:v0.13.4### You can find the latest version of the image here: https://github.com/kubernetes-sigs/external-dns/releases args: ---source=service ---source=ingress ---domain-filter=YOUR_DOMIAN_NAME# will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones ---provider=aws ---policy=upsert-only# would prevent ExternalDNS from deleting any records, omit to enable full synchronization ---aws-zone-type=public# only look at public hosted zones (valid values are public, private or no value for both) ---registry=txt ---txt-owner-id=HOSTED_ZONE_ID securityContext: fsGroup:65534# For ExternalDNS to be able to read Kubernetes and AWS token files
You can find original template from here and you can find more information about the parameters from [here]and you can find more configuration options for the ExternalDNS deployment here
Then run the following command to create the deployment.
1
kubectl apply -f external-dns-deployment.yaml
Test External DNS
Now we have finished installing external DNS. Let's test it. Let's create simple deployment and service to test external DNS. To create a deployment and service, you can use the following YAML file.
apiVersion:v1 kind:Service metadata: name:nginx annotations: external-dns.alpha.kubernetes.io/hostname:nginx.example.com### This is the domain name which we want to point to the nginx service spec: ports: -port:80 targetPort:80 protocol:TCP type:LoadBalancer selector: app:nginx
Now run the following command to create the deployment and service.
1
kubectl apply -f nginx-deployment.yaml
Now you can check whether the external DNS has created the DNS record for the nginx service. To check that, go to Route53 -> Hosted Zones -> YOUR_DOMAIN_NAME. You can see that external DNS has created the DNS record for the nginx service.
Conclusion
In this article, we learned how to setup external dns in your cluster. I hope you enjoyed this article. You can find the all the related commands for this tutorial from here. If you have any issue regarding this tutorial, mention your issue in the comment section or reach me through my E-mail.