Customize DNS on a Nexus Kubernetes cluster

Nexus Kubernetes clusters use a combination of CoreDNS and node-local-dns for cluster DNS management and resolution, with node-local-dns taking precedence for name resolution outside the cluster.

Azure Operator Nexus is a managed service, so you can't modify the main configuration for CoreDNS or node-local-dns. Instead, you use a Kubernetes ConfigMap to override the default settings. To see the default CoreDNS and node-local-dns ConfigMaps, use the kubectl get configmaps --namespace=kube-system coredns -o yaml or kubectl get configmaps --namespace=kube-system node-local-dns -o yamlcommand.

This article shows you how to use ConfigMaps for basic DNS customization options in your Nexus Kubernetes cluster.

Prerequisites

Before proceeding with this how-to guide, it's recommended that you:

  • Refer to the Nexus Kubernetes cluster QuickStart guide for a comprehensive overview and steps involved.
  • Ensure that you meet the outlined prerequisites to ensure smooth implementation of the guide.

The ConfigMap data format

Both CoreDNS and node-local-DNS use a Kubernetes ConfigMap to store configuration options. To see the default CoreDNS and node-local-dns ConfigMaps, use kubectl:

console</code> kubectl get configmaps --namespace=kube-system coredns -o yaml kubectl get configmaps --namespace=kube-system node-local-dns -o yaml <code>

When you create configurations like the examples below, the names in the data field must end in .server or .override.

Custom forward server

If you need to specify a forward server for your network traffic, you can create a ConfigMap to customize DNS.

  1. Create a file named customdns.yaml and paste the following example configuration. Make sure to replace the forward name and the address with the values for your own environment. The bind 169.254.20.10 line is required and should not be changed.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: | # you can select any name here, but it must end with the .server file extension
        <domain to be rewritten>.com:53 {
            forward foo.com 1.1.1.1
            bind 169.254.20.10
        }
    
  2. Create the ConfigMap.

    kubectl apply -f customdns.yaml
    
  3. Restart CoreDNS without downtime by performing a Daemonset rollout.

    kubectl rollout restart -n kube-system daemonset/node-local-dns
    

Use custom domains

You might want to configure custom domains that can only be resolved internally. For example, you might want to resolve the custom domain puglife.local, which isn't a valid top-level domain. Without a custom domain ConfigMap, the Nexus Kubernetes cluster can't resolve the address.

  1. Create a new file named customdns.yaml and paste the following example configuration. Make sure to update the custom domain and IP address with the values for your own environment. The bind 169.254.20.10 line is required and should not be modified.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      puglife.server: | # you can select any name here, but it must end with the .server file extension
        puglife.local:53 {
            errors
            cache 30
            forward . 192.11.0.1  # this is my test/dev DNS server
            bind 169.254.20.10
        }
    
  2. Create the ConfigMap.

    kubectl apply -f customdns.yaml
    
  3. Restart CoreDNS without downtime by performing a Daemonset rollout.

    kubectl rollout restart -n kube-system daemonset/node-local-dns
    

Stub domains

CoreDNS can also be used to configure stub domains.

  1. Create a file named customdns.yaml and paste the following example configuration. Make sure to update the custom domains and IP addresses with the values for your own environment. The bind 169.254.20.10 line is required and should not be modified.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: | # you can select any name here, but it must end with the .server file extension
        abc.com:53 {
         errors
         cache 30
         forward . 1.2.3.4
         bind 169.254.20.10
        }
        my.cluster.local:53 {
         errors
         cache 30
         forward . 2.3.4.5
         bind 169.254.20.10
        }
    
    
  2. Create the ConfigMap.

    kubectl apply -f customdns.yaml
    
  3. Restart CoreDNS without downtime by performing a Daemonset rollout.

    kubectl rollout restart -n kube-system daemonset/node-local-dns
    

Hosts plugin

The hosts plugin is available to customize as well.

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom # this is the name of the configmap you can overwrite with your changes
  namespace: kube-system
data:
    test.override: | # you can select any name here, but it must end with the .override file extension
          hosts { 
              10.0.0.1 example1.org
              10.0.0.2 example2.org
              10.0.0.3 example3.org
              fallthrough
          }

Troubleshooting

Enable DNS query logging

  1. Add the following configuration to your coredns-custom ConfigMap:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      log.override: | # you can select any name here, but it must end with the .override file extension
            log
    
  2. Apply the configuration changes, and restart CoreDNS without downtime by performing a Daemonset rollout.:

    # Apply configuration changes
    kubectl apply -f customdns.yaml
    
    # Force CoreDNS to reload the ConfigMap
    kubectl rollout restart -n kube-system daemonset/node-local-dns
    
  3. View the CoreDNS debug logging using the kubectl logs command.

    kubectl logs --namespace kube-system -l k8s-app=node-local-dns