On-Premise Dynamic DNS with Kubernetes and CoreDNS

Tyler Lisowski
3 min readJun 6, 2022

Kubernetes users in some on premise environments have a need to be able to configure DNS entries on demand similar to what is done in popular platforms like Cloudflare, Akamai, or private DNS services offered by Cloud Providers. Dynamic DNS allows users to provision a domain for an on-premise application and be able to access the application over that domain instead of tracking IP addresses. Kubernetes headless services and CoreDNS rewrite rules can be utilized to allow a user to define a DNS entry for any domain and have it map to the IPs they choose. This guide utilizes an IBM Cloud Satellite Red Hat Openshift cluster to illustrate.This guide will walk through creating a DNS entry: my-on-prem-application-17146.com that resolves to 3 redundant IPs that map to the on-premise application.

First: we will create the headless service and associated endpoint IPs in an isolated namespace that will serve as the basis for the IP information. In our example: the IPs that serve the on premise application are going to be: 172.19.1.1, 172.19.1.2, and 172.19.1.3. The following resources will create an isolated namespace and associated service and endpoint information to create the dns entry:

We will test that everything is created appropriately by execing into a pod in the pod network and issuing a DNS resolution of my-on-prem-application-17146.custom-dns.svc.cluster.local.

kubectl apply -f https://gist.githubusercontent.com/relyt0925/f0c8cd941dd9bc316b385ab38815f627/raw/6ef9c631586f343b28848742649e006199cdf169/my-on-prem-application-17146-customdns-entry.yaml
namespace/custom-dns unchanged
service/my-on-prem-application-17146 unchanged
endpoints/my-on-prem-application-17146 created
kubectl exec -it -n openshift-console console-67659bb768-9xwgm bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.4$ nslookup my-on-prem-application-17146.custom-dns.svc.cluster.local
Server: 172.21.0.10
Address: 172.21.0.10#53
Name: my-on-prem-application-17146.custom-dns.svc.cluster.local
Address: 172.19.1.1
Name: my-on-prem-application-17146.custom-dns.svc.cluster.local
Address: 172.19.1.2
Name: my-on-prem-application-17146.custom-dns.svc.cluster.local
Address: 172.19.1.3
bash-4.4$

At this point: we have a DNS entry that will map to the 3 IPs we desire however it does not match the domain we are expecting to serve the application over which is my-on-prem-application-17146.com. CoreDNS will now be deployed which will handle ensuring that domain name is ultimately resolved to the same IPs using rewrite rules. The configuration to accomplish that is shown below:

The config above deploys a CoreDNS instance with a rewrite rule that is going to ensure any DNS requests for my-on-prem-application-17146.com will map to the IPs defined in the headless service defined previously. Once deployed: the domain lookup can be verified by sending a DNS request to the CoreDNS instance with the rewrite rule for my-on-prem-application-17146.com. That is shown below:

kubectl get service -n custom-dns
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
coredns ClusterIP 172.21.53.31 <none> 53/UDP,53/TCP,9153/TCP 6m24skubectl exec -it -n openshift-console console-67659bb768-9xwgm bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.4$ nslookup my-on-prem-application-17146.com 172.21.53.31
Server: 172.21.53.31
Address: 172.21.53.31#53
Name: my-on-prem-application-17146.com
Address: 172.19.1.1
Name: my-on-prem-application-17146.com
Address: 172.19.1.2
Name: my-on-prem-application-17146.com
Address: 172.19.1.3

Lastly: DNS requests for this domain need to be forwarded from the standard Openshift CoreDNS instances to this dedicated coreDNS instance. That is done by applying the following Openshift DNS configuration:

The structure tells the standard Openshift CoreDNS deployment to forward DNS requests for my-on-prem-application-17146.com to the service IP of the deployed CoreDNS instance that has the configuration to serve our domain. At this point: all pods will be able to resolve the domain appropriately:

kubectl exec -it -n openshift-console console-67659bb768-9xwgm bash
bash-4.4$ nslookup my-on-prem-application-17146.com
Server: 172.21.0.10
Address: 172.21.0.10#53
Name: my-on-prem-application-17146.com
Address: 172.19.1.1
Name: my-on-prem-application-17146.com
Address: 172.19.1.2
Name: my-on-prem-application-17146.com
Address: 172.19.1.3

Congratulations! At this point the custom DNS entry is live for all pods that are configured to talk to the Openshift CoreDNS servers in the cluster. This strategy can be utilized for any DNS name. Additionally: if the Openshift DNS service is exposed outside the cluster network: non Openshift machines can be configured to point their resolvers to the Openshift CoreDNS deployment and be able to resolve the domain outside of the Openshift cluster!

--

--

Tyler Lisowski

IBM Cloud Satellite Lead Architect. Proud member of Bills Mafia.