En este documento se describe cómo usar NodeLocal DNSCache para reducir la latencia de búsqueda de DNS y mejorar el rendimiento de tu aplicación en tu clúster de Google Kubernetes Engine (GKE).
NodeLocal DNSCache es un complemento de GKE que mejora el rendimiento del DNS al ejecutar una caché de DNS directamente en cada nodo del clúster como un DaemonSet. Cuando tus pods hacen una solicitud de DNS, la solicitud se dirige primero a la caché local del mismo nodo. Gestionar las solicitudes de forma local reduce significativamente los tiempos medios de búsqueda de DNS y disminuye la carga del proveedor de DNS central de tu clúster, como kube-dns o Cloud DNS para GKE. Para obtener una explicación detallada de la arquitectura de DNS y las ventajas de NodeLocal DNSCache, consulta el artículo Acerca del descubrimiento de servicios.
En los clústeres de GKE Autopilot, NodeLocal DNSCache está habilitado de forma predeterminada y no se puede inhabilitar. En los clústeres estándar de GKE que ejecutan la versión 1.33.1 y posteriores, NodeLocal DNSCache está habilitado de forma predeterminada, pero puedes inhabilitarlo.
Este documento está dirigido a usuarios de GKE, incluidos desarrolladores, administradores y arquitectos. Para obtener más información sobre los roles y las tareas de ejemplo habituales en Google Cloud, consulta Roles y tareas de usuario habituales de GKE Enterprise.
En este documento se da por hecho que conoces los siguientes conceptos:
- Servicio de Kubernetes.
- Servicios multiclúster.
- Información sobre el descubrimiento de servicios
- Acerca de Cloud DNS
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 akube-dns. Los pods node-local-dns usan elkube-dns-upstreamservicio para acceder a los podskube-dns. - 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 en el que se originó 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.
Después de que GKE vuelva a crear los nodos, GKE añade 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 de tabla conntrack. Este comportamiento evita que se pierdan o rechacen conexiones debido al agotamiento de la tabla conntrack y a 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 local y omiten
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
kube-dnsmediante TCP. - NodeLocal DNSCache accede a
upstreamServersystubDomainsmediante 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 DNS es
NXDOMAIN.
- Los pods de NodeLocal DNSCache escuchan en los puertos 53, 9253, 9353 y 8080 de los nodos.
Si ejecutas otro
hostNetworkPod o configuras unhostPortscon esos puertos, NodeLocal DNSCache fallará y se producirán errores de DNS. Los pods de NodeLocal DNSCache no usan el modohostNetworkcuando usan GKE Dataplane V2 y no usan Cloud DNS para GKE. - La caché DNS local solo se ejecuta en los grupos de nodos que ejecutan versiones de GKE 1.15 y posteriores. Si habilitas NodeLocal DNSCache en un clúster con nodos que ejecutan versiones anteriores, los pods de esos nodos usarán
kube-dns.
Antes de empezar
Antes de empezar, asegúrate de que has realizado las siguientes tareas:
- Habilita la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la CLI de gcloud, obtén la versión más reciente ejecutando el comando
gcloud components update. Es posible que las versiones anteriores de la interfaz de línea de comandos de gcloud no admitan la ejecución de los comandos de este documento.
- Asegúrate de que tienes un clúster Autopilot o Standard. Si necesitas uno, crea un clúster de Autopilot. En los clústeres Autopilot, NodeLocal DNSCache está habilitado de forma predeterminada y no se puede anular.
Habilitar NodeLocal DNSCache
En los clústeres estándar, puedes habilitar NodeLocal DNSCache con la CLI de Google Cloud o la consola de Google Cloud .
gcloud
Para habilitar NodeLocal DNSCache en un clúster ya creado, 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.
Consola
Para habilitar NodeLocal DNSCache en un clúster nuevo, sigue estos pasos:
Ve a la página Google Kubernetes Engine en la Google Cloud consola.
Haz clic en el nombre del clúster que quieras modificar.
En Redes, en el campo Proveedor de DNS, haz clic en edit Editar proveedor de DNS.
Selecciona la casilla Habilitar NodeLocal DNSCache.
Haz clic en Guardar cambios.
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-dnspods:
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 node-local-dns Pod por cada nodo que ejecute la versión 1.15 o posterior de GKE.
Inhabilitar NodeLocal DNSCache
Para inhabilitar NodeLocal DNSCache, usa 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 aplicar 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:
Ver la dirección IP del servicio
kube-dns: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.Abre una sesión de shell en tu pod:
kubectl exec -it POD_NAME -- /bin/bashEn la sesión de shell del pod, lee el contenido del archivo
/etc/resolv.conf:cat /etc/resolv.confEl 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-dnspods 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. Para obtener la dirección IP del servicio kube-dns, usa el siguiente comando:
kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
Problemas conocidos
En esta sección se enumeran los problemas conocidos de NodeLocal DNSCache.
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 el campo hostNetwork definido como true y el campo dnsPolicy definido como ClusterFirstWithHostNet no pueden acceder a los back-ends de DNS del clúster. Los registros de DNS pueden contener entradas similares a las siguientes:
dnslookup: 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 los campos dnsPolicy y dnsConfig para los pods hostNetwork:
spec:
dnsPolicy: "None"
dnsConfig:
nameservers:
- KUBE_DNS_UPSTREAM
searches:
- NAMESPACE.svc.cluster.local
- svc.cluster.local
- 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 Google Cloud .KUBE_DNS_UPSTREAM: elClusterIPdel serviciokube-dnsupstream. Puedes obtener este valor con el siguiente comando:kubectl get svc -n kube-system kube-dns-upstream -o jsonpath="{.spec.clusterIP}"
Las solicitudes 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 que tienen habilitado NodeLocal DNSCache, 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 dos segundos. Este problema puede deberse a uno de los siguientes motivos:
- Un problema de conectividad de red subyacente.
- Las consultas de DNS han aumentado significativamente desde la carga de trabajo o desde el escalado vertical del grupo de nodos.
Por lo tanto, los kube-dns pods no pueden gestionar todas las solicitudes a tiempo. La solución alternativa es aumentar el número de réplicas de kube-dns escalando kube-dns.
Escalado vertical kube-dns
Puede usar un valor inferior en el campo nodesPerReplica para asegurarse de que se creen más pods kube-dns mientras se escalan 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 por el gran número de pods kube-dns que monitorizan la API de Kubernetes.
Puedes definir el campo max con 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.
En los clústeres estándar, puedes modificar el número de kube-dns réplicas
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))
Si defines los campos min y max en el ConfigMap, las réplicas estarán limitadas por estos valores. Para aumentar la escala, cambia el valor del campo nodesPerReplica
por un valor más pequeño e incluye un valor en el campo max:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
La 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 no superará los 15, que es el valor de max.kube-dns
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.
El resultado de kube-dns-autoscaler ConfigMap que tiene un campo min definido sería similar al siguiente:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
Siguientes pasos
- Consulta una descripción general sobre 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.