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 el clúster de Google Kubernetes Engine (GKE).
NodeLocal DNSCache es un complemento de GKE que mejora el rendimiento del DNS ejecutando una caché de DNS directamente en cada nodo del clúster como DaemonSet. Cuando tus Pods realizan una solicitud de DNS, la solicitud primero va a la caché local en el mismo nodo. El procesamiento local de solicitudes reduce significativamente los tiempos promedio de búsqueda de DNS y disminuye la carga en el 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 los beneficios de NodeLocal DNSCache, consulta 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 de GKE Standard que ejecutan la versión 1.33.1 y versiones posteriores, NodeLocal DNSCache está habilitado de forma predeterminada, pero puedes inhabilitarlo.
Este documento está dirigido a los usuarios de GKE, incluidos los desarrolladores, los administradores y los arquitectos. Para obtener más información sobre los roles comunes y las tareas de ejemplo en Google Cloud, consulta Roles de usuario y tareas comunes de GKE Enterprise.
En este documento, se supone que estás familiarizado con lo siguiente:
- Servicio de Kubernetes.
- Services de varios clústeres.
- Acerca del 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 de tu clúster.
Cuando un Pod realiza una solicitud de DNS, la solicitud va 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 caché reenvía la solicitud a uno de los siguientes lugares, según el destino de la consulta:
- kube-dns: Todas las consultas para el dominio DNS del clúster (
cluster.local) se reenvían akube-dns. Los Pods node-local-dns usan el Servicekube-dns-upstreampara acceder a los Podskube-dns. - Dominios de stub personalizados o servidores de nombres ascendentes: 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 existente, GKE vuelve a crear todos los nodos del clúster que ejecutan la versión 1.15 y posteriores de GKE según el proceso de actualización de nodos.
Después de que GKE vuelve a crear los nodos, GKE agrega de forma automática la etiqueta addon.gke.io/node-local-dns-ds-ready=true a los nodos. No debes agregar esta etiqueta a los nodos del clúster de forma manual.
Beneficios de NodeLocal DNSCache
NodeLocal DNSCache proporciona los siguientes beneficios:
- Tiempo de búsqueda de DNS promedio reducido
- Las conexiones desde los Pods a su caché local no crean entradas de tabla conntrack. Este comportamiento evita las conexiones caídas y rechazadas que se producen por el agotamiento de la tabla de Conntrack y las condiciones de carrera.
- Puedes usar NodeLocal DNSCache con Cloud DNS para GKE.
- Las consultas de DNS para URLs externas (URLs que no hacen referencia a recursos de clúster) se reenvían directamente al servidor de metadatos local y omiten
kube-dns. - Las cachés de DNS locales recogen automáticamente los dominios de stub y los servidores de nombres ascendentes que se especifican en la sección Cómo agregar agentes de resolución personalizados para dominios stub.
Requisitos y limitaciones
- NodeLocal DNSCache consume recursos de procesamiento en cada nodo de tu clúster.
- NodeLocal DNSCache no es compatible con los grupos de nodos de Windows Server.
- NodeLocal DNSCache requiere GKE versión 1.15 o superior.
- NodeLocal DNSCache accede a los Pods de
kube-dnsa través de TCP. - NodeLocal DNSCache accede a
upstreamServersystubDomainscon TCP y UDP en las versiones 1.18 o posteriores de GKE. Se debe poder acceder al servidor DNS con TCP y UDP. - Los registros DNS se almacenan en caché durante los siguientes períodos:
- El tiempo de actividad (TTL) del registro o 30 segundos si el TTL es más de 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 en los nodos.
Si ejecutas cualquier otro Pod
hostNetworko configuras unhostPortscon esos puertos, NodeLocal DNSCache falla y se producen 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é de DNS local solo se ejecuta en grupos de nodos que ejecutan la versión 1.15 de GKE y versiones posteriores. Si habilitas NodeLocal DNSCache en un clúster con nodos que ejecutan versiones anteriores, los Pods en esos nodos usan
kube-dns.
Antes de comenzar
Antes de comenzar, asegúrate de haber realizado las siguientes tareas:
- Habilita la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta el comando
gcloud components updatepara obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos que se describen en este documento.
- Asegúrate de tener un clúster de Autopilot o Standard existente. Si necesitas uno, crea un clúster de Autopilot. En el caso de los clústeres de Autopilot, NodeLocal DNSCache está habilitado de forma predeterminada y no se puede anular.
Habilitar NodeLocal DNSCache
Para los clústeres de Standard, puedes habilitar NodeLocal DNSCache con Google Cloud CLI o la consola de Google Cloud .
gcloud
Para habilitar NodeLocal DNSCache en un clúster existente, usa la marca --update-addons con el argumento NodeLocalDNS=ENABLED:
gcloud container clusters update CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--update-addons=NodeLocalDNS=ENABLED
Reemplaza lo siguiente:
CLUSTER_NAME: es el nombre de tu clúster.COMPUTE_LOCATION: la ubicación de Compute Engine para el clúster.
Console
Para habilitar NodeLocal DNSCache en un clúster nuevo, sigue estos pasos:
Ve a la página de Google Kubernetes Engine en la consola de Google Cloud .
Click the name of the cluster you want to modify.
En Herramientas de redes, en el campo Proveedor de DNS, haz clic en edit Editar proveedor de DNS.
Selecciona la casilla de verificación Habilitar NodeLocal DNSCache.
Haz clic en Guardar cambios.
Este cambio requiere volver a crear los nodos, lo que puede causar interrupciones en tus cargas de trabajo en ejecución. Para obtener detalles sobre este cambio específico, busca la fila correspondiente en la tabla de cambios manuales que recrean los nodos con una estrategia de actualización de nodos y respetan las políticas de mantenimiento. Para obtener más información sobre las actualizaciones de nodos, consulta Planificación de interrupciones por actualizaciones de nodos.
Verifica que NodeLocal DNSCache esté habilitado
Para verificar que NodeLocal DNSCache se esté ejecutando, enumera los pods node-local-dns.
kubectl get pods -n kube-system -o wide | grep node-local-dns
El resultado es similar a lo 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 ejecuta 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
Reemplaza lo siguiente:
CLUSTER_NAME: el nombre del clúster que se inhabilitará.COMPUTE_LOCATION: la ubicación de Compute Engine para el clúster.
Este cambio requiere volver a crear los nodos, lo que puede causar interrupciones en tus cargas de trabajo en ejecución. Para obtener detalles sobre este cambio específico, busca la fila correspondiente en la tabla de cambios manuales que recrean los nodos con una estrategia de actualización de nodos y respetan las políticas de mantenimiento. Para obtener más información sobre las actualizaciones de nodos, consulta Planificación de interrupciones por actualizaciones de nodos.
Soluciona problemas de NodeLocal DNSCache
Para obtener información general sobre el diagnóstico de problemas de DNS de Kubernetes, consulta Depuración de la resolución de DNS.
NodeLocal DNSCache no se habilita de inmediato
Cuando habilitas NodeLocal DNSCache en un clúster existente, es posible que GKE no actualice los nodos de inmediato si el clúster tiene una exclusión o un período de mantenimiento configurado. Si deseas obtener más información, consulta Advertencias para los períodos de mantenimiento y recreación de nodos.
Si no quieres esperar, puedes aplicar los cambios a los nodos de forma manual. Para ello, llama al comando gcloud container clusters upgrade y pasa la marca --cluster-version con la misma versión de GKE que el grupo de nodos ya ejecuta. Debes usar Google Cloud CLI para esta solución alternativa.
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:
Como resultado, la dirección IP del servicio kube-dns puede ser diferente de la dirección IP del servidor de nombres que usan tus Pods. Se espera esta diferencia en las direcciones IP, ya que la dirección IP del servidor de nombres 169.254.20.10 es necesaria para que Cloud DNS funcione correctamente.
Para verificar las direcciones IP, ejecuta los siguientes comandos:
Consulta 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 la política 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 Pods node-local-dns envíen consultas de DNS.
Usa una regla ipBlock en tu manifiesto para permitir la comunicación entre tus Pods y kube-dns.
En el siguiente manifiesto, se 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
Reemplaza 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
En esta sección, se enumeran los problemas conocidos de NodeLocal DNSCache.
Tiempo de espera de DNS en ClusterFirstWithHostNet dnsPolicy cuando se usa NodeLocal DNSCache y GKE Dataplane V2
En los clústeres que usan GKE Dataplane V2 y NodeLocal DNSCache, los Pods con el campo hostNetwork establecido en true y el campo dnsPolicy establecido en ClusterFirstWithHostNet no pueden alcanzar los backends de DNS del clúster. Los registros 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 de backend.
Una solución alternativa es configurar 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"
Reemplaza lo siguiente:
NAMESPACE: Es el espacio de nombres del PodhostNetwork.PROJECT_ID: Es el ID de tu proyecto de Google Cloud .KUBE_DNS_UPSTREAM: Es 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 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 con NodeLocal DNSCache 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 de IP del clúster kube-dns-upstream. En este ejemplo, no se recibió la respuesta a una solicitud de DNS desde kube-dns en dos segundos. Este problema podría deberse a uno de los siguientes motivos:
- Un problema de conectividad de red subyacente.
- Aumentos significativos de las consultas de DNS desde la carga de trabajo o desde el escalamiento vertical del grupo de nodos.
Como resultado, los Pods kube-dns existentes no pueden controlar todas las solicitudes a tiempo. La solución alternativa es aumentar la cantidad de réplicas de kube-dns escalando kube-dns.
Escalamiento vertical kube-dns
Puedes usar un valor más bajo para el campo nodesPerReplica para asegurarte de que se creen más Pods de kube-dns a medida que se escalan los nodos del clúster. Recomendamos configurar un valor max explícito para garantizar que la máquina virtual (VM) del plano de control de GKE no se sobrecargue por la gran cantidad de Pods kube-dns que observan la API de Kubernetes.
Puedes configurar el campo max en la cantidad de nodos del clúster. Si el clúster tiene más de 500 nodos, establece el campo max en 500.
En el caso de los clústeres de Standard, puedes modificar la cantidad de réplicas de kube-dns si editas el ConfigMap kube-dns-autoscaler. Esta configuración no es compatible con los clústeres de Autopilot.
kubectl edit configmap kube-dns-autoscaler --namespace=kube-system
El resultado es similar a lo siguiente:
linear: '{"coresPerReplica":256, "nodesPerReplica":16,"preventSinglePointFailure":true}'
La cantidad de réplicas de kube-dns se calcula con 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 escalar verticalmente, cambia el valor del campo nodesPerReplica a un valor más pequeño y, luego, incluye un valor para el campo max:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
La configuración crea un Pod kube-dns 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, la cantidad de réplicas de kube-dns no aumenta más allá de 15, que es el valor de max.
Para garantizar un nivel de referencia de disponibilidad de DNS en tu clúster, establece un recuento mínimo de réplicas para kube-dns.
El resultado del ConfigMap kube-dns-autoscaler que tiene un campo min definido sería similar al siguiente:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
¿Qué sigue?
- Lee una descripción general de cómo GKE proporciona DNS administrado.
- Lee DNS para servicios y Pods para obtener una descripción general de cómo se usa DNS en los clústeres de Kubernetes.
- Aprende a usar Cloud DNS para GKE.