0% found this document useful (0 votes)
10 views5 pages

Troubleshooting Kubernetes DNS Issues

Uploaded by

Rohan Ashish
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views5 pages

Troubleshooting Kubernetes DNS Issues

Uploaded by

Rohan Ashish
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Debugging DNS Resolution

This page provides hints on diagnosing DNS problems.

Before you begin


You need to have a Kubernetes cluster, and the kubectl command-line tool must be
configured to communicate with your cluster. It is recommended to run this tutorial on
a cluster with at least two nodes that are not acting as control plane hosts. If you do
not already have a cluster, you can create one by using minikube or you can use one
of these Kubernetes playgrounds:

 Killercoda
 Play with Kubernetes

Your cluster must be configured to use the CoreDNS addon or its precursor, kube-dns.
Your Kubernetes server must be at or later than version v1.6. To check the version,
enter kubectl version.

Create a simple Pod to use as a test environment

admin/dns/[Link]
apiVersion: v1
kind: Pod
metadata:
name: dnsutils
namespace: default
spec:
containers:
- name: dnsutils
image: [Link]/e2e-test-images/jessie-dnsutils:1.3
command:
- sleep
- "infinity"
imagePullPolicy: IfNotPresent
restartPolicy: Always
Note: This example creates a pod in the default namespace. DNS name resolution for
services depends on the namespace of the pod. For more information, review DNS for
Services and Pods.
Use that manifest to create a Pod:

kubectl apply -f [Link]


pod/dnsutils created
…and verify its status:

kubectl get pods dnsutils


NAME READY STATUS RESTARTS AGE
dnsutils 1/1 Running 0 <some-time>
Once that Pod is running, you can exec nslookup in that environment. If you see
something like the following, DNS is working correctly.

kubectl exec -i -t dnsutils -- nslookup [Link]


Server: [Link]
Address 1: [Link]
Name: [Link]
Address 1: [Link]
If the nslookup command fails, check the following:

Check the local DNS configuration first

Take a look inside the [Link] file. (See Customizing DNS Service and Known
issues below for more information)

kubectl exec -ti dnsutils -- cat /etc/[Link]


Verify that the search path and name server are set up like the following (note that
search path may vary for different cloud providers):

search [Link] [Link] [Link] [Link]


c.gce_project_id.internal
nameserver [Link]
options ndots:5
Errors such as the following indicate a problem with the CoreDNS (or kube-dns) add-
on or with associated Services:

kubectl exec -i -t dnsutils -- nslookup [Link]


Server: [Link]
Address 1: [Link]

nslookup: can't resolve '[Link]'


or

kubectl exec -i -t dnsutils -- nslookup [Link]


Server: [Link]
Address 1: [Link] [Link]

nslookup: can't resolve '[Link]'

Check if the DNS pod is running

Use the kubectl get pods command to verify that the DNS pod is running.

kubectl get pods --namespace=kube-system -l k8s-app=kube-dns


NAME READY STATUS RESTARTS AGE
...
coredns-7b96bf9f76-5hsxb 1/1 Running 0 1h
coredns-7b96bf9f76-mvmmt 1/1 Running 0 1h
...
Note: The value for label k8s-app is kube-dns for both CoreDNS and kube-dns
deployments.
If you see that no CoreDNS Pod is running or that the Pod has failed/completed, the
DNS add-on may not be deployed by default in your current environment and you will
have to deploy it manually.

Check for errors in the DNS pod

Use the kubectl logs command to see logs for the DNS containers.

For CoreDNS:

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


Here is an example of a healthy CoreDNS log:

.:53
2018/08/15 14:37:17 [INFO] CoreDNS-1.2.2
2018/08/15 14:37:17 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.2
linux/amd64, go1.10.3, 2e322f6
2018/08/15 14:37:17 [INFO] plugin/reload: Running configuration MD5 =
24e6c59e83ce706f07bcc82c31b1ea1c
See if there are any suspicious or unexpected messages in the logs.

Is DNS service up?

Verify that the DNS service is up by using the kubectl get service command.

kubectl get svc --namespace=kube-system


NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
kube-dns ClusterIP [Link] <none> 53/UDP,53/TCP 1h
...
Note: The service name is kube-dns for both CoreDNS and kube-dns deployments.
If you have created the Service or in the case it should be created by default but it
does not appear, see debugging Services for more information.

Are DNS endpoints exposed?

You can verify that DNS endpoints are exposed by using the kubectl get
endpoints command.

kubectl get endpoints kube-dns --namespace=kube-system


NAME ENDPOINTS AGE
kube-dns [Link]:53,[Link]:53 1h
If you do not see the endpoints, see the endpoints section in the debugging
Services documentation.

For additional Kubernetes DNS examples, see the cluster-dns examples in the
Kubernetes GitHub repository.

