Consul DNS on Kubernetes

    Once configured, DNS requests in the form will resolve for services in Consul. This will work from all Kubernetes namespaces.

    Note: If you want requests to just <consul-service-name> (without the .service.consul) to resolve, then you’ll need to turn on Consul to Kubernetes Service Sync.

    To configure KubeDNS or CoreDNS you’ll first need the ClusterIP of the Consul DNS service created by the .

    The default name of the Consul DNS service will be consul-dns. Use that name to get the ClusterIP:

    1. $ kubectl get svc consul-dns --output jsonpath='{.spec.clusterIP}'
    2. 10.35.240.78%

    For this installation the ClusterIP is 10.35.240.78.

    Note: If you’ve installed Consul using a different helm release name than consul then the DNS service name will be <release-name>-consul-dns.

    Export the Consul DNS IP as an environment variable:

    1. export CONSUL_DNS_IP=10.35.240.78
    1. export CONSUL_DNS_IP=10.35.240.78

    And create the ConfigMap:

    1. $ cat <<EOF | kubectl apply --filename -
    2. apiVersion: v1
    3. kind: ConfigMap
    4. metadata:
    5. labels:
    6. addonmanager.kubernetes.io/mode: EnsureExists
    7. name: kube-dns
    8. namespace: kube-system
    9. data:
    10. stubDomains: |
    11. {"consul": ["$CONSUL_DNS_IP"]}
    12. EOF
    13. Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
    14. configmap/kube-dns configured
    1. $ cat <<EOF | kubectl apply --filename -
    2. apiVersion: v1
    3. kind: ConfigMap
    4. metadata:
    5. labels:
    6. addonmanager.kubernetes.io/mode: EnsureExists
    7. name: kube-dns
    8. namespace: kube-system
    9. data:
    10. stubDomains: |
    11. {"consul": ["$CONSUL_DNS_IP"]}
    12. EOF
    13. Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
    14. configmap/kube-dns configured

    Ensure that the ConfigMap was created successfully:

    1. $ kubectl get configmap kube-dns --namespace kube-system --output yaml
    2. apiVersion: v1
    3. data:
    4. stubDomains: |
    5. {"consul": ["10.35.240.78"]}
    6. kind: ConfigMap
    7. ...

    Note: The stubDomain can only point to a static IP. If the cluster IP of the Consul DNS service changes, then it must be updated in the config map to match the new service IP for this to continue working. This can happen if the service is deleted and recreated, such as in full cluster rebuilds.

    Note: If using a different zone than .consul, change the stub domain to that zone.

    Now skip ahead to the Verifying DNS Works section.

    Edit the ConfigMap:

    1. $ kubectl edit configmap coredns --namespace kube-system
    1. $ kubectl edit configmap coredns --namespace kube-system

    And add the consul block below the default .:53 block and replace <consul-dns-service-cluster-ip> with the DNS Service’s IP address you found previously.

    1. apiVersion: v1
    2. kind: ConfigMap
    3. metadata:
    4. labels:
    5. addonmanager.kubernetes.io/mode: EnsureExists
    6. namespace: kube-system
    7. data:
    8. Corefile: |
    9. .:53 {
    10. <Existing CoreDNS definition>
    11. }
    12. + consul {
    13. + errors
    14. + cache 30
    15. + forward . <consul-dns-service-cluster-ip>
    16. + }
    1. apiVersion: v1
    2. kind: ConfigMap
    3. metadata:
    4. labels:
    5. addonmanager.kubernetes.io/mode: EnsureExists
    6. name: coredns
    7. namespace: kube-system
    8. data:
    9. Corefile: |
    10. .:53 {
    11. <Existing CoreDNS definition>
    12. }
    13. + consul {
    14. + errors
    15. + cache 30
    16. + forward . <consul-dns-service-cluster-ip>
    17. + }

    Note: The consul proxy can only point to a static IP. If the cluster IP of the consul-dns service changes, then it must be updated to the new IP to continue working. This can happen if the service is deleted and recreated, such as in full cluster rebuilds.

    Note: If using a different zone than .consul, change the key accordingly.

    To verify DNS works, run a simple job to query DNS. Save the following job to the file job.yaml and run it:

    1. apiVersion: batch/v1
    2. kind: Job
    3. metadata:
    4. name: dns
    5. spec:
    6. template:
    7. spec:
    8. containers:
    9. - name: dns
    10. image: anubhavmishra/tiny-tools
    11. command: ['dig', 'consul.service.consul']
    12. restartPolicy: Never
    13. backoffLimit: 4
    1. $ kubectl apply --filename job.yaml

    Then query the pod name for the job and check the logs. You should see output similar to the following showing a successful DNS query. If you see any errors, then DNS is not configured properly.

    1. $ kubectl get pods --show-all | grep dns
    2. dns-lkgzl 0/1 Completed 0 6m
    3. $ kubectl logs dns-lkgzl
    4. ; <<>> DiG 9.11.2-P1 <<>> consul.service.consul
    5. ;; global options: +cmd
    6. ;; Got answer:
    7. ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 4
    8. ;; OPT PSEUDOSECTION:
    9. ; EDNS: version: 0, flags:; udp: 4096
    10. ;; QUESTION SECTION:
    11. ;consul.service.consul. IN A
    12. ;; ANSWER SECTION:
    13. consul.service.consul. 0 IN A 10.36.2.23
    14. consul.service.consul. 0 IN A 10.36.4.12
    15. consul.service.consul. 0 IN A 10.36.0.11
    16. ;; ADDITIONAL SECTION:
    17. consul.service.consul. 0 IN TXT "consul-network-segment="
    18. consul.service.consul. 0 IN TXT "consul-network-segment="
    19. consul.service.consul. 0 IN TXT "consul-network-segment="
    20. ;; Query time: 5 msec
    21. ;; SERVER: 10.39.240.10#53(10.39.240.10)
    22. ;; WHEN: Wed Sep 12 02:12:30 UTC 2018
    23. ;; MSG SIZE rcvd: 206
    1. $ kubectl get pods --show-all | grep dns
    2. dns-lkgzl 0/1 Completed 0 6m
    3. $ kubectl logs dns-lkgzl
    4. ; <<>> DiG 9.11.2-P1 <<>> consul.service.consul
    5. ;; global options: +cmd
    6. ;; Got answer:
    7. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4489
    8. ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 4
    9. ;; OPT PSEUDOSECTION:
    10. ; EDNS: version: 0, flags:; udp: 4096
    11. ;; QUESTION SECTION:
    12. ;consul.service.consul. IN A
    13. ;; ANSWER SECTION:
    14. consul.service.consul. 0 IN A 10.36.2.23
    15. consul.service.consul. 0 IN A 10.36.4.12
    16. consul.service.consul. 0 IN A 10.36.0.11
    17. ;; ADDITIONAL SECTION:
    18. consul.service.consul. 0 IN TXT "consul-network-segment="
    19. consul.service.consul. 0 IN TXT "consul-network-segment="
    20. consul.service.consul. 0 IN TXT "consul-network-segment="
    21. ;; Query time: 5 msec
    22. ;; SERVER: 10.39.240.10#53(10.39.240.10)
    23. ;; WHEN: Wed Sep 12 02:12:30 UTC 2018