Consul
Resolve Consul DNS requests in Kubernetes
This topic describes how to resolve Consul DNS requests in Kubernetes. Before you do so, you need to configure KubeDNS or CoreDNS to interface with Consul.
Introduction
Consul DNS is the primary interface for querying records. You can configure Consul DNS in Kubernetes using:
- A stub-domain configuration if using KubeDNS
- A proxy configuration if using CoreDNS
Once configured, DNS requests in the form <consul-service-name>.service.consul
will resolve for services in Consul. This will work from all Kubernetes namespaces.
If you want resolve requests using <consul-service-name>
(without the .service.consul
), then you need to enable service sync.
Retrieve Consul DNS cluster IP
To configure KubeDNS or CoreDNS, you need the ClusterIP
of the Consul DNS service created by the Helm chart.
The default name of the Consul DNS service will be consul-dns
. Use that name to get the ClusterIP
. For this installation, the ClusterIP
is 10.35.240.78
.
$ kubectl get svc consul-dns --output jsonpath='{.spec.clusterIP}'
10.35.240.78%
If you've installed Consul using a different Helm release name than consul
, then the DNS service name will be <release-name>-consul-dns
.
Once you have the ClusterIP
, you can go to the KubeDNS or CoreDNS section that matches your Kubernetes setup.
Configure KubeDNS
If using KubeDNS, you need to create a ConfigMap
that tells KubeDNS to use Consul DNS to resolve all domains ending with .consul
.
First, export the Consul DNS IP as an environment variable. This is the IP address you retrieved in the previous step.
$ export CONSUL_DNS_IP=10.35.240.78
Then, define the ConfigMap
. If using a different zone than .consul
, change the stub domain to that zone.
consul-kubedns-config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
addonmanager.kubernetes.io/mode: EnsureExists
name: kube-dns
namespace: kube-system
data:
stubDomains: |
{ "consul": ["$CONSUL_DNS_IP"] }
Create the ConfigMap
.
$ kubectl apply --filename consul-kubedns-config-map.yaml
Verify that the ConfigMap
was created successfully.
$ kubectl get configmap kube-dns --namespace kube-system --output yaml
apiVersion: v1
data:
stubDomains: |
{"consul": ["10.35.240.78"]}
kind: ConfigMap
## ...
The stubDomain
can only point to a static IP. If the cluster IP of Consul DNS changes, then you must update the ConfigMap
to match the new service IP. The cluster IP of Consul DNS may change if the service is deleted and recreated, such as in full cluster rebuilds.
Now, skip ahead to the Verify DNS section.
Configure CoreDNS
If using CoreDNS, you need to update your existing coredns
ConfigMap in the kube-system
namespace to include a forward
definition for consul
that points to the cluster IP of the Consul DNS service.
Edit the coreDNS
ConfigMap
.
$ kubectl edit configmap coredns --namespace kube-system
You need to edit the following items:
- Add the
consul
block below the default.:53
block. - Replace
<consul-dns-service-cluster-ip>
with the DNS Service's IP address you retrieved previously. - If using a different zone than
.consul
, change the key accordingly.
apiVersion: v1
kind: ConfigMap
metadata:
labels:
addonmanager.kubernetes.io/mode: EnsureExists
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
## Existing CoreDNS definition...
}
consul {
errors
cache 30
forward . <consul-dns-service-cluster-ip>
}
The Consul proxy can only point to a static IP. If the cluster IP of Consul DNS changes, then you must update the ConfigMap
to match the new service IP. The cluster IP of Consul DNS may change if the service is deleted and recreated, such as in full cluster rebuilds.
Verify DNS
To verify DNS works, run the following example job to query DNS. Save the following job to the file job.yaml
.
job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: dns
spec:
template:
spec:
containers:
- name: dns
image: anubhavmishra/tiny-tools
command: ['dig', 'consul.service.consul']
restartPolicy: Never
backoffLimit: 4
Deploy the example job to your cluster.
$ kubectl apply --filename job.yaml
Then, retrieve the pod name of the job.
$ kubectl get pods --show-all | grep dns
dns-lkgzl 0/1 Completed 0 6m
Finally, retrieve the logs for the pod. The logs should show a successful DNS query, something similar to the following. If the logs show any errors, then DNS is not configured properly.
$ kubectl logs dns-lkgzl
; <<>> DiG 9.11.2-P1 <<>> consul.service.consul
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4489
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 4
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;consul.service.consul. IN A
;; ANSWER SECTION:
consul.service.consul. 0 IN A 10.36.2.23
consul.service.consul. 0 IN A 10.36.4.12
consul.service.consul. 0 IN A 10.36.0.11
;; ADDITIONAL SECTION:
consul.service.consul. 0 IN TXT "consul-network-segment="
consul.service.consul. 0 IN TXT "consul-network-segment="
consul.service.consul. 0 IN TXT "consul-network-segment="
;; Query time: 5 msec
;; SERVER: 10.39.240.10#53(10.39.240.10)
;; WHEN: Wed Sep 12 02:12:30 UTC 2018
;; MSG SIZE rcvd: 206