Are DNS queries being received/processed?

You can verify if queries are being received by CoreDNS by adding the log plugin to
the CoreDNS configuration (aka Corefile). The CoreDNS Corefile is held in
a ConfigMap named coredns. To edit it, use the command:

kubectl -n kube-system edit configmap coredns


Then add log in the Corefile section per the example below:

apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
log
errors
health
kubernetes [Link] [Link] [Link] {
pods insecure
upstream
fallthrough [Link] [Link]
}
prometheus :9153
forward . /etc/[Link]
cache 30
loop
reload
loadbalance
}
After saving the changes, it may take up to minute or two for Kubernetes to
propagate these changes to the CoreDNS pods.

Next, make some queries and view the logs per the sections above in this document.
If CoreDNS pods are receiving the queries, you should see them in the logs.

Here is an example of a query in the log:

.:53
2018/08/15 14:37:15 [INFO] CoreDNS-1.2.0
2018/08/15 14:37:15 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.0
linux/amd64, go1.10.3, 2e322f6
2018/09/07 15:29:04 [INFO] plugin/reload: Running configuration MD5 =
162475cdf272d8aa601e6fe67a6ad42f
2018/09/07 15:29:04 [INFO] Reloading complete
[Link]:41675 - [07/Sep/2018:15:29:11 +0000] 59925 "A IN
[Link]. udp 54 false 512" NOERROR qr,aa,rd,ra 106
0.000066649s

Does CoreDNS have sufficient permissions?

CoreDNS must be able to list service and endpoint related resources to properly
resolve service names.

Sample error message:

2022-03-18T07:12:15.699431183Z [INFO] [Link]:52299 - 3686 "A IN


[Link]. udp 52 false 512" SERVFAIL qr,aa,rd 145
0.000091221s
First, get the current ClusterRole of system:coredns:

kubectl describe clusterrole system:coredns -n kube-system


Expected output:

PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
nodes [] [] [get]
endpoints [] [] [list watch]
namespaces [] [] [list watch]
pods [] [] [list watch]
services [] [] [list watch]
[Link] [] [] [list watch]
If any permissions are missing, edit the ClusterRole to add them:

kubectl edit clusterrole system:coredns -n kube-system


Example insertion of EndpointSlices permissions:

...
- apiGroups:
- [Link]
resources:
- endpointslices
verbs:
- list
- watch
...

Are you in the right namespace for the service?

DNS queries that don't specify a namespace are limited to the pod's namespace.

If the namespace of the pod and service differ, the DNS query must include the
namespace of the service.

This query is limited to the pod's namespace:

kubectl exec -i -t dnsutils -- nslookup <service-name>


This query specifies the namespace:

kubectl exec -i -t dnsutils -- nslookup <service-name>.<namespace>


To learn more about name resolution, see DNS for Services and Pods.

Known issues
Some Linux distributions (e.g. Ubuntu) use a local DNS resolver by default (systemd-
resolved). Systemd-resolved moves and replaces /etc/[Link] with a stub file that
can cause a fatal forwarding loop when resolving names in upstream servers. This can
be fixed manually by using kubelet's --resolv-conf flag to point to the
correct [Link] (With systemd-resolved, this is /run/systemd/resolve/[Link]).
kubeadm automatically detects systemd-resolved, and adjusts the kubelet flags
accordingly.

Kubernetes installs do not configure the nodes' [Link] files to use the cluster DNS
by default, because that process is inherently distribution-specific. This should
probably be implemented eventually.

Linux's libc (a.k.a. glibc) has a limit for the DNS nameserver records to 3 by default and
Kubernetes needs to consume 1 nameserver record. This means that if a local
installation already uses 3 nameservers, some of those entries will be lost. To work
around this limit, the node can run dnsmasq, which will provide more nameserver entries.
You can also use kubelet's --resolv-conf flag.

If you are using Alpine version 3.3 or earlier as your base image, DNS may not work
properly due to a known issue with Alpine. Kubernetes issue 30215 details more
information on this.

Common questions

Powered by AI

If the `nslookup` command fails in a Kubernetes environment, first check the local DNS configuration by examining the contents of `/etc/resolv.conf` within the pod using `kubectl exec -ti dnsutils -- cat /etc/resolv.conf` to ensure the search path and nameserver settings are correct. Next, verify that the DNS pod is running with `kubectl get pods --namespace=kube-system -l k8s-app=kube-dns`. If necessary, check DNS pod logs using `kubectl logs --namespace=kube-system -l k8s-app=kube-dns` for any errors or unexpected messages. Further, verify the DNS service with `kubectl get svc --namespace=kube-system` and ensure DNS endpoints are correctly exposed using `kubectl get endpoints kube-dns --namespace=kube-system`. If all configurations seem correct, ensure CoreDNS has the necessary permissions, such as listing service and endpoint resources .

