Diagnosticar el acceso DNS a un Servicio

KubernetesBeginner
Practicar Ahora

Introducción

En el laboratorio anterior vimos cómo un Servicio proporciona a los Pods un punto de entrada estable dentro del clúster. Kubernetes también asigna a cada Servicio un nombre DNS. Un Pod en el mismo espacio de nombres (namespace) generalmente puede usar el nombre corto del Servicio, pero un Pod en un espacio de nombres diferente a menudo necesita un nombre más largo que incluya el espacio de nombres del Servicio.

En este laboratorio, crearás un Servicio web, probarás el acceso DNS dentro del mismo espacio de nombres, reproducirás un fallo al intentar usar un nombre corto entre espacios de nombres, corregirás la solicitud utilizando el FQDN (nombre de dominio totalmente cualificado) del Servicio e inspeccionarás los objetos que te ayudarán a diagnosticar si un problema de DNS se debe realmente al Servicio, a los endpoints o a CoreDNS.

Preparar un Servicio web

En este paso, crearás el Servicio objetivo que las pruebas de DNS resolverán más adelante. La carga de trabajo es intencionalmente sencilla, ya que el tema principal es la nomenclatura DNS y no el despliegue de aplicaciones.

Comienza en /home/labex/project:

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

Verifica que el servidor de la API de Kubernetes sea accesible. Si la máquina virtual acaba de iniciarse y el nodo aún no está listo, espera unos segundos y vuelve a ejecutar el comando.

kubectl get nodes --request-timeout=5s

La salida esperada incluye:

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

Espera hasta que la red del clúster esté lista. Este laboratorio envía tráfico entre Pods, por lo que la red de los Pods debe estar operativa antes de que las pruebas de acceso DNS sean significativas.

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

Salida esperada:

pod/calico-node-... condition met

Crea un espacio de nombres llamado ckad-prep-dns y establécelo como el espacio de nombres actual:

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

Crea un Deployment y exponlo con un Servicio llamado dns-web:

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

Espera a que el Pod web esté disponible:

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

Inspecciona el Servicio y su EndpointSlice. El Servicio es el destino DNS estable; el EndpointSlice muestra las direcciones actuales de los Pods backend seleccionados por el Servicio.

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

La salida esperada incluye:

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

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

Resolver el Servicio desde el mismo espacio de nombres

En este paso, crearás un Pod cliente en el mismo espacio de nombres que el Servicio y utilizarás el nombre corto del Servicio. Este es el caso más sencillo de DNS en un Servicio.

Crea un Pod cliente que se mantenga en ejecución:

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

Espera a que el Pod cliente esté listo:

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

Salida esperada:

pod/same-ns-client condition met

Usa nslookup dentro del Pod cliente para resolver el nombre corto del Servicio dns-web. El nombre corto funciona aquí porque el Pod cliente y el Servicio están en el mismo espacio de nombres. El nslookup de BusyBox puede imprimir líneas NXDOMAIN adicionales para otros sufijos de búsqueda y devolver un código de salida distinto de cero después de mostrar la dirección correcta, por lo que el comando utiliza || true y debes fijarte en las líneas Name y Address.

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

La salida esperada incluye:

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

Ahora envía una solicitud HTTP al nombre corto del Servicio:

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

Salida esperada:

<title>Welcome to nginx!</title>

Diagnosticar un fallo de nombre corto entre espacios de nombres

En este paso, crearás un Pod cliente en un espacio de nombres diferente y reproducirás un error común de DNS. Un nombre corto de Servicio se resuelve primero en relación con el espacio de nombres del Pod cliente, por lo que dns-web no encontrará el Servicio en ckad-prep-dns cuando el cliente se ejecute en otro espacio de nombres.

Crea un segundo espacio de nombres y un Pod cliente allí:

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

La salida esperada incluye:

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

Intenta resolver el nombre corto desde el espacio de nombres remoto. El || true permite que el laboratorio continúe, ya que este fallo es esperado.

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

La salida esperada incluye un fallo como:

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

Ahora resuelve el nombre del Servicio totalmente cualificado (FQDN). El patrón completo es <service>.<namespace>.svc.cluster.local.

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

La salida esperada incluye:

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

Usa el mismo nombre totalmente cualificado para el acceso HTTP:

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'

Salida esperada:

<title>Welcome to nginx!</title>

Comprobar la ruta de resolución de problemas de DNS

En este paso, inspeccionarás los objetos que ayudan a distinguir un problema de nomenclatura DNS de un problema del Servicio o del backend. Un orden práctico para la resolución de problemas es: confirmar el nombre y el espacio de nombres del Servicio, confirmar que tiene endpoints y, finalmente, confirmar que CoreDNS está disponible.

Primero, inspecciona el Servicio en su espacio de nombres real:

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

La salida esperada incluye:

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

A continuación, inspecciona el EndpointSlice. Si el DNS se resuelve pero el tráfico HTTP falla, la falta de endpoints es una causa común.

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

La salida esperada incluye al menos un endpoint:

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

Comprueba los Pods de CoreDNS. CoreDNS es el servicio DNS del clúster que responde a las consultas DNS de los Pods.

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

La salida esperada incluye los Pods de CoreDNS en estado Running:

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

Finalmente, inspecciona la configuración de búsqueda DNS desde el cliente remoto. La línea search explica por qué se buscó el nombre corto dns-web en el espacio de nombres del cliente antes de usar el nombre completo.

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

La salida esperada incluye una ruta de búsqueda similar a:

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

Resumen

Has practicado el diagnóstico del acceso DNS a Servicios de Kubernetes siguiendo una secuencia sencilla para principiantes. Creaste un Servicio, confirmaste que un cliente en el mismo espacio de nombres puede usar el nombre corto del Servicio, reproduciste un fallo de nombre corto entre espacios de nombres, lo corregiste con el nombre DNS completo del Servicio e inspeccionaste el Servicio, el EndpointSlice, los Pods de CoreDNS y la ruta de búsqueda DNS del cliente para comprender el origen de los problemas de acceso DNS.