Este documento ha sido traducido utilizando tecnología de traducción automática. Si bien nos esforzamos por proporcionar traducciones precisas, no ofrecemos garantías sobre la integridad, precisión o confiabilidad del contenido traducido. En caso de discrepancia, la versión original en inglés prevalecerá y constituirá el texto autorizado.

DNS

Los comandos/pasos listados en esta página se pueden utilizar para comprobar problemas de resolución de nombres en tu clúster.

Asegúrate de haber configurado el kubeconfig correcto (por ejemplo, export KUBECONFIG=$PWD/kube_config_cluster.yml para Rancher HA) o de estar utilizando el kubectl integrado a través de la interfaz de usuario.

Antes de ejecutar las comprobaciones de DNS, asegúrate de que la red superpuesta está funcionando correctamente para tu proveedor de DNS, ya que esto también puede ser la razón por la que la resolución de DNS falla (parcialmente).

Verifica si los pods de DNS están en ejecución

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

Ejemplo de salida al usar CoreDNS:

NAME                       READY   STATUS    RESTARTS   AGE
coredns-799dffd9c4-6jhlz   1/1     Running   0          76m

Ejemplo de salida al usar kube-dns:

NAME                        READY   STATUS    RESTARTS   AGE
kube-dns-5fd74c7488-h6f7n   3/3     Running   0          4m13s

Verifica si el servicio de DNS está presente con la cluster-ip correcta

kubectl -n kube-system get svc -l k8s-app=kube-dns
NAME               TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
service/kube-dns   ClusterIP   10.43.0.10   <none>        53/UDP,53/TCP   4m13s

Verifica si los nombres de dominio se están resolviendo

Verifica si los nombres internos del clúster se están resolviendo (en este ejemplo, kubernetes.default), la IP mostrada después de Server: debería ser la misma que la CLUSTER-IP del servicio kube-dns.

kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- nslookup kubernetes.default

Resultado de ejemplo:

Server:    10.43.0.10
Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes.default
Address 1: 10.43.0.1 kubernetes.default.svc.cluster.local
pod "busybox" deleted

Verifica si los nombres externos se están resolviendo (en este ejemplo, www.google.com)

kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- nslookup www.google.com

Resultado de ejemplo:

Server:    10.43.0.10
Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local

Name:      www.google.com
Address 1: 2a00:1450:4009:80b::2004 lhr35s04-in-x04.1e100.net
Address 2: 216.58.211.100 ams15s32-in-f4.1e100.net
pod "busybox" deleted

Si deseas comprobar la resolución de nombres de dominio en todos los hosts, ejecuta los siguientes pasos:

  1. Guarda el siguiente archivo como ds-dnstest.yml

     apiVersion: apps/v1
     kind: DaemonSet
     metadata:
       name: dnstest
     spec:
       selector:
           matchLabels:
             name: dnstest
       template:
         metadata:
           labels:
             name: dnstest
         spec:
           tolerations:
           - operator: Exists
           containers:
           - image: busybox:1.28
             imagePullPolicy: Always
             name: alpine
             command: ["sleep", "infinity"]
             terminationMessagePath: /dev/termination-log
  2. Inícialo usando kubectl create -f ds-dnstest.yml

  3. Espera hasta que kubectl rollout status ds/dnstest -w devuelva: daemon set "dnstest" successfully rolled out.

  4. Configura la variable de entorno DOMAIN a un nombre de dominio completo (FQDN) que el host debería poder resolver (www.google.com se utiliza como ejemplo) y ejecuta el siguiente comando para permitir que cada contenedor en cada host resuelva el nombre de dominio configurado (es un comando de una sola línea).

     export DOMAIN=www.google.com; echo "=> Start DNS resolve test"; kubectl get pods -l name=dnstest --no-headers -o custom-columns=NAME:.metadata.name,HOSTIP:.status.hostIP | while read pod host; do kubectl exec $pod -- /bin/sh -c "nslookup $DOMAIN > /dev/null 2>&1"; RC=$?; if [ $RC -ne 0 ]; then echo $host cannot resolve $DOMAIN; fi; done; echo "=> End DNS resolve test"
  5. Cuando este comando haya terminado de ejecutarse, la salida que indica que todo es correcto es:

     => Start DNS resolve test
     => End DNS resolve test

Si ves un error en la salida, significa que el/los host(s) mencionado(s) no pueden resolver el FQDN dado.

Ejemplo de salida de error de una situación donde el host con IP 209.97.182.150 tenía los puertos UDP bloqueados.

=> Start DNS resolve test
command terminated with exit code 1
209.97.182.150 cannot resolve www.google.com
=> End DNS resolve test

Limpia el DaemonSet alpine ejecutando kubectl delete ds/dnstest.

Específico de CoreDNS