DNS name resolution issues in a Kubernetes cluster can arise from misconfigurations, missing CoreDNS pods, or insufficient permissions. Misconfigurations can result from incorrect setup in `/etc/resolv.conf`, identifiable by executing `kubectl exec -ti dnsutils -- cat /etc/resolv.conf`. CoreDNS pods absent or not running can be detected by executing `kubectl get pods --namespace=kube-system -l k8s-app=kube-dns`. Checking the pod logs with `kubectl logs --namespace=kube-system -l k8s-app=kube-dns` can highlight errors like 'cannot resolve'. Insufficient permissions can hinder CoreDNS from resolving service names, checkable by describing the cluster role with `kubectl describe clusterrole system:coredns -n kube-system`. Correct any missing permissions by editing the cluster role .

To ensure CoreDNS has sufficient permissions, verify CoreDNS's ClusterRole configuration using `kubectl describe clusterrole system:coredns -n kube-system`. It should have permissions to list and watch resources like services and endpoints. If any permissions are missing, modify the ClusterRole using `kubectl edit clusterrole system:coredns -n kube-system` to add necessary verbs for the required resources. Insufficient permissions would manifest as DNS query failures with error messages such as 'SERVFAIL', indicating failures in resolving service names due to an inability to access necessary resources .

In Kubernetes, a pod's namespace plays a critical role in DNS query resolution as it limits the scope of the query to the pod's namespace if unspecified. This means that if a DNS query does not include the namespace, it will only resolve services within the pod's own namespace. To resolve services in a different namespace, the query must specify the target service’s namespace like `<service-name>.<namespace>`. This specificity is essential for resolving services correctly across multiple namespaces .

To set up a testing environment for debugging DNS resolution in Kubernetes, you need an operational Kubernetes cluster with the kubectl command-line tool configured for your cluster. It’s recommended to have a cluster with at least two nodes that are not acting as control plane hosts. The cluster should run at or later than Kubernetes version v1.6 and be configured to use the CoreDNS addon or its precursor, kube-dns. You can create this cluster using tools like minikube or utilize Kubernetes playgrounds such as Killercoda or Play with Kubernetes. Additionally, a simple Pod needs to be created, often using a manifest file, to serve as the test environment .

CoreDNS functions as the DNS server within Kubernetes clusters, resolving DNS queries for services and pods. It generates an internal DNS-responsive environment so that service names can be resolved into cluster-internal IPs. CoreDNS processes queries through its configuration (Corefile), managing them via plugins and handling lookups as configured in cluster-local domains like cluster.local. It ensures applications within the cluster can smoothly communicate using DNS names instead of direct IP references .

The effectiveness of DNS resolution within a Kubernetes pod can be verified by executing the `nslookup` command in the pod's environment. Once a pod, such as 'dnsutils', is running, use `kubectl exec -i -t dnsutils -- nslookup kubernetes.default` to confirm DNS resolution. Successful output should display the DNS server and the resolved address of the Kubernetes service. If it fails, further diagnosis of local DNS configuration and the DNS pod's status using commands like `kubectl exec -ti dnsutils -- cat /etc/resolv.conf` and checking running DNS pods with `kubectl get pods --namespace=kube-system -l k8s-app=kube-dns` is essential .

The CoreDNS plugin system allows the customization of DNS behavior to fit specific needs or troubleshoot issues. Key plugins like 'log', 'reload', and 'forward' can be configured in the Corefile to log DNS queries, manage configuration changes dynamically, or forward queries to specific resolver addresses respectively. To configure these for troubleshooting, the Corefile can be edited to include 'log' for capturing DNS queries which appear in the logs. This setup aids in diagnosing and understanding query flow and potential resolution issues within the environment .

The installation of CoreDNS can be verified by checking if the CoreDNS pods are running with the command `kubectl get pods --namespace=kube-system -l k8s-app=kube-dns`. If CoreDNS is not running, it might not have been deployed by default in your environment. You may need to manually deploy it, ensuring that any configuration files are correctly applied and that it has the necessary permissions to operate, which is crucial for DNS functionality in the Kubernetes cluster. Additionally, reviewing logs can provide insights if there are any errors causing CoreDNS to fail .

To determine if CoreDNS pods are receiving and processing DNS queries, you can modify the CoreDNS configuration to include log-related information. Edit the CoreDNS Corefile through the ConfigMap by executing `kubectl -n kube-system edit configmap coredns` and inserting 'log' in the relevant section. After updating configurations and allowing time for the changes to propagate, execute DNS queries and examine the CoreDNS logs for entries showing query reception and processing. The logs should demonstrate entries related to the queries, confirming that the DNS requests are being handled by CoreDNS .

You might also like