Si usas kube-dns para el descubrimiento de servicios, es posible que se produzcan errores de conexión, como dial tcp: i/o timeout
o no such host
. Estos errores suelen indicar que hay problemas con los pods de kube-dns en el espacio de nombres kube-system
, como configuraciones incorrectas, limitaciones de recursos o problemas de conectividad de red que afectan a estos pods.
Usa esta página para diagnosticar y resolver problemas habituales específicos de la implementación de kube-dns, lo que te ayudará a asegurar una resolución de DNS fiable para tus cargas de trabajo.
Esta información es importante para los administradores y operadores de la plataforma, que son responsables de mantener los componentes principales del clúster, como kube-dns, y para los desarrolladores de aplicaciones, cuyas aplicaciones dependen de él para conectarse con otros servicios del clúster. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido, consulta Roles y tareas habituales de los usuarios de GKE. Google Cloud
Identificar la fuente de los problemas de DNS en kube-dns
En las siguientes secciones se explica cómo diagnosticar por qué kube-dns tiene problemas para resolver consultas.
Comprobar si los pods de kube-dns se están ejecutando
Los pods de Kube-DNS son fundamentales para la resolución de nombres en el clúster. Si no se están ejecutando, es probable que tengas problemas con la resolución de DNS.
Para verificar que los pods de kube-dns se están ejecutando sin reinicios recientes, consulta el estado de estos pods:
kubectl get pods -l k8s-app=kube-dns -n kube-system
El resultado debería ser similar al siguiente:
NAME READY STATUS RESTARTS AGE
kube-dns-POD_ID_1 5/5 Running 0 16d
kube-dns-POD_ID_2 0/5 Terminating 0 16d
En este resultado, POD_ID_1
y POD_ID_2
representan identificadores únicos que se añaden automáticamente a los pods de kube-dns.
Si el resultado muestra que alguno de tus pods kube-dns no tiene el estado Running
, sigue estos pasos:
Usa los registros de auditoría de actividad del administrador para investigar si se han producido cambios recientes, como actualizaciones de la versión del clúster o del grupo de nodos, o cambios en el ConfigMap de kube-dns. Para obtener más información sobre los registros de auditoría, consulta el artículo Registros de auditoría de GKE. Si detectas cambios, revierte los cambios y vuelve a consultar el estado de los pods.
Si no encuentras ningún cambio reciente relevante, investiga si se produce un error de falta de memoria en el nodo en el que se ejecuta el pod kube-dns. Si ves un error similar al siguiente en los mensajes de registro de Cloud Logging, significa que estos pods están experimentando un error de falta de memoria:
Warning: OOMKilling Memory cgroup out of memory
Este mensaje indica que Kubernetes ha terminado un proceso debido a un consumo excesivo de recursos. Kubernetes programa los pods en función de las solicitudes de recursos, pero permite que los pods consuman hasta sus límites de recursos. Si los límites son superiores a las solicitudes o no hay límites, el uso de recursos del pod puede superar los recursos del sistema.
Para resolver este error, puedes eliminar las cargas de trabajo problemáticas o definir límites de memoria o CPU. Para obtener más información sobre cómo definir límites, consulta el artículo Gestión de recursos para pods y contenedores de la documentación de Kubernetes. Para obtener más información sobre los eventos de falta de memoria, consulta Solucionar problemas de eventos de falta de memoria.
Si no encuentras ningún mensaje de error de falta de memoria, reinicia el despliegue de kube-dns:
kubectl rollout restart deployment/kube-dns --namespace=kube-system
Después de reiniciar la implementación, comprueba si tus pods kube-dns están en ejecución.
Si estos pasos no funcionan o todos tus pods kube-dns tienen el estado Running
, pero sigues teniendo problemas con el DNS, comprueba que el archivo /etc/resolv.conf
esté configurado correctamente.
Comprueba que /etc/resolv.conf
esté configurado correctamente
Revisa el archivo /etc/resolv.conf
de los pods que tienen problemas con el DNS y asegúrate de que las entradas que contiene sean correctas:
Consulta el archivo
/etc/resolv.conf
del pod:kubectl exec -it POD_NAME -- cat /etc/resolv.conf
Sustituye POD_NAME por el nombre del pod que tiene problemas con el DNS. Si hay varios pods que tienen problemas, repite los pasos de esta sección con cada uno de ellos.
Si el archivo binario del pod no admite el comando
kubectl exec
, es posible que este comando falle. Si esto ocurre, crea un Pod sencillo para usarlo como entorno de prueba. Este procedimiento te permite ejecutar un pod de prueba en el mismo espacio de nombres que el pod problemático.Comprueba que la dirección IP del servidor de nombres del archivo
/etc/resolv.conf
sea correcta:- Los pods que usen una red de host deben usar los valores del archivo
/etc/resolv.conf
del nodo. La dirección IP del servidor de nombres debe ser169.254.169.254
. En el caso de los pods que no usan una red de host, la dirección IP del servicio kube-dns debe ser la misma que la dirección IP del servidor de nombres. Para comparar las direcciones IP, sigue estos pasos:
Obtén la dirección IP del servicio kube-dns:
kubectl get svc kube-dns -n kube-system
El resultado debería ser similar al siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 192.0.2.10 <none> 53/UDP,53/TCP 64d
Anota el valor de la columna IP de clúster. En este ejemplo, es
192.0.2.10
.Compara la dirección IP del servicio kube-dns con la dirección IP del archivo
/etc/resolv.conf
:# cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local c.PROJECT_NAME google.internal nameserver 192.0.2.10 options ndots:5
En este ejemplo, los dos valores coinciden, por lo que una dirección IP de servidor de nombres incorrecta no es la causa del problema.
Sin embargo, si las direcciones IP no coinciden, significa que el campo
dnsConfig
se ha configurado en el manifiesto del pod de la aplicación.Si el valor del campo
dnsConfig.nameservers
es correcto, investiga tu servidor DNS y asegúrate de que funciona correctamente.Si no quieres usar el servidor de nombres personalizado, elimina el campo y realiza un reinicio gradual del pod:
kubectl rollout restart deployment POD_NAME
Sustituye
POD_NAME
por el nombre de tu pod.
- Los pods que usen una red de host deben usar los valores del archivo
Verifica las entradas de
search
yndots
en/etc/resolv.conf
. Asegúrate de que no haya errores ortográficos ni configuraciones obsoletas y de que la solicitud fallida apunte a un servicio que exista en el espacio de nombres correcto.
Realizar una petición de DNS
Una vez que hayas confirmado que /etc/resolv.conf
está configurado correctamente y que el registro DNS es correcto, usa la herramienta de línea de comandos dig para realizar búsquedas de DNS desde el pod que informa de errores de DNS:
Consulta directamente un pod abriendo un shell en él:
kubectl exec -it POD_NAME -n NAMESPACE_NAME -- SHELL_NAME
Haz los cambios siguientes:
POD_NAME
: nombre del pod que informa de errores de DNS.NAMESPACE_NAME
: el espacio de nombres al que pertenece el pod.SHELL_NAME
: el nombre del shell que quieras abrir. Por ejemplo,sh
o/bin/bash
.
Es posible que este comando falle si tu pod no permite el comando
kubectl exec
o si el pod no tiene el archivo binario dig. Si esto ocurre, crea un Pod de prueba con una imagen que tenga instalado dig:kubectl run "test-$RANDOM" ti --restart=Never --image=thockin/dnsutils - bash
Comprueba si el pod puede resolver correctamente el servicio DNS interno del clúster:
dig kubernetes
Como el archivo
/etc/resolv.conf
apunta a la dirección IP del servicio kube-dns, cuando ejecutas este comando, el servidor DNS es el servicio kube-dns.Deberías ver una respuesta DNS correcta con la dirección IP del servicio de la API de Kubernetes (a menudo, algo parecido a
10.96.0.1
). Si vesSERVFAIL
o no recibes ninguna respuesta, suele significar que el pod kube-dns no puede resolver los nombres de servicio internos.Comprueba si el servicio kube-dns puede resolver un nombre de dominio externo:
dig example.com
Si tienes problemas con un pod de kube-dns concreto que responde a consultas de DNS, comprueba si ese pod puede resolver un nombre de dominio externo:
dig example.com @KUBE_DNS_POD_IP
Sustituye
KUBE_DNS_POD_IP
por la dirección IP del pod kube-dns. Si no sabes el valor de esta dirección IP, ejecuta el siguiente comando:kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
La dirección IP se encuentra en la columna
IP
.Si la resolución del comando se realiza correctamente, verás
status: NOERROR
y los detalles del registro A, como se muestra en el siguiente ejemplo:; <<>> DiG 9.16.27 <<>> example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31256 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 30 IN A 93.184.215.14 ;; Query time: 6 msec ;; SERVER: 10.76.0.10#53(10.76.0.10) ;; WHEN: Tue Oct 15 16:45:26 UTC 2024 ;; MSG SIZE rcvd: 56
Salir del shell:
exit
Si falla alguno de estos comandos, realiza un reinicio gradual de la implementación de kube-dns:
kubectl rollout restart deployment/kube-dns --namespace=kube-system
Una vez que hayas completado el reinicio, vuelve a probar los comandos dig y comprueba si ahora funcionan. Si siguen fallando, haz una captura de paquetes.
Hacer una captura de paquetes
Haz una captura de paquetes para verificar si los pods de kube-dns reciben las consultas de DNS y responden a ellas correctamente:
Conéctate mediante SSH al nodo que ejecuta el pod kube-dns. Por ejemplo:
En la consola de Google Cloud , ve a la página Instancias de VM.
Busca el nodo al que quieras conectarte. Si no sabes el nombre del nodo de tu pod kube-dns, ejecuta el siguiente comando:
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
El nombre del nodo aparece en la columna Nodo.
En la columna Conectar, haz clic en SSH.
En el terminal, inicia toolbox, una herramienta de depuración preinstalada:
toolbox
En la petición de raíz, instala el paquete
tcpdump
:apt update -y && apt install -y tcpdump
Con
tcpdump
, haz una captura de paquetes de tu tráfico DNS:tcpdump -i eth0 port 53" -w FILE_LOCATION
Sustituye
FILE_LOCATION
por la ruta a la ubicación donde quieras guardar la captura.Revisa la captura de paquetes. Comprueba si hay paquetes con direcciones IP de destino que coincidan con la dirección IP del servicio kube-dns. De esta forma, se asegura de que las solicitudes de DNS lleguen al destino correcto para la resolución. Si no ves que el tráfico DNS llega a los pods correctos, puede que haya una política de red que esté bloqueando las solicitudes.
Comprobar si hay una política de red
En ocasiones, las políticas de red restrictivas pueden interrumpir el tráfico DNS. Para comprobar si existe una política de red en el espacio de nombres kube-system, ejecuta el siguiente comando:
kubectl get networkpolicy -n kube-system
Si encuentras una política de red, revísala y asegúrate de que permita la comunicación DNS necesaria. Por ejemplo, si tienes una política de red que bloquea todo el tráfico de salida, la política también bloqueará las solicitudes DNS.
Si el resultado es No resources found in kube-system namespace
, significa que no tienes ninguna política de red y puedes descartar que sea la causa del problema. Investigar los registros puede ayudarte a encontrar más puntos de fallo.
Habilitar el registro temporal de consultas DNS
Para ayudarle a identificar problemas como respuestas de DNS incorrectas, habilite temporalmente el registro de depuración de las consultas de DNS. Para habilitar las consultas, crea un pod basado en un pod kube-dns. Los cambios que se hagan en el despliegue de kube-dns se revertirán automáticamente.
Habilitar el registro temporal de consultas de DNS es un procedimiento que requiere muchos recursos, por lo que te recomendamos que elimines el pod que crees en cuanto hayas recogido una muestra de registros adecuada.
Para habilitar el registro temporal de consultas DNS, sigue estos pasos:
Recupera un pod de kube-dns y almacénalo en una variable llamada
POD
:POD=$(kubectl -n kube-system get pods --selector=k8s-app=kube-dns -o jsonpath="{.items[0].metadata.name}")
Crea un Pod llamado
kube-dns-debug
. Este pod es una copia del pod almacenado en la variablePOD
, pero con el registro de dnsmasq habilitado. Este comando no modifica el pod kube-dns original:kubectl apply -f <(kubectl get pod -n kube-system ${POD} -o json | jq -e ' ( (.spec.containers[] | select(.name == "dnsmasq") | .args) += ["--log-queries"] ) | (.metadata.name = "kube-dns-debug") | (del(.metadata.labels."pod-template-hash")) ')
Inspecciona los registros:
kubectl logs -f --tail 100 -c dnsmasq -n kube-system kube-dns-debug
También puede ver las consultas en Cloud Logging.
Cuando hayas terminado de ver los registros de consultas de DNS, elimina el
kube-dns-debug
Pod:kubectl -n kube-system delete pod kube-dns-debug
Investigar el pod kube-dns
Consulta cómo reciben y resuelven las consultas DNS los pods de kube-dns con Cloud Logging.
Para ver las entradas de registro relacionadas con el pod kube-dns, sigue estos pasos:
En la Google Cloud consola, ve a la página Explorador de registros.
En el panel de consultas, introduce el siguiente filtro para ver los eventos relacionados con el contenedor kube-dns:
resource.type="k8s_container" resource.labels.namespace_name="kube-system" resource.labels.pod_name:"kube-dns" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="CLUSTER_LOCATION"
Haz los cambios siguientes:
CLUSTER_NAME
: el nombre del clúster al que pertenece el pod kube-dns.CLUSTER_LOCATION
: la ubicación de tu clúster.
Haz clic en Realizar una consulta.
Revisa el resultado. En el siguiente ejemplo se muestra un posible error que puede aparecer:
{ "timestamp": "2024-10-10T15:32:16.789Z", "severity": "ERROR", "resource": { "type": "k8s_container", "labels": { "namespace_name": "kube-system", "pod_name": "kube-dns", "cluster_name": "CLUSTER_NAME", "location": "CLUSTER_LOCATION" } }, "message": "Failed to resolve 'example.com': Timeout." },
En este ejemplo, kube-dns no ha podido resolver
example.com
en un tiempo razonable. Este tipo de error puede deberse a varios problemas. Por ejemplo, el servidor upstream podría estar configurado incorrectamente en el ConfigMap de kube-dns o podría haber un tráfico de red elevado.
Si no tienes habilitado Cloud Logging, consulta los registros de Kubernetes:
Pod=$(kubectl get Pods -n kube-system -l k8s-app=kube-dns -o name | head -n1)
kubectl logs -n kube-system $Pod -c dnsmasq
kubectl logs -n kube-system $Pod -c kubedns
kubectl logs -n kube-system $Pod -c sidecar
Investigar los cambios recientes en el ConfigMap kube-dns
Si de repente se producen errores de resolución de DNS en tu clúster, una de las causas puede ser un cambio de configuración incorrecto en el ConfigMap de kube-dns. En concreto, los cambios en la configuración de los dominios stub y las definiciones de los servidores upstream pueden provocar problemas.
Para comprobar si hay actualizaciones de la configuración del dominio de stub, sigue estos pasos:
En la Google Cloud consola, ve a la página Explorador de registros.
En el panel de consultas, introduce la siguiente consulta:
resource.labels.cluster_name="clouddns" resource.type="k8s_container" resource.labels.namespace_name="kube-system" labels.k8s-pod/k8s-app="kube-dns" jsonPayload.message=~"Updated stubDomains to"
Haz clic en Realizar una consulta.
Revisa el resultado. Si ha habido alguna actualización, el resultado será similar al siguiente:
Updated stubDomains to map[example.com: [8.8.8.8 8.8.4.4 1.1.3.3 1.0.8.111]]
Si ves una actualización, despliega el resultado para obtener más información sobre los cambios. Verifica que los dominios de stub y sus servidores DNS upstream correspondientes se hayan definido correctamente. Si las entradas son incorrectas, se pueden producir errores de resolución en esos dominios.
Para comprobar si se han producido cambios en el servidor upstream, sigue estos pasos:
En la Google Cloud consola, ve a la página Explorador de registros.
En el panel de consultas, introduce la siguiente consulta:
resource.labels.cluster_name="clouddns" resource.type="k8s_container" resource.labels.namespace_name="kube-system" labels.k8s-pod/k8s-app="kube-dns" jsonPayload.message=~"Updated upstreamNameservers to"
Haz clic en Realizar una consulta.
Revisa el resultado. Si se ha producido algún cambio, el resultado será similar al siguiente:
Updated upstreamNameservers to [8.8.8.8]
Despliega el resultado para obtener más información sobre los cambios. Verifica que la lista de servidores DNS ascendentes sea precisa y que se pueda acceder a estos servidores desde tu clúster. Si estos servidores no están disponibles o están mal configurados, es posible que falle la resolución general de DNS.
Si has comprobado si hay cambios en los dominios stub y los servidores upstream, pero no has encontrado ningún resultado, busca todos los cambios con el siguiente filtro:
resource.type="k8s_cluster"
protoPayload.resourceName:"namespaces/kube-system/configmaps/kube-dns"
protoPayload.methodName=~"io.k8s.core.v1.configmaps."
Revisa los cambios que se hayan hecho para ver si han provocado el error.
Contactar con Cloud Customer Care
Si has seguido los pasos de las secciones anteriores, pero sigues sin poder diagnosticar la causa del problema, ponte en contacto con el servicio de atención al cliente de Cloud.
Resolver los problemas más habituales
Si has experimentado un error o un problema específico, sigue los consejos que se indican en las secciones siguientes.
Problema: tiempos de espera de DNS intermitentes
Si observas que se agota el tiempo de espera de la resolución de DNS de forma intermitente cuando aumenta el tráfico de DNS o cuando empieza el horario de apertura, prueba las siguientes soluciones para optimizar el rendimiento de DNS:
Comprueba el número de pods de kube-dns que se ejecutan en el clúster y compáralo con el número total de nodos de GKE. Si no hay suficientes recursos, te recomendamos que aumentes la escala de los pods de kube-dns.
Para mejorar el tiempo medio de búsqueda de DNS, habilita NodeLocal DNS Cache.
La resolución de DNS a nombres externos puede sobrecargar el pod kube-dns. Para reducir el número de consultas, ajusta el ajuste
ndots
en el archivo/etc/resolv.conf
.ndots
representa el número de puntos que deben aparecer en un nombre de dominio para resolver una consulta antes de la consulta absoluta inicial.El siguiente ejemplo es el archivo
/etc/resolv.conf
de un pod de aplicación:search default.svc.cluster.local svc.cluster.local cluster.local c.PROJECT_ID.internal google.internal nameserver 10.52.16.10 options ndots:5
En este ejemplo, kube-dns busca cinco puntos en el dominio consultado. Si el pod hace una llamada de resolución de DNS para
example.com
, los registros serán similares al siguiente ejemplo:"A IN example.com.default.svc.cluster.local." NXDOMAIN "A IN example.com.svc.cluster.local." NXDOMAIN "A IN example.com.cluster.local." NXDOMAIN "A IN example.com.google.internal." NXDOMAIN "A IN example.com.c.PROJECT_ID.internal." NXDOMAIN "A IN example.com." NOERROR
Para solucionar este problema, cambie el valor de ndots a
1
para buscar solo un punto o añada un punto (.
) al final del dominio que consulte o utilice. Por ejemplo:dig example.com.
Problema: las consultas de DNS fallan de forma intermitente desde algunos nodos
Si observas que las consultas de DNS fallan de forma intermitente desde algunos nodos, es posible que se produzcan los siguientes síntomas:
- Cuando ejecutas comandos dig en la dirección IP del servicio kube-dns o en la dirección IP del pod, las consultas de DNS fallan de forma intermitente con tiempos de espera.
- No se pueden ejecutar comandos dig desde un pod en el mismo nodo que el pod kube-dns.
Para solucionar este problema, siga estos pasos:
- Realiza una prueba de conectividad. Define el pod o el nodo problemático como origen y la dirección IP del pod kube-dns como destino. De esta forma, puedes comprobar si tienes las reglas de cortafuegos necesarias para permitir este tráfico.
Si la prueba no se realiza correctamente y una regla de cortafuegos bloquea el tráfico, usa Cloud Logging para consultar los cambios manuales que se hayan hecho en las reglas de cortafuegos. Busca los cambios que bloquean un tipo de tráfico específico:
En la Google Cloud consola, ve a la página Explorador de registros.
En el panel de consultas, introduce la siguiente consulta:
logName="projects/project-name/logs/cloudaudit.googleapis.com/activity" resource.type="gce_firewall_rule"
Haz clic en Realizar una consulta. Usa el resultado de la consulta para determinar si se ha realizado algún cambio. Si detecta algún error, corríjalo y vuelva a aplicar la regla de firewall.
Asegúrate de no hacer cambios en ninguna regla de cortafuegos automatizada.
Si no se ha realizado ningún cambio en las reglas de cortafuegos, comprueba la versión del grupo de nodos y asegúrate de que sea compatible con el plano de control y otros grupos de nodos que funcionen. Si alguno de los grupos de nodos del clúster tiene una versión anterior a la del plano de control en más de dos versiones secundarias, puede que esto esté causando problemas. Para obtener más información sobre esta incompatibilidad, consulta La versión de Node no es compatible con la versión del plano de control.
Para determinar si las solicitudes se envían a la IP de servicio kube-dns correcta, captura el tráfico de red en el nodo problemático y filtra por el puerto 53 (tráfico DNS). Captura el tráfico de los pods de kube-dns para ver si las solicitudes llegan a los pods previstos y si se resuelven correctamente.
Siguientes pasos
Para obtener información general sobre cómo diagnosticar problemas de DNS de Kubernetes, consulta Depuración de la resolución de DNS.
Si no encuentras una solución a tu problema en la documentación, consulta la sección Obtener asistencia para obtener más ayuda, incluidos consejos sobre los siguientes temas:
- Abrir un caso de asistencia poniéndose en contacto con el equipo de Atención al Cliente de Cloud.
- Obtener asistencia de la comunidad haciendo preguntas en Stack Overflow
y usando la etiqueta
google-kubernetes-engine
para buscar problemas similares. También puedes unirte al#kubernetes-engine
canal de Slack para obtener más ayuda de la comunidad. - Abrir errores o solicitudes de funciones mediante el seguimiento de problemas público.