2018-09-12 15:44:30 +00:00
---
2020-04-07 18:55:19 +00:00
layout: docs
2022-09-14 22:26:14 +00:00
page_title: Resolve Consul DNS requests in Kubernetes
2020-04-07 18:55:19 +00:00
description: >-
2022-09-16 15:28:32 +00:00
Use a k8s ConfigMap to configure KubeDNS or CoreDNS so that you can use Consul's `<service-name>.service.consul` syntax for queries and other DNS requests. In Kubernetes, this process uses either stub-domain or proxy configuration.
2018-09-12 15:44:30 +00:00
---
2022-09-15 19:33:39 +00:00
# Resolve Consul DNS Requests in Kubernetes
2018-09-12 15:44:30 +00:00
One of the primary query interfaces to Consul is the
2023-01-25 16:52:43 +00:00
[DNS interface](/consul/docs/discovery/dns). You can configure Consul DNS in
2019-09-06 09:33:13 +00:00
Kubernetes using a
[stub-domain configuration](https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configure-stub-domain-and-upstream-dns-servers)
if using KubeDNS or a [proxy configuration](https://coredns.io/plugins/proxy/) if using CoreDNS.
2018-09-12 15:44:30 +00:00
2019-09-06 09:34:11 +00:00
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.
2018-09-12 15:44:30 +00:00
2019-09-06 09:34:11 +00:00
-> **Note:** If you want requests to just `<consul-service-name>` (without the `.service.consul`) to resolve, then you'll need
2023-01-25 16:52:43 +00:00
to turn on [Consul to Kubernetes Service Sync](/consul/docs/k8s/service-sync#consul-to-kubernetes).
2019-09-06 09:33:13 +00:00
## Consul DNS Cluster IP
2020-04-06 20:27:35 +00:00
2019-09-06 09:34:11 +00:00
To configure KubeDNS or CoreDNS you'll first need the `ClusterIP` of the Consul
2023-01-25 16:52:43 +00:00
DNS service created by the [Helm chart](/consul/docs/k8s/helm).
2019-09-06 09:33:13 +00:00
2022-04-01 14:38:56 +00:00
The default name of the Consul DNS service will be `consul-dns`. Use
2019-09-06 09:33:13 +00:00
that name to get the `ClusterIP`:
2020-05-19 18:32:38 +00:00
```shell-session
2022-04-01 14:38:56 +00:00
$ kubectl get svc consul-dns --output jsonpath='{.spec.clusterIP}'
2019-09-06 09:33:13 +00:00
10.35.240.78%
```
2020-04-06 20:27:35 +00:00
For this installation the `ClusterIP` is `10.35.240.78`.
2019-09-06 09:33:13 +00:00
2019-09-06 09:34:11 +00:00
-> **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`.
2019-09-06 09:33:13 +00:00
## KubeDNS
2020-04-06 20:27:35 +00:00
2019-09-06 09:33:13 +00:00
If using KubeDNS, you need to create a `ConfigMap` that tells KubeDNS
to use the Consul DNS service to resolve all domains ending with `.consul`:
Export the Consul DNS IP as an environment variable:
```bash
export CONSUL_DNS_IP=10.35.240.78
2018-09-12 15:44:30 +00:00
```
2019-09-06 09:33:13 +00:00
And create the `ConfigMap`:
2020-05-19 18:32:38 +00:00
```shell-session
2022-01-12 23:05:01 +00:00
$ cat <<EOF | kubectl apply --filename -
2018-09-12 15:44:30 +00:00
apiVersion: v1
kind: ConfigMap
metadata:
labels:
addonmanager.kubernetes.io/mode: EnsureExists
name: kube-dns
namespace: kube-system
data:
stubDomains: |
2019-09-06 09:33:13 +00:00
{"consul": ["$CONSUL_DNS_IP"]}
2018-09-12 15:44:30 +00:00
EOF
2019-09-06 09:33:13 +00:00
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
configmap/kube-dns configured
```
Ensure that the `ConfigMap` was created successfully:
2020-05-19 18:32:38 +00:00
```shell-session
2022-01-12 23:05:01 +00:00
$ kubectl get configmap kube-dns --namespace kube-system --output yaml
2019-09-06 09:33:13 +00:00
apiVersion: v1
data:
stubDomains: |
{"consul": ["10.35.240.78"]}
kind: ConfigMap
...
2018-09-12 15:44:30 +00:00
```
-> **Note:** The `stubDomain` can only point to a static IP. If the cluster IP
2020-04-06 20:27:35 +00:00
of the Consul DNS service changes, then it must be updated in the config map to
2019-03-20 17:08:30 +00:00
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.
2019-09-06 09:33:13 +00:00
-> **Note:** If using a different zone than `.consul`, change the stub domain to
that zone.
Now skip ahead to the [Verifying DNS Works](#verifying-dns-works) section.
2019-03-20 17:08:30 +00:00
## CoreDNS Configuration
2019-09-06 09:33:13 +00:00
If using CoreDNS instead of KubeDNS in your Kubernetes cluster, you will
2019-03-20 17:08:30 +00:00
need to update your existing `coredns` ConfigMap in the `kube-system` namespace to
2019-09-06 09:33:13 +00:00
include a `forward` definition for `consul` that points to the cluster IP of the
Consul DNS service.
Edit the `ConfigMap`:
2019-03-20 17:08:30 +00:00
2020-05-19 18:32:38 +00:00
```shell-session
2022-01-12 23:05:01 +00:00
$ kubectl edit configmap coredns --namespace kube-system
2019-03-20 17:08:30 +00:00
```
2019-09-06 09:33:13 +00:00
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.
```diff
2019-03-20 17:08:30 +00:00
apiVersion: v1
kind: ConfigMap
metadata:
labels:
addonmanager.kubernetes.io/mode: EnsureExists
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
<Existing CoreDNS definition>
}
2019-09-06 09:33:13 +00:00
+ consul {
+ errors
+ cache 30
+ forward . <consul-dns-service-cluster-ip>
+ }
2019-03-20 17:08:30 +00:00
```
-> **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
2018-09-12 15:44:30 +00:00
working. This can happen if the service is deleted and recreated, such as
in full cluster rebuilds.
2019-09-06 09:33:13 +00:00
-> **Note:** If using a different zone than `.consul`, change the key accordingly.
2018-09-12 15:44:30 +00:00
## Verifying DNS Works
To verify DNS works, run a simple job to query DNS. Save the following
job to the file `job.yaml` and run it:
2021-07-31 01:37:33 +00:00
<CodeBlockConfig filename="job.yaml">
2018-09-12 15:44:30 +00:00
```yaml
apiVersion: batch/v1
kind: Job
metadata:
name: dns
spec:
template:
spec:
containers:
2020-04-06 20:27:35 +00:00
- name: dns
image: anubhavmishra/tiny-tools
command: ['dig', 'consul.service.consul']
2018-09-12 15:44:30 +00:00
restartPolicy: Never
backoffLimit: 4
```
2021-07-31 01:37:33 +00:00
</CodeBlockConfig>
2020-05-19 18:32:38 +00:00
```shell-session
2022-01-12 23:05:01 +00:00
$ kubectl apply --filename job.yaml
2018-09-12 15:44:30 +00:00
```
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.
2020-05-19 18:32:38 +00:00
```shell-session
2018-09-12 15:44:30 +00:00
$ kubectl get pods --show-all | grep dns
dns-lkgzl 0/1 Completed 0 6m
$ 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
```