En esta página se explica cómo mejorar la latencia de búsqueda de DNS en un clúster de Google Kubernetes Engine (GKE) mediante NodeLocal DNSCache.
En los clústeres de GKE Autopilot, NodeLocal DNSCache está habilitado de forma predeterminada y no se puede anular.
Arquitectura
NodeLocal DNSCache es un complemento de GKE que puedes ejecutar además de kube-dns.
GKE implementa NodeLocal DNSCache como un DaemonSet que ejecuta una caché de DNS en cada nodo del clúster.
Cuando un pod hace una solicitud de DNS, esta se envía a la caché de DNS que se ejecuta en el mismo nodo que el pod. Si la caché no puede resolver la solicitud de DNS, la reenvía a uno de los siguientes lugares en función del destino de la consulta:
- kube-dns: todas las consultas del dominio DNS del clúster (
cluster.local
) se reenvían a kube-dns. Los pods node-local-dns usan el servicio kube-dns-upstream para acceder a los pods kube-dns. En el siguiente diagrama, la dirección IP del servicio kube-dns es10.0.0.10:53
. - Dominios stub personalizados o servidores de nombres upstream: las consultas se reenvían directamente desde los pods de NodeLocal DNSCache.
- Cloud DNS: todas las demás consultas se reenvían al servidor de metadatos local que se ejecuta en el mismo nodo que el pod del que procede la consulta. El servidor de metadatos local accede a Cloud DNS.
Cuando habilitas NodeLocal DNSCache en un clúster, GKE vuelve a crear todos los nodos del clúster que ejecutan GKE 1.15 o una versión posterior según el proceso de actualización de nodos.
Una vez que GKE haya recreado los nodos, GKE añadirá automáticamente la etiqueta addon.gke.io/node-local-dns-ds-ready=true
a los nodos. No debes añadir esta etiqueta a los nodos del clúster manualmente.
Ventajas de NodeLocal DNSCache
NodeLocal DNSCache ofrece las siguientes ventajas:
- Reducción del tiempo medio de petición de DNS
- Las conexiones de los pods a su caché local no crean entradas en la tabla conntrack. De esta forma, se evitan las conexiones rechazadas y perdidas causadas por el agotamiento de la tabla conntrack y las condiciones de carrera.
- Puedes usar NodeLocal DNSCache con Cloud DNS para GKE.
- Las consultas de DNS de URLs externas (URLs que no hacen referencia a recursos del clúster) se reenvían directamente al servidor de metadatos de Cloud DNS local, lo que evita kube-dns.
- Las cachés de DNS locales detectan automáticamente los dominios stub y los servidores de nombres upstream que se especifican en la sección Añadir resoluciones personalizadas para dominios stub.
Requisitos y limitaciones
- NodeLocal DNSCache consume recursos de computación en cada nodo de tu clúster.
- NodeLocal DNSCache no es compatible con los grupos de nodos de Windows Server.
- NodeLocal DNSCache requiere GKE 1.15 o una versión posterior.
- NodeLocal DNSCache accede a los pods de kube-dns mediante TCP.
- NodeLocal DNSCache accede a
upstreamServers
ystubDomains
mediante TCP y UDP en GKE 1.18 o versiones posteriores. Se debe poder acceder al servidor DNS mediante TCP y UDP. - Los registros DNS se almacenan en caché durante los siguientes periodos:
- El tiempo de vida (TTL) del registro o 30 segundos si el TTL es superior a 30 segundos.
- 5 segundos si la respuesta de DNS es
NXDOMAIN
.
- Los pods de NodeLocal DNSCache escuchan en los puertos 53, 9253, 9353 y 8080 de los nodos. Si ejecutas otro
hostNetwork
pod o configuras unhostPorts
con esos puertos, NodeLocal DNSCache fallará y se producirán errores de DNS. Los pods de NodeLocal DNSCache no usan el modohostNetwork
cuando se usa Dataplane V2 de GKE y no se usa Cloud DNS para GKE. - La caché DNS local solo se ejecuta en grupos de nodos que ejecutan versiones 1.15 y posteriores de GKE. Si habilitas NodeLocal DNSCache en un clúster con nodos que ejecutan versiones anteriores, los pods de esos nodos usarán kube-dns.
Habilitar NodeLocal DNSCache
En los clústeres de Autopilot, NodeLocal DNSCache está habilitado de forma predeterminada y no se puede anular.
En los clústeres estándar, puedes habilitar NodeLocal DNSCache en clústeres nuevos o ya creados mediante la CLI de Google Cloud. Puedes habilitar NodeLocal DNSCache en clústeres nuevos mediante la Trusted Cloud consola.
Habilitar NodeLocal DNSCache en un clúster nuevo
gcloud
Para habilitar NodeLocal DNSCache en un clúster nuevo, usa la marca --addons
con el argumento NodeLocalDNS
:
gcloud container clusters create CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--addons=NodeLocalDNS
Haz los cambios siguientes:
CLUSTER_NAME
: el nombre del nuevo clúster.COMPUTE_LOCATION
: la ubicación de Compute Engine del clúster.
Consola
Para habilitar NodeLocal DNSCache en un clúster nuevo, sigue estos pasos:
Ve a la página Google Kubernetes Engine en la Trusted Cloud consola.
Junto a Estándar, haz clic en Configurar.
Configura el clúster como quieras.
En el panel de navegación, haz clic en Redes.
En la sección Opciones de red avanzadas, marca la casilla Habilitar NodeLocal DNSCache.
Haz clic en Crear.
Habilitar NodeLocal DNSCache en un clúster
Para habilitar NodeLocal DNSCache en un clúster, usa la marca --update-addons
con el argumento NodeLocalDNS=ENABLED
:
gcloud container clusters update CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--update-addons=NodeLocalDNS=ENABLED
Haz los cambios siguientes:
CLUSTER_NAME
: el nombre de tu clúster.COMPUTE_LOCATION
: la ubicación de Compute Engine del clúster.
Para aplicar este cambio, es necesario volver a crear los nodos, lo que puede provocar interrupciones en las cargas de trabajo en ejecución. Para obtener información sobre este cambio concreto, busca la fila correspondiente en la tabla Cambios manuales que recrean los nodos mediante una estrategia de actualización de nodos y respetando las políticas de mantenimiento. Para obtener más información sobre las actualizaciones de nodos, consulta Planificar interrupciones de actualizaciones de nodos.
Verificar que NodeLocal DNSCache esté habilitado
Para comprobar que NodeLocal DNSCache se está ejecutando, puedes enumerar los node-local-dns
pods:
kubectl get pods -n kube-system -o wide | grep node-local-dns
El resultado debería ser similar al siguiente:
node-local-dns-869mt 1/1 Running 0 6m24s 10.128.0.35 gke-test-pool-69efb6b8-5d7m <none> <none>
node-local-dns-htx4w 1/1 Running 0 6m24s 10.128.0.36 gke-test-pool-69efb6b8-wssk <none> <none>
node-local-dns-v5njk 1/1 Running 0 6m24s 10.128.0.33 gke-test-pool-69efb6b8-bhz3 <none> <none>
El resultado muestra un pod node-local-dns
para cada nodo que ejecute la versión 1.15 o posterior de GKE.
Inhabilitar NodeLocal DNSCache
Puedes inhabilitar NodeLocal DNSCache con el siguiente comando:
gcloud container clusters update CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--update-addons=NodeLocalDNS=DISABLED
Haz los cambios siguientes:
CLUSTER_NAME
: el nombre del clúster que se va a inhabilitar.COMPUTE_LOCATION
: la ubicación de Compute Engine del clúster.
Para aplicar este cambio, es necesario volver a crear los nodos, lo que puede provocar interrupciones en las cargas de trabajo en ejecución. Para obtener información sobre este cambio concreto, busca la fila correspondiente en la tabla Cambios manuales que recrean los nodos mediante una estrategia de actualización de nodos y respetando las políticas de mantenimiento. Para obtener más información sobre las actualizaciones de nodos, consulta Planificar interrupciones de actualizaciones de nodos.
Solucionar problemas de NodeLocal DNSCache
Para obtener información general sobre cómo diagnosticar problemas de DNS de Kubernetes, consulta Depuración de la resolución de DNS.
NodeLocal DNSCache no se habilita inmediatamente
Cuando habilitas NodeLocal DNSCache en un clúster, es posible que GKE no actualice los nodos de inmediato si el clúster tiene una ventana de mantenimiento o exclusión configurada. Para obtener más información, consulta las advertencias sobre la recreación de nodos y las ventanas de mantenimiento.
Si prefieres no esperar, puedes aplicar los cambios a los nodos manualmente llamando al comando gcloud container clusters upgrade
y pasando el indicador --cluster-version
con la misma versión de GKE que ya está ejecutando el grupo de nodos. Para usar esta solución alternativa, debes usar la CLI de Google Cloud.
NodeLocal DNSCache con Cloud DNS
Si usas NodeLocal DNSCache con Cloud DNS, el clúster usa la dirección IP del servidor de nombres 169.254.20.10
, como se muestra en el siguiente diagrama:
Por lo tanto, la dirección IP del servicio kube-dns
puede ser diferente de la dirección IP del servidor de nombres que usan tus pods. Esta diferencia en las direcciones IP es normal, ya que se necesita la dirección IP del servidor de nombres 169.254.20.10
para que Cloud DNS funcione correctamente.
Para comprobar las direcciones IP, ejecuta los siguientes comandos:
Para ver la dirección IP del servicio
kube-dns
, sigue estos pasos:kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
El resultado es la dirección IP de
kube-dns
, como10.0.0.10:53
.Abre una sesión de shell en tu pod:
kubectl exec -it POD_NAME -- /bin/bash
En la sesión de shell del pod, lee el contenido del archivo
/etc/resolv.conf
:cat /etc/resolv.conf
El resultado es
169.254.20.10
Política de red con NodeLocal DNSCache
Si usas políticas de red con NodeLocal DNSCache y no usas Cloud DNS ni GKE Dataplane V2, debes configurar reglas para permitir que tus cargas de trabajo y los node-local-dns
Pods envíen consultas de DNS.
Usa una regla ipBlock
en tu manifiesto para permitir la comunicación entre tus pods y kube-dns.
El siguiente manifiesto describe una política de red que usa una regla ipBlock
:
spec:
egress:
- ports:
- port: 53
protocol: TCP
- port: 53
protocol: UDP
to:
- ipBlock:
cidr: KUBE_DNS_SVC_CLUSTER_IP/32
podSelector: {}
policyTypes:
- Egress
Sustituye KUBE_DNS_SVC_CLUSTER_IP
por la dirección IP del servicio kube-dns. Puedes obtener la dirección IP del servicio kube-dns con el siguiente comando:
kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
Problemas conocidos
Tiempo de espera de DNS en dnsPolicy ClusterFirstWithHostNet al usar NodeLocal DNSCache y GKE Dataplane V2
En los clústeres que usan GKE Dataplane V2 y NodeLocal DNSCache, los pods con hostNetwork
definido como true
y dnsPolicy
definido como ClusterFirstWithHostNet
no pueden acceder a los back-ends de DNS del clúster. Los registros DNS pueden contener entradas similares a las siguientes:
nslookup: write to 'a.b.c.d': Operation not permitted
;; connection timed out; no servers could be reached
El resultado indica que las solicitudes de DNS no pueden llegar a los servidores backend.
Una solución alternativa es definir dnsPolicy
y dnsConfig
para los pods hostNetwork
:
spec:
dnsPolicy: "None"
dnsConfig:
nameservers:
- KUBE_DNS_UPSTREAM
searches:
- cluster.local
- svc.cluster.local
- NAMESPACE.svc.cluster.local
- c.PROJECT_ID.internal
- google.internal
options:
- name: ndots
value: "5"
Haz los cambios siguientes:
NAMESPACE
: el espacio de nombres del podhostNetwork
.PROJECT_ID
: el ID de tu proyecto de Trusted Cloud .KUBE_DNS_UPSTREAM
: ClusterIP del servicio kube-dns upstream. Puedes obtener este valor con el siguiente comando:kubectl get svc -n kube-system kube-dns-upstream -o jsonpath="{.spec.clusterIP}"
Las solicitudes de DNS del pod ahora pueden llegar a kube-dns y omitir NodeLocal DNSCache.
Errores de tiempo de espera de NodeLocal DNSCache
En los clústeres en los que NodeLocal DNSCache está habilitado, los registros pueden contener entradas similares a las siguientes:
[ERROR] plugin/errors: 2 <hostname> A: read tcp <node IP: port>-><kubedns IP>:53: i/o timeout
El resultado incluye la dirección IP del servicio kube-dns-upstream
Cluster IP. En este ejemplo, no se ha recibido la respuesta a una solicitud de DNS de kube-dns en 2 segundos. Esto puede deberse a uno de los siguientes motivos:
- Un problema de conectividad de red subyacente.
- Las consultas de DNS de la carga de trabajo han aumentado significativamente o se debe a un aumento de los grupos de nodos.
Por lo tanto, los pods kube-dns
no pueden gestionar todas las solicitudes a tiempo. La solución alternativa consiste en aumentar el número de réplicas de kube-dns ajustando los parámetros de escalado automático.
Escalar verticalmente kube-dns
Puedes usar un valor inferior para nodesPerReplica
para asegurarte de que se creen más pods de kube-dns a medida que se escalen los nodos del clúster. Te recomendamos que definas un valor max
explícito 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 de kube-dns que monitorizan la API de Kubernetes.
Puedes definir max
como el número de nodos del clúster. Si el clúster tiene más de 500 nodos, asigna el valor 500 a max
.
En los clústeres estándar, puedes modificar el número de réplicas de kube-dns
editando el kube-dns-autoscaler
ConfigMap. Esta configuración no se admite en clústeres de Autopilot.
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 ), maxValue )
Para aumentar la escala, cambia nodesPerReplica
a un valor más pequeño e incluye un valor de max
.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
La configuración crea un pod kube-dns por cada 8 nodos del clúster. Un clúster de 24 nodos tendrá 3 réplicas y un clúster de 40 nodos tendrá 5 réplicas. Si el clúster supera los 120 nodos, el número de réplicas de kube-dns no superará las 15, el valor de max
.
Para asegurar un nivel de disponibilidad de DNS básico en tu clúster, define un número mínimo de réplicas para kube-dns.
La salida de kube-dns-autoscaler
ConfigMap con el campo min
sería similar a la siguiente:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
Siguientes pasos
- Consulta una descripción general de cómo proporciona GKE DNS gestionado.
- 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 usar Cloud DNS para GKE.