En esta página, se muestra cómo resolver problemas con kube-dns en Google Kubernetes Engine (GKE).
Identifica el origen de los problemas de DNS en kube-dns
Los errores como dial tcp: i/o timeout
, no such
host
o Could not resolve host
suelen indicar problemas con la capacidad de kube-dns para resolver consultas.
Si viste uno de esos errores, pero no conoces la causa, usa las siguientes secciones para ayudarte a encontrarla. Las siguientes secciones están organizadas para comenzar con los pasos que probablemente te ayudarán más, así que prueba cada sección en orden.
Verifica si los Pods de kube-dns se están ejecutando
Los Pods de kube-dns son fundamentales para la resolución de nombres dentro del 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 es similar a este:
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 agregan automáticamente a los Pods de kube-dns.
Si el resultado muestra que alguno de tus Pods de kube-dns no tiene el estado Running
, sigue estos pasos:
Usa los registros de auditoría de actividad del administrador para investigar si hubo cambios recientes, como actualizaciones de versiones de clústeres o grupos de nodos, o cambios en el ConfigMap de kube-dns. Para obtener más información sobre los registros de auditoría, consulta la información del registro de auditoría de GKE. Si encuentras cambios, revierte y vuelve a ver el estado de los Pods.
Si no encuentras ningún cambio reciente pertinente, investiga si se produce un error de OOM en el nodo en el que se ejecuta el Pod de 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 OOM:
Warning: OOMKilling Memory cgroup out of memory
Este mensaje indica que Kubernetes finalizó 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 más altos que las solicitudes o no hay límites, el uso de recursos del Pod puede exceder los recursos del sistema.
Para resolver este error, puedes borrar las cargas de trabajo que generan problemas o establecer límites de memoria o CPU. Si deseas obtener más información para establecer límites, consulta Administración de recursos para Pods y contenedores en la documentación de Kubernetes. Para obtener más información sobre los eventos de OOM, consulta Soluciona problemas relacionados con eventos de OOM.
Si no encuentras ningún mensaje de error de OOM, reinicia la Deployment de kube-dns:
kubectl rollout restart deployment/kube-dns --namespace=kube-system
Después de reiniciar la Deployment, verifica si tus Pods de kube-dns se están ejecutando.
Si estos pasos no funcionan o todos tus Pods de kube-dns tienen el estado Running
, pero sigues teniendo problemas de DNS, verifica que el archivo /etc/resolv.conf
esté configurado correctamente.
Verifica que /etc/resolv.conf
esté configurado correctamente
Revisa el archivo /etc/resolv.conf
de los Pods que tienen problemas de DNS y asegúrate de que las entradas que contiene sean correctas:
Visualiza el archivo
/etc/resolv.conf
del Pod:kubectl exec -it POD_NAME -- cat /etc/resolv.conf
Reemplaza POD_NAME por el nombre del pod que tiene problemas de DNS. Si hay varios Pods que tienen problemas, repite los pasos de esta sección para cada uno de ellos.
Si el binario del Pod no admite el comando
kubectl exec
, es posible que este comando falle. Si esto sucede, crea un Pod simple 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.Verifica que la dirección IP del servidor de nombres en el archivo
/etc/resolv.conf
sea correcta:- Los Pods que usan una red del 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, completa los siguientes pasos:
Obtén la dirección IP del servicio kube-dns:
kubectl get svc kube-dns -n kube-system
El resultado es similar a este:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 192.0.2.10 <none> 53/UDP,53/TCP 64d
Toma nota del valor en 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 la dirección IP incorrecta del servidor de nombres no es la causa del problema.
Sin embargo, si las direcciones IP no coinciden, significa que se configuró un campo
dnsConfig
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 funcione correctamente.Si no quieres usar el servidor de nombres personalizado, quita el campo y realiza un reinicio progresivo del Pod:
kubectl rollout restart deployment POD_NAME
Reemplaza
POD_NAME
por el nombre del Pod.
- Los Pods que usan una red del host deben usar los valores del archivo
Verifica las entradas
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 existente en el espacio de nombres correcto.
Realiza una búsqueda de DNS
Después de confirmar 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 errores de DNS:
Consulta un Pod directamente abriendo una shell dentro de él:
kubectl exec -it POD_NAME -n NAMESPACE_NAME -- SHELL_NAME
Reemplaza lo siguiente:
POD_NAME
: Es el nombre del Pod que informa errores de DNS.NAMESPACE_NAME
: Es el espacio de nombres al que pertenece el Pod.SHELL_NAME
: Es el nombre del shell que deseas abrir. Por ejemplo,sh
o/bin/bash
.
Este comando podría fallar si tu Pod no permite el comando
kubectl exec
o si no tiene el binario dig. Si esto sucede, crea un Pod de prueba con una imagen que tenga instalado dig:kubectl run "test-$RANDOM" ti --restart=Never --image=thockin/dnsutils - bash
Verifica si el Pod puede resolver correctamente el servicio de DNS interno del clúster:
dig kubernetes
Dado que el archivo
/etc/resolv.conf
apunta a la dirección IP del servicio de kube-dns, cuando ejecutas este comando, el servidor DNS es el servicio de kube-dns.Deberías ver una respuesta de DNS correcta con la dirección IP del servicio de la API de Kubernetes (a menudo, algo como
10.96.0.1
). Si vesSERVFAIL
o no hay respuesta, esto suele indicar que el Pod de kube-dns no puede resolver los nombres de servicio internos.Verifica si el servicio kube-dns puede resolver un nombre de dominio externo:
dig example.com
Si tienes dificultades con un Pod de kube-dns en particular que responde a las consultas de DNS, verifica si ese Pod puede resolver un nombre de dominio externo:
dig example.com @KUBE_DNS_POD_IP
Reemplaza
KUBE_DNS_POD_IP
por la dirección IP del Pod de kube-dns. Si no conoces 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
Sal de la shell:
exit
Si falla alguno de estos comandos, realiza un reinicio progresivo de la Deployment de kube-dns:
kubectl rollout restart deployment/kube-dns --namespace=kube-system
Después de completar el reinicio, vuelve a intentar los comandos dig y comprueba si ahora se ejecutan correctamente. Si siguen fallando, realiza una captura de paquetes.
Cómo tomar una captura de paquetes
Realiza una captura de paquetes para verificar si los Pods de kube-dns reciben las consultas de DNS y responden a ellas de forma adecuada:
Conéctate al nodo que ejecuta el Pod kube-dns con SSH. Por ejemplo:
En la Google Cloud consola, ve a la página Instancias de VM.
Ubica el nodo al que deseas conectarte. Si no conoces el nombre del nodo en tu Pod de 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 la terminal, inicia toolbox, una herramienta de depuración preinstalada:
toolbox
En el mensaje de raíz, instala el paquete
tcpdump
:apt update -y && apt install -y tcpdump
Con
tcpdump
, realiza una captura de paquetes de tu tráfico de DNS:tcpdump -i eth0 port 53" -w FILE_LOCATION
Reemplaza
FILE_LOCATION
por la ruta de acceso en la que deseas guardar la captura.Revisa la captura de paquetes. Verifica si hay paquetes con direcciones IP de destino que coincidan con la dirección IP del servicio kube-dns. Esto garantiza que las solicitudes de DNS lleguen al destino correcto para su resolución. Si no ves que el tráfico de DNS llega a los Pods correctos, es posible que haya una política de red que bloquee las solicitudes.
Cómo verificar si hay una política de red
En ocasiones, las políticas de red restrictivas pueden interrumpir el tráfico de DNS. Para verificar 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 de 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 de DNS.
Si el resultado es No resources found in kube-system namespace
, no tienes ninguna política de red y puedes descartar esta opción como la causa del problema. Investigar los registros puede ayudarte a encontrar más puntos de falla.
Habilita el registro temporal de consultas de DNS
Para ayudarte a identificar problemas, como respuestas de DNS incorrectas, habilita temporalmente el registro de depuración de las consultas de DNS. Para habilitar las consultas, crea un Pod basado en un Pod kube-dns existente. Los cambios en la Deployment de kube-dns se revierten automáticamente.
Habilitar el registro temporal de consultas de DNS es un procedimiento que requiere muchos recursos, por lo que te recomendamos que borres el Pod que crees tan pronto como recopiles una muestra adecuada de registros.
Para habilitar el registro temporal de consultas de DNS, completa los siguientes 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 puedes ver las consultas en Cloud Logging.
Cuando termines de ver los registros de consultas de DNS, borra el Pod:
kube-dns-debug
kubectl -n kube-system delete pod kube-dns-debug
Investiga el Pod de kube-dns
Revisa cómo los Pods de kube-dns reciben y resuelven las consultas de DNS con Cloud Logging.
Para ver las entradas de registro relacionadas con el Pod de kube-dns, completa los siguientes pasos:
En la Google Cloud consola, ve a la página Explorador de registros.
En el panel de consultas, ingresa 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"
Reemplaza lo siguiente:
CLUSTER_NAME
: Es el nombre del clúster al que pertenece el Pod de kube-dns.CLUSTER_LOCATION
: Es la ubicación de tu clúster.
Haz clic en Ejecutar consulta.
Revise el resultado. En el siguiente ejemplo de resultado, se muestra un posible error que podrías ver:
{ "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 pudo resolver
example.com
en un tiempo razonable. Este tipo de error puede deberse a varios problemas. Por ejemplo, es posible que el servidor ascendente esté configurado de forma incorrecta en el ConfigMap de kube-dns o que haya un tráfico de red alto.
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
Investiga los cambios recientes en el ConfigMap de kube-dns
Si de repente se producen fallas en la resolución de DNS en tu clúster, una de las causas puede ser un cambio de configuración incorrecto realizado en el ConfigMap de kube-dns. En particular, los cambios de configuración en las definiciones de los dominios de stub y los servidores upstream pueden causar problemas.
Para verificar si hay actualizaciones en la configuración del dominio de zona, completa los siguientes pasos:
En la Google Cloud consola, ve a la página Explorador de registros.
En el panel de consultas, ingresa 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 Ejecutar consulta.
Revise el resultado. Si hubo actualizaciones, el resultado es 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, expande el resultado para obtener más información sobre los cambios. Verifica que los dominios de stub y sus servidores DNS ascendentes correspondientes estén definidos correctamente. Si las entradas son incorrectas, es posible que se produzcan errores de resolución para esos dominios.
Para verificar si hay cambios en el servidor upstream, completa los siguientes pasos:
En la Google Cloud consola, ve a la página Explorador de registros.
En el panel de consultas, ingresa 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 Ejecutar consulta.
Revise el resultado. Si hubo cambios, el resultado es similar al siguiente:
Updated upstreamNameservers to [8.8.8.8]
Expande 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 verificaste los cambios en los dominios stub y los servidores upstream, pero no encontraste ningún resultado, verifica 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 enumeran para ver si causaron el error.
Comunícate con Atención al cliente de Cloud
Si completaste las secciones anteriores, pero aún no puedes diagnosticar la causa del problema, comunícate con Atención al cliente de Cloud.
Soluciona problemas habituales
Si experimentaste un error o problema específico, sigue las recomendaciones de las siguientes secciones.
Problema: Se agota el tiempo de espera de DNS de forma intermitente
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 comienzan las horas de trabajo, prueba las siguientes soluciones para optimizar el rendimiento de DNS:
Verifica la cantidad de Pods de kube-dns que se ejecutan en el clúster y compárala con la cantidad total de nodos de GKE. Si no hay suficientes recursos, considera aumentar la escala de los Pods de kube-dns.
Para mejorar el tiempo promedio de búsqueda de DNS, habilita NodeLocal DNS Cache.
La resolución de DNS para nombres externos puede sobrecargar el Pod de kube-dns. Para reducir la cantidad de búsquedas, ajusta el parámetro de configuración
ndots
en el archivo/etc/resolv.conf
.ndots
representa la cantidad 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 que se consulta. Si el Pod realiza una llamada de resolución de DNS para
example.com
, tus registros se verá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 resolver este problema, cambia el valor de ndots a
1
para buscar solo un punto o agrega un punto (.
) al final del dominio que consultas o usas. 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.
- Falla la ejecución de comandos dig desde un Pod en el mismo nodo que el Pod kube-dns.
Para resolver este problema, realiza los siguientes pasos:
- Realiza una prueba de conectividad. Establece el Pod o el nodo problemático como la fuente y el destino como la dirección IP del Pod kube-dns. Esto te permite verificar si tienes las reglas de firewall necesarias para permitir este tráfico.
Si la prueba no se realiza correctamente y una regla de firewall bloquea el tráfico, usa Cloud Logging para enumerar los cambios manuales que se realizaron en las reglas de firewall. Busca los cambios que bloquean un tipo específico de tráfico:
En la Google Cloud consola, ve a la página Explorador de registros.
En el panel de consultas, ingresa la siguiente consulta:
logName="projects/project-name/logs/cloudaudit.googleapis.com/activity" resource.type="gce_firewall_rule"
Haz clic en Ejecutar consulta. Usa el resultado de la consulta para determinar si se realizaron cambios. Si observas algún error, corrígelo y vuelve a aplicar la regla de firewall.
Asegúrate de no realizar cambios en ninguna regla de firewall automática.
Si no hubo cambios en las reglas del firewall, verifica 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 más de dos versiones secundarias anteriores a la versión del plano de control, es posible que esto genere problemas. Para obtener más información sobre esta incompatibilidad, consulta La versión del nodo 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 el puerto 53 (tráfico de DNS). Captura el tráfico en los Pods de kube-dns para ver si las solicitudes llegan a los Pods previstos y si se resuelven correctamente.
¿Qué sigue?
Para obtener información general sobre el diagnóstico de 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 Obtener asistencia para obtener más ayuda, incluidos consejos sobre los siguientes temas:
- Abrir un caso de asistencia comunicándose con Atención al cliente de Cloud
- Obtén asistencia de la comunidad haciendo preguntas en StackOverflow y usando la etiqueta
google-kubernetes-engine
para buscar problemas similares. También puedes unirte al canal de Slack#kubernetes-engine
para obtener más asistencia de la comunidad. - Abrir errores o solicitudes de funciones con la herramienta de seguimiento de errores pública