Written by Sam McGeown on 15/12/2020 · Read in about 3 min (482 words)
Published under Cloud-Native

When I deploy a new service into a namespace, I need to create a new DNS record that makes it available. I’ve previously talked about using CoreDNS to host my lab DNS zones, but this is something different. I want to make a Kubernetes Service available using an existing Microsoft DNS server - which is already used by all the clients who would need to access the service.

To do this I will create a delegated zone under my existing zone cmbu.local that CoreDNS will be responsible for. Then I will use the k8s_gateway plugin to automatically create records for Services provisioned within my zone.

Deploying k8s_gateway

The k8s_gateway plugin for CoreDNS automatically creates a DNS record based on the name of the service and it’s namespace, into a zone that you specify. If I create a CoreDNS zone called and then deploy a LoadBalancer called my-lb in a namespace called my-namespace will create a corresponding DNS record of

There’s a handy helm chart to deploy a separate instance of CoreDNS with the plugin configured. By passing the domain value I can configure a zone in which the records for my Services will automatically be created.

With my Kuberentes context pointed at my namespace, I clone the k8s_gateway repository, and deploy the helm chart:

1git clone
2helm install opencart-dns --set domain=moad.cmbu.local ./k8s_gateway/charts/k8s-gateway

This deploys a new instance of CoreDNS and exposes it with a service, to get the IP address of the new service I use kubectl get services

1❯ kubectl get services
2NAME                       TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
3opencart-dns-k8s-gateway   LoadBalancer   53:30482/UDP   9m

Delegating a DNS Zone

Next I create the delgated zone within my Microsoft DNS zone:

Create a new Delegation
Create a new Delegation

The subdomain will be part of the generated DNS name - in my case service-name.namespace.moad.cmbu.local

Name the delegated zone
Name the delegated zone

You can either create an A record for your CoreDNS instance, then add and resolved the FQDN, or manually add a Server FQDN (in my case I just used the generated one) and then add the Service’s IP address from the kubectl output above.

Add the CoreDNS server as authoritative for the zone
Add the CoreDNS server as authoritative for the zone

Testing with a new Service

To validate this is working and to test my new dynamically generated DNS record, I’ve deployed a new service called oc-smcgeown - you can see it in the output of the command below:

1❯ kubectl get services
2NAME                       TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
3oc-smcgeown                LoadBalancer   80:30207/TCP,443:32171/TCP   4m2s
4opencart-dns-k8s-gateway   LoadBalancer   53:30879/UDP                 36m

All being well, my DNS record service-name.namespace-name.moad.cmbu.local should be responding:

1❯ ping oc-smcgeown.opencart.moad.cmbu.local
2PING oc-smcgeown.opencart.moad.cmbu.local ( 56 data bytes
364 bytes from icmp_seq=0 ttl=50 time=168.755 ms
464 bytes from icmp_seq=1 ttl=50 time=168.649 ms
564 bytes from icmp_seq=2 ttl=50 time=168.702 ms
7--- oc-smcgeown.opencart.moad.cmbu.local ping statistics ---
83 packets transmitted, 3 packets received, 0.0% packet loss
9round-trip min/avg/max/stddev = 168.649/168.702/168.755/0.043 ms
Share this post