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. Cloud de Confiance by S3NS
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 memoryEste 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-systemDespué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.confdel pod:kubectl exec -it POD_NAME -- cat /etc/resolv.confSustituye 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.confsea correcta:- Los pods que usen una red de host deben usar los valores del archivo
/etc/resolv.confdel 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-systemEl 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 64dAnota 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:5En 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 se ha configurado un campo
dnsConfigen el manifiesto del pod de la aplicación.Si el valor del campo
dnsConfig.nameserverses 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_NAMESustituye
POD_NAMEpor el nombre de tu pod.
- Los pods que usen una red de host deben usar los valores del archivo
Verifica las entradas de
searchyndotsen/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_NAMEHaz 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,sho/bin/bash.
Es posible que este comando falle si tu pod no permite el comando
kubectl execo 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 - bashComprueba si el pod puede resolver correctamente el servicio DNS interno del clúster:
dig kubernetesComo el archivo
/etc/resolv.confapunta 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 vesSERVFAILo 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.comSi 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_IPSustituye
KUBE_DNS_POD_IPpor 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 wideLa dirección IP se encuentra en la columna
IP.Si la resolución del comando se realiza correctamente, verás
status: NOERRORy 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: 56Salir 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 Cloud de Confiance , 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 wideEl 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:
toolboxEn la petición de raíz, instala el paquete
tcpdump:apt update -y && apt install -y tcpdumpCon
tcpdump, haz una captura de paquetes de tu tráfico DNS:tcpdump -i eth0 port 53" -w FILE_LOCATIONSustituye
FILE_LOCATIONpor 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 permite 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 adecuada de registros.
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-debugTambién puede ver las consultas en Cloud Logging.
Cuando hayas terminado de ver los registros de consultas de DNS, elimina el
kube-dns-debugPod: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 Cloud de Confiance 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.comen 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 Cloud de Confiance 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 Cloud de Confiance 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
ndotsen el archivo/etc/resolv.conf.ndotsrepresenta 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.confde 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:5En 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." NOERRORPara solucionar este problema, cambie el valor de ndots a
1para 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 veas 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 Cloud de Confiance 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 de kube-dns correcta, captura el tráfico de red en el nodo problemático y filtra por el puerto 53 (tráfico de 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-enginepara buscar problemas similares. También puedes unirte al#kubernetes-enginecanal de Slack para obtener más ayuda de la comunidad. - Abrir errores o solicitudes de funciones mediante el seguimiento de problemas público.