Verifica el registro de CoreDNS

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

Verifica la configuración

La configuración de CoreDNS se almacena en el configmap coredns en el espacio de nombres kube-system.

kubectl -n kube-system get configmap coredns -o go-template={{.data.Corefile}}

Verifica los servidores de nombres en sentido ascendente en resolv.conf

Por defecto, los servidores de nombres configurados en el host (en /etc/resolv.conf) se utilizarán como servidores de nombres en sentido ascendente para CoreDNS. Puedes verificar este archivo en el host o ejecutar el siguiente Pod con dnsPolicy configurado en Default, que heredará el /etc/resolv.conf del host en el que se está ejecutando.

kubectl run -i --restart=Never --rm test-${RANDOM} --image=ubuntu --overrides='{"kind":"Pod", "apiVersion":"v1", "spec": {"dnsPolicy":"Default"}}' -- sh -c 'cat /etc/resolv.conf'

Habilitar el registro de consultas

La habilitación del registro de consultas se puede realizar activando el complemento de log en la configuración del Corefile en el configmap coredns. Puedes hacerlo utilizando kubectl -n kube-system edit configmap coredns o usar el comando a continuación para reemplazar la configuración en su lugar:

kubectl get configmap -n kube-system coredns -o json | sed -e 's_loadbalance_log\\n    loadbalance_g' | kubectl apply -f -

Todas las consultas ahora se registrarán y se podrán verificar utilizando el comando en Verifica el registro de CoreDNS.

Específico de kube-dns

Verifica los servidores de nombres en sentido ascendente en el contenedor de kubedns

Por defecto, los servidores de nombres configurados en el host (en /etc/resolv.conf) se utilizarán como servidores de nombres en sentido ascendente para kube-dns. A veces, el host ejecutará un servidor de nombres DNS de caché local, lo que significa que la dirección en /etc/resolv.conf apuntará a una dirección en el rango de retrobucle (127.0.0.0/8), que será inalcanzable por el contenedor. En el caso de Ubuntu 18.04, esto se hace mediante systemd-resolved. Detectamos si systemd-resolved está en ejecución y utilizaremos automáticamente el archivo /etc/resolv.conf con los nombres de servidores en sentido ascendente correctos (que se encuentra en /run/systemd/resolve/resolv.conf).

Utiliza el siguiente comando para comprobar los servidores de nombres en sentido ascendente utilizados por el contenedor kubedns:

kubectl -n kube-system get pods -l k8s-app=kube-dns --no-headers -o custom-columns=NAME:.metadata.name,HOSTIP:.status.hostIP | while read pod host; do echo "Pod ${pod} on host ${host}"; kubectl -n kube-system exec $pod -c kubedns cat /etc/resolv.conf; done

Resultado de ejemplo:

Pod kube-dns-667c7cb9dd-z4dsf on host x.x.x.x
nameserver 1.1.1.1
nameserver 8.8.4.4

Si la salida muestra una dirección en el rango de retrobucle (127.0.0.0/8), puedes corregir esto de dos maneras:

  • Asegúrate de que los servidores de nombres correctos estén listados en /etc/resolv.conf en tus nodos del clúster; consulta la documentación de tu sistema operativo sobre cómo hacerlo. Asegúrate de ejecutar esto antes de aprovisionar un clúster o reinicia los nodos después de realizar la modificación.

  • Configura el kubelet para utilizar un archivo diferente para resolver nombres, utilizando extra_args como se muestra a continuación (donde /run/resolvconf/resolv.conf es el archivo con los servidores de nombres correctos):

services:
  kubelet:
    extra_args:
      resolv-conf: "/run/resolvconf/resolv.conf"

Como el kubelet se está ejecutando dentro de un contenedor, las rutas para los archivos ubicados en /etc y /usr están en /host/etc y /host/usr dentro del contenedor kubelet.

Consulta la sección Editar Clúster como YAML para saber cómo aplicar este cambio. Cuando el aprovisionamiento del clúster haya terminado, debes eliminar el pod kube-dns para activar la nueva configuración en el pod:

kubectl delete pods -n kube-system -l k8s-app=kube-dns
pod "kube-dns-5fd74c7488-6pwsf" deleted

Intenta resolver el nombre de nuevo utilizando Verifica si los nombres de dominio se están resolviendo.

Si deseas comprobar la configuración de kube-dns en tu clúster (por ejemplo, para verificar si hay diferentes servidores de nombres en sentido ascendente configurados), puedes ejecutar el siguiente comando para listar la configuración de kube-dns:

kubectl -n kube-system get configmap kube-dns -o go-template='{{range $key, $value := .data}}{{ $key }}{{":"}}{{ $value }}{{"\n"}}{{end}}'

Resultado de ejemplo:

upstreamNameservers:["1.1.1.1"]