Diagnose Service DNS Access

KubernetesBeginner
Practice Now

Introduction

The previous lab showed how a Service gives Pods a stable in-cluster entry point. Kubernetes also gives each Service a DNS name. A Pod in the same namespace can usually use the short Service name, but a Pod in a different namespace often needs a longer name that includes the Service namespace.

In this lab, you will create a web Service, test same-namespace DNS access, reproduce a cross-namespace short-name failure, fix the request with the Service FQDN, and inspect the objects that help you diagnose whether a DNS problem is really a Service, endpoint, or CoreDNS problem.

Prepare a Web Service

In this step, you will create the target Service that later DNS tests will resolve. The workload is intentionally simple because the main topic is DNS naming, not application deployment.

Start in /home/labex/project:

mkdir -p /home/labex/project
cd /home/labex/project

Check that the Kubernetes API server is reachable. If the VM has just started and the node is not ready yet, wait a few seconds and run the command again.

kubectl get nodes --request-timeout=5s

Expected output includes:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Wait until cluster networking is Ready. This lab sends traffic between Pods, so Pod networking must be healthy before DNS access tests are meaningful.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Expected output:

pod/calico-node-... condition met

Create a namespace named ckad-prep-dns and set it as the current namespace:

kubectl create namespace ckad-prep-dns
kubectl config set-context --current --namespace=ckad-prep-dns

Create a Deployment and expose it with a Service named dns-web:

kubectl create deployment dns-web --image=nginx:1.25 --port=80
kubectl expose deployment dns-web --port=80 --target-port=80

Wait for the web Pod to become available:

kubectl rollout status deployment/dns-web --timeout=120s

Inspect the Service and its EndpointSlice. The Service is the stable DNS target; the EndpointSlice shows the current backend Pod addresses selected by the Service.

kubectl get service dns-web
kubectl get endpointslice -l kubernetes.io/service-name=dns-web

Expected output includes:

NAME      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
dns-web   ClusterIP   ...          <none>        80/TCP    ...

NAME          ADDRESSTYPE   PORTS   ENDPOINTS   AGE
dns-web-...   IPv4          80      ...         ...

Resolve the Service from the Same Namespace

In this step, you will create a client Pod in the same namespace as the Service and use the short Service name. This is the simplest Service DNS case.

Create a client Pod that stays running:

kubectl run same-ns-client --image=busybox:1.36 --restart=Never --command -- sleep 3600

Wait for the client Pod to be Ready:

kubectl wait --for=condition=Ready pod/same-ns-client --timeout=120s

Expected output:

pod/same-ns-client condition met

Use nslookup inside the client Pod to resolve the short Service name dns-web. The short name works here because the client Pod and Service are in the same namespace. BusyBox nslookup may still print extra NXDOMAIN lines for other search suffixes and return a nonzero exit code after showing the correct address, so the command uses || true and you should read the Name and Address lines.

kubectl exec same-ns-client -- sh -c 'nslookup dns-web || true'

Expected output includes:

Name:      dns-web.ckad-prep-dns.svc.cluster.local
Address: ...

Now send an HTTP request to the Service short name:

kubectl exec same-ns-client -- wget -qO- http://dns-web | grep '<title>Welcome to nginx'

Expected output:

<title>Welcome to nginx!</title>

Diagnose a Cross-Namespace Short Name Failure

In this step, you will create a client Pod in a different namespace and reproduce a common DNS mistake. A short Service name is resolved relative to the client Pod's namespace first, so dns-web will not find the Service in ckad-prep-dns when the client runs in another namespace.

Create a second namespace and a client Pod there:

kubectl create namespace ckad-prep-dns-client
kubectl run remote-client --namespace ckad-prep-dns-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --namespace ckad-prep-dns-client --for=condition=Ready pod/remote-client --timeout=120s

Expected output includes:

namespace/ckad-prep-dns-client created
pod/remote-client created
pod/remote-client condition met

Try to resolve the short name from the remote namespace. The || true keeps the lab moving because this failure is expected.

kubectl exec --namespace ckad-prep-dns-client remote-client -- nslookup dns-web || true

Expected output includes a failure such as:

** server can't find dns-web...

Now resolve the fully qualified Service name. The full pattern is <service>.<namespace>.svc.cluster.local.

kubectl exec --namespace ckad-prep-dns-client remote-client -- nslookup dns-web.ckad-prep-dns.svc.cluster.local

Expected output includes:

Name:      dns-web.ckad-prep-dns.svc.cluster.local
Address 1: ...

Use the same fully qualified name for HTTP access:

kubectl exec --namespace ckad-prep-dns-client remote-client -- wget -qO- http://dns-web.ckad-prep-dns.svc.cluster.local | grep '<title>Welcome to nginx'

Expected output:

<title>Welcome to nginx!</title>

Check the DNS Troubleshooting Path

In this step, you will inspect the objects that help separate a DNS naming problem from a Service or backend problem. A practical troubleshooting order is: confirm the Service name and namespace, confirm it has endpoints, then confirm CoreDNS is available.

First, inspect the Service in its actual namespace:

kubectl get service dns-web --namespace ckad-prep-dns

Expected output includes:

NAME      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
dns-web   ClusterIP   ...          <none>        80/TCP    ...

Next, inspect the EndpointSlice. If DNS resolves but HTTP traffic fails, missing endpoints are a common reason.

kubectl get endpointslice --namespace ckad-prep-dns -l kubernetes.io/service-name=dns-web

Expected output includes at least one endpoint:

NAME          ADDRESSTYPE   PORTS   ENDPOINTS   AGE
dns-web-...   IPv4          80      ...         ...

Check the CoreDNS Pods. CoreDNS is the cluster DNS service that answers Pod DNS queries.

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

Expected output includes Running CoreDNS Pods:

NAME                       READY   STATUS    RESTARTS   AGE
coredns-...                1/1     Running   ...        ...

Finally, inspect the DNS search configuration from the remote client. The search line explains why the short name dns-web was searched in the client namespace before you used the full name.

kubectl exec --namespace ckad-prep-dns-client remote-client -- cat /etc/resolv.conf

Expected output includes a search path similar to:

search ckad-prep-dns-client.svc.cluster.local svc.cluster.local cluster.local
nameserver ...

Summary

You practiced diagnosing Kubernetes Service DNS access in a beginner-friendly sequence. You created a Service, confirmed that a same-namespace client can use the short Service name, reproduced a cross-namespace short-name failure, fixed it with the full Service DNS name, and inspected the Service, EndpointSlice, CoreDNS Pods, and client DNS search path to understand where DNS access problems come from.