Si ejecutas aplicaciones en clústeres estándar, kube-dns es el proveedor de DNS predeterminado que te ayuda a habilitar la detección y la comunicación de servicios. En este documento se describe cómo gestionar el DNS con kube-dns, así como su arquitectura, configuración y prácticas recomendadas para optimizar la resolución de DNS en tu entorno de GKE.
Este documento está dirigido a desarrolladores, administradores y arquitectos que se encargan de gestionar el DNS en GKE. Para obtener contexto sobre los roles y las tareas habituales en Google Cloud, consulta Roles y tareas habituales de los usuarios de GKE Enterprise.
Antes de empezar, asegúrate de que conoces los servicios de Kubernetes y los conceptos generales de DNS.
Información sobre la arquitectura de kube-dns
kube-dns funciona dentro de tu clúster de GKE para habilitar la resolución de DNS entre pods y servicios.
En el siguiente diagrama se muestra cómo interactúan tus pods con el servicio kube-dns:
Componentes clave
kube-dns incluye los siguientes componentes clave:
kube-dnsPods: estos pods ejecutan el software del servidorkube-dns. Se ejecutan varias réplicas de estos pods en el espacio de nombreskube-system, que proporcionan alta disponibilidad y redundancia.kube-dnsServicio: este servicio de Kubernetes de tipoClusterIPagrupa los podskube-dnsy los expone como un único endpoint estable.ClusterIPactúa como servidor DNS del clúster, que los pods utilizan para enviar consultas de DNS.kube-dnsadmite hasta 1000 endpoints por servicio sin interfaz gráfica.kube-dns-autoscaler: este pod ajusta el número de réplicas dekube-dnsen función del tamaño del clúster, que incluye el número de nodos y núcleos de CPU. De esta forma, se asegura de quekube-dnspueda gestionar cargas de consultas de DNS variables.
Resolución de DNS interna
Cuando un pod necesita resolver un nombre de DNS dentro del dominio del clúster, como myservice.my-namespace.svc.cluster.local, se produce el siguiente proceso:
- Configuración de DNS de los pods: el
kubeletde cada nodo configura el archivo/etc/resolv.confdel pod. Este archivo usa elkube-dnsdeClusterIPcomo servidor de nombres. - Consulta DNS: el pod envía una consulta DNS al servicio
kube-dns. - Resolución de nombres:
kube-dnsrecibe la consulta. Busca la dirección IP correspondiente en sus registros DNS internos y responde al pod. - Comunicación: el pod usa la dirección IP resuelta para comunicarse con el servicio de destino.
Resolución de DNS externa
Cuando un pod necesita resolver un nombre DNS externo o un nombre que está fuera del dominio del clúster, kube-dns actúa como un resolvedor recursivo. Reenvía la consulta a los servidores DNS upstream configurados en su archivo ConfigMap. También puedes configurar resoluciones personalizadas para dominios específicos, que también se conocen como dominios stub. Esta configuración indica a kube-dns que reenvíe las solicitudes de esos dominios a servidores DNS upstream específicos.
Configurar el DNS de los pods
En GKE, el agente kubelet de cada nodo configura los ajustes de DNS de los pods que se ejecutan en ese nodo.
Configurar el archivo /etc/resolv.conf
Cuando GKE crea un pod, el agente kubelet modifica el archivo /etc/resolv.conf del pod. Este archivo configura el servidor DNS para la resolución de nombres
y especifica los dominios de búsqueda. De forma predeterminada, kubelet configura el pod para que use el servicio DNS interno del clúster, kube-dns, como servidor de nombres. También rellena los dominios de búsqueda del archivo. Estos dominios de búsqueda te permiten usar nombres no cualificados en las consultas de DNS. Por ejemplo, si un pod consulta myservice, Kubernetes primero intenta resolver myservice.default.svc.cluster.local, luego myservice.svc.cluster.local y, a continuación, otros dominios de la lista search.
En el siguiente ejemplo se muestra una configuración /etc/resolv.conf predeterminada:
nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local c.my-project-id.internal google.internal
options ndots:5
Este archivo tiene las siguientes entradas:
nameserver: define elClusterIPdel serviciokube-dns.search: define los dominios de búsqueda que se añaden a los nombres no cualificados durante las búsquedas de DNS.options ndots:5: define el umbral para que GKE considere que un nombre está completo. Un nombre se considera completo si tiene cinco o más puntos.
Los pods configurados con el ajuste hostNetwork: true heredan su configuración de DNS del host y no consultan kube-dns directamente.
Personalizar kube-dns
kube-dns proporciona una resolución de DNS predeterminada sólida. Puedes adaptar su comportamiento a necesidades específicas, como mejorar la eficiencia de la resolución o usar los resolvedores de DNS que prefieras. Los dominios stub y los servidores de nombres upstream se configuran modificando el kube-dns ConfigMap en el espacio de nombres kube-system.
Modifica el ConfigMap kube-dns.
Para modificar el kube-dns ConfigMap, haz lo siguiente:
Abre el ConfigMap para editarlo:
kubectl edit configmap kube-dns -n kube-systemEn la sección
data, añada los camposstubDomainsyupstreamNameserversa lo siguiente:apiVersion: v1 kind: ConfigMap metadata: labels: addonmanager.kubernetes.io/mode: EnsureExists name: kube-dns namespace: kube-system data: stubDomains: | { "example.com": [ "8.8.8.8", "8.8.4.4" ], "internal": [ # Required if your upstream nameservers can't resolve GKE internal domains "169.254.169.254" # IP of the metadata server ] } upstreamNameservers: | [ "8.8.8.8", # Google Public DNS "1.1.1.1" # Cloudflare DNS ]Guarda el ConfigMap.
kube-dnsvuelve a cargar la configuración automáticamente.
Dominios de stub
Los dominios stub te permiten definir resoluciones de DNS personalizadas para dominios específicos. Cuando un pod consulta un nombre en ese dominio stub, kube-dns reenvía la consulta al resolver especificado en lugar de usar su mecanismo de resolución predeterminado.
Incluye una sección stubDomains en el kube-dns ConfigMap.
En esta sección se especifican el dominio y los servidores de nombres upstream correspondientes.
A continuación, kube-dns reenvía las consultas de nombres de ese dominio a los servidores designados. Por ejemplo, puedes enrutar todas las consultas de DNS de internal.mycompany.com
a 192.168.0.10 o añadir "internal.mycompany.com": ["192.168.0.10"] a
stubDomains.
Cuando configuras un resolvedor personalizado para un dominio stub, como example.com,
kube-dns reenvía todas las solicitudes de resolución de nombres de ese dominio, incluidos los subdominios como *.example.com, a los servidores especificados.
Servidores de nombres upstream
Puedes configurar kube-dns para que use servidores de nombres upstream personalizados para resolver nombres de dominio externos. Esta configuración indica a kube-dns que reenvíe todas las solicitudes DNS, excepto las solicitudes del dominio interno del clúster (*.cluster.local), a los servidores upstream designados. Es posible que tus servidores upstream personalizados no puedan resolver dominios internos como metadata.internal y *.google.internal. Si habilitas Workload Identity Federation para GKE o tienes cargas de trabajo que dependen de estos dominios, añade un dominio de stub para internal en ConfigMap. Usa 169.254.169.254, la dirección IP del servidor de metadatos, como el
resolver de este dominio stub.
Gestionar una implementación personalizada de kube-dns
En un clúster de GKE estándar, kube-dns se ejecuta como un Deployment. Una implementación personalizada
kube-dns significa que tú, como administrador del clúster, puedes controlar
la implementación y personalizarla según tus necesidades, en lugar de usar la implementación
predeterminada proporcionada por GKE.
Motivos para crear un despliegue personalizado
Te recomendamos que utilices una implementación kube-dns personalizada por los siguientes motivos:
- Asignación de recursos: ajusta los recursos de CPU y memoria de los pods de
kube-dnspara optimizar el rendimiento en clústeres con mucho tráfico de DNS. - Versión de la imagen: usa una versión específica de la imagen de
kube-dnso cambia a un proveedor de DNS alternativo, como CoreDNS. - Configuración avanzada: personaliza los niveles de registro, las políticas de seguridad y el comportamiento del almacenamiento en caché de DNS.
Autoescalado de despliegues personalizados
La función kube-dns-autoscaler integrada funciona con la implementación kube-dns predeterminada.
Si crea una kube-dns implementación personalizada, la herramienta de escalado automático integrada no la gestionará. Por lo tanto, debes configurar un escalador automático independiente que esté configurado específicamente para monitorizar y ajustar el número de réplicas de tu Deployment personalizado.
Este enfoque implica crear e implementar tu propia configuración de autoescalador en tu clúster.
Cuando gestionas una implementación personalizada, eres responsable de todos sus componentes, como mantener actualizada la imagen del escalador automático. Usar componentes obsoletos puede provocar un deterioro del rendimiento o errores de DNS.
Para obtener instrucciones detalladas sobre cómo configurar y gestionar tu propia kube-dns
implementación, consulta Configurar una implementación de kube-dns personalizada.
Solucionar problemas
Para obtener información sobre cómo solucionar problemas de kube-dns, consulta las siguientes páginas:
- Para obtener información sobre
kube-dnsen GKE, consulta Solucionar problemas dekube-dnsen GKE. - Para obtener consejos generales sobre cómo diagnosticar problemas de DNS de Kubernetes, consulta Depuración de la resolución de DNS.
Optimizar la resolución de DNS
En esta sección se describen problemas habituales y prácticas recomendadas para gestionar el DNS en GKE.
Límite de dominios de búsqueda de dnsConfig de un Pod
Kubernetes limita el número de dominios de búsqueda de DNS a 32. Si intentas definir más de 32 dominios de búsqueda en el dnsConfig de un pod, el kube-apiserver no creará el pod y mostrará un error similar al siguiente:
The Pod "dns-example" is invalid: spec.dnsConfig.searches: Invalid value: []string{"ns1.svc.cluster-domain.example", "my.dns.search.suffix1", "ns2.svc.cluster-domain.example", "my.dns.search.suffix2", "ns3.svc.cluster-domain.example", "my.dns.search.suffix3", "ns4.svc.cluster-domain.example", "my.dns.search.suffix4", "ns5.svc.cluster-domain.example", "my.dns.search.suffix5", "ns6.svc.cluster-domain.example", "my.dns.search.suffix6", "ns7.svc.cluster-domain.example", "my.dns.search.suffix7", "ns8.svc.cluster-domain.example", "my.dns.search.suffix8", "ns9.svc.cluster-domain.example", "my.dns.search.suffix9", "ns10.svc.cluster-domain.example", "my.dns.search.suffix10", "ns11.svc.cluster-domain.example", "my.dns.search.suffix11", "ns12.svc.cluster-domain.example", "my.dns.search.suffix12", "ns13.svc.cluster-domain.example", "my.dns.search.suffix13", "ns14.svc.cluster-domain.example", "my.dns.search.suffix14", "ns15.svc.cluster-domain.example", "my.dns.search.suffix15", "ns16.svc.cluster-domain.example", "my.dns.search.suffix16", "my.dns.search.suffix17"}: must not have more than 32 search paths.
kube-apiserver devuelve este mensaje de error en respuesta a un intento de creación de un pod. Para solucionar este problema, elimina las rutas de búsqueda adicionales de la configuración.
Límite de nameservers de subida para kube-dns
kube-dns limita el número de valores de upstreamNameservers a tres. Si defines más de tres, Cloud Logging muestra un error similar al siguiente:
Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update
En este caso, kube-dns ignora la configuración de upstreamNameservers y sigue usando la configuración válida anterior. Para solucionar este problema, quita el upstreamNameservers adicional de kube-dns ConfigMap.
Aumentar la escala kube-dns
En los clústeres estándar, puedes usar un valor inferior para nodesPerReplica
para que se creen más pods kube-dns cuando se escale verticalmente el número de nodos del clúster. Te recomendamos que definas un valor explícito para el campo max para asegurarte de que la máquina virtual (VM) del plano de control de GKE no se vea sobrecargada debido al gran número de pods kube-dns que están monitorizando la API de Kubernetes.
Puedes definir el valor del campo max como el número de nodos del clúster.
Si el clúster tiene más de 500 nodos, asigna el valor 500 al campo max.
Puedes modificar el número de réplicas de kube-dns editando el kube-dns-autoscaler ConfigMap.
kubectl edit configmap kube-dns-autoscaler --namespace=kube-system
El resultado debería ser similar al siguiente:
linear: '{"coresPerReplica":256, "nodesPerReplica":16,"preventSinglePointFailure":true}'
El número de réplicas de kube-dns se calcula mediante la siguiente fórmula:
replicas = max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) )
Para aumentar la escala, cambia el valor del campo nodesPerReplica a un valor menor e incluye un valor en el campo max.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
Esta configuración crea un kube-dns pod por cada ocho nodos del clúster. Un clúster de 24 nodos tiene tres réplicas y un clúster de 40 nodos tiene cinco réplicas. Si el clúster supera los 120 nodos, el número de réplicas de kube-dns no superará las 15, que es el valor del campo max.
Para asegurar un nivel básico de disponibilidad de DNS en tu clúster, define un número mínimo de réplicas para el campo kube-dns.
El resultado de kube-dns-autoscaler ConfigMap con el campo min configurado es similar al siguiente:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
Mejorar los tiempos de petición de DNS
Hay varios factores que pueden provocar una latencia alta en las peticiones de DNS o en los errores de resolución de DNS con el proveedor kube-dns predeterminado. Las aplicaciones pueden experimentar estos problemas como errores getaddrinfo EAI_AGAIN, que indican un fallo temporal en la resolución de nombres. Entre las causas se incluyen las siguientes:
- Peticiones de DNS frecuentes en tu carga de trabajo.
- Alta densidad de pods por nodo.
- Ejecutar
kube-dnsen máquinas virtuales de Spot o máquinas virtuales interrumpibles, lo que puede provocar la eliminación inesperada de nodos. - Un volumen de consultas alto que supera la capacidad de la instancia
dnsmasqen el podkube-dns. Una sola instancia dekube-dnstiene un límite de 200 conexiones TCP simultáneas en GKE 1.31 y versiones posteriores, y un límite de 20 conexiones TCP simultáneas en GKE 1.30 y versiones anteriores.
Para mejorar los tiempos de búsqueda de DNS, haz lo siguiente:
- Evita ejecutar componentes críticos del sistema, como
kube-dns, en Spot VMs o máquinas virtuales interrumpibles. Crea al menos un grupo de nodos que tenga VMs estándar y no tenga VMs de Spot ni VMs interrumpibles. Usa taints y tolerations para asegurarte de que las cargas de trabajo críticas se programen en estos nodos fiables. - Habilita NodeLocal
DNSCache. NodeLocal DNSCache almacena en caché las respuestas de DNS directamente en cada nodo, lo que reduce la latencia y la carga en el servicio
kube-dns. Si habilitas NodeLocal DNSCache y usas políticas de red con reglas de denegación predeterminadas, añade una política para permitir que las cargas de trabajo envíen consultas de DNS a los podsnode-local-dns. - Aumentar la escala
kube-dns. - Asegúrate de que tu aplicación use funciones basadas en
dns.resolve*en lugar de funciones basadas endns.lookup, ya quedns.lookupes síncrono. - Usa nombres de dominio completos (FQDNs), por ejemplo,
https://google.com./en lugar dehttps://google.com/.
Pueden producirse errores de resolución de DNS durante las actualizaciones de clústeres de GKE debido a las actualizaciones simultáneas de los componentes del plano de control, incluido kube-dns.
Estos errores suelen afectar a un pequeño porcentaje de nodos. Prueba a fondo las actualizaciones de clústeres en un entorno que no sea de producción antes de aplicarlas a los clústeres de producción.
Asegurar la visibilidad del servicio
kube-dns solo crea registros DNS para los servicios que tienen endpoints. Si un servicio no tiene ningún endpoint, kube-dns no crea registros DNS para ese servicio.
Gestionar las discrepancias de TTL de DNS
Si kube-dns recibe una respuesta DNS de un resolvedor DNS upstream con un TTL grande o infinito, mantiene este valor de TTL. Este comportamiento puede provocar una discrepancia entre la entrada almacenada en caché y la dirección IP real.
GKE resuelve este problema en versiones específicas del plano de control, como 1.21.14-gke.9100 y posteriores, o 1.22.15-gke.2100 y posteriores. Estas versiones definen un valor TTL máximo de 30 segundos para cualquier respuesta DNS que tenga un TTL superior. Este comportamiento es similar al de NodeLocal DNSCache.
Ver métricas de kube-dns
Puede obtener métricas sobre las consultas DNS de su clúster directamente de los kube-dnspods.
Busca los pods de
kube-dnsen el espacio de nombreskube-system:kubectl get pods -n kube-system --selector=k8s-app=kube-dnsEl resultado debería ser similar al siguiente:
NAME READY STATUS RESTARTS AGE kube-dns-548976df6c-98fkd 4/4 Running 0 48m kube-dns-548976df6c-x4xsh 4/4 Running 0 47mElige uno de los pods y configura el reenvío de puertos para acceder a las métricas de ese pod:
- El puerto
10055expone las métricas dekube-dns. - El puerto
10054expone las métricas dednsmasq.
Sustituye
POD_NAMEpor el nombre del pod que hayas elegido.POD_NAME="kube-dns-548976df6c-98fkd" # Replace with your pod name kubectl port-forward pod/${POD_NAME} -n kube-system 10055:10055 10054:10054El resultado debería ser similar al siguiente:
Forwarding from 127.0.0.1:10054 -> 10054 Forwarding from 127.0.0.1:10055 -> 10055- El puerto
En una nueva sesión de terminal, usa el comando
curlpara acceder a los endpoints de métricas.# Get kube-dns metrics curl http://127.0.0.1:10055/metrics # Get dnsmasq metrics curl http://127.0.0.1:10054/metricsLa salida será similar a la siguiente:
kubedns_dnsmasq_errors 0 kubedns_dnsmasq_evictions 0 kubedns_dnsmasq_hits 3.67351e+06 kubedns_dnsmasq_insertions 254114 kubedns_dnsmasq_max_size 1000 kubedns_dnsmasq_misses 3.278166e+06
Siguientes pasos
- Consulta una descripción general del DNS de clústeres en GKE.
- Consulta DNS para servicios y pods para obtener una descripción general de cómo se usa el DNS en los clústeres de Kubernetes.
- Consulta cómo configurar NodeLocalDNSCache.
- Consulta cómo configurar un despliegue personalizado de kube-dns.