¿Cómo puedo solucionar los errores de DNS con Amazon EKS?

10 minutos de lectura
0

Las aplicaciones o los pods que utilizan CoreDNS en mi clúster de Amazon Elastic Kubernetes Service (Amazon EKS) no superan las resoluciones de nombres DNS internas o externas.

Breve descripción

Los pods que se ejecutan dentro del clúster de Amazon EKS utilizan la dirección IP del clúster de CoreDNS como servidor de nombres para consultar los registros DNS internos y externos. Si hay problemas con los pods, la configuración del servicio o la conectividad de CoreDNS, puede que las aplicaciones no superen las resoluciones de DNS.

Un objeto de servicio llamado kube-dns aísla los pods de CoreDNS. Para solucionar problemas con sus pods de CoreDNS, compruebe el estado de funcionamiento de todos los componentes del servicio kube-dns, como las opciones de punto de conexión del servicio y las reglas iptables.

Solución

La siguiente solución es aplicable a la IP del clúster (ClusterIP) de CoreDNS 10.100.0.10.

Siga estos pasos:

  1. Obtenga la ClusterIP de su servicio de CoreDNS:

    kubectl get service kube-dns -n kube-system
  2. Compruebe que los puntos de conexión de DNS estén expuestos y señalen a los pods de CoreDNS:

    kubectl -n kube-system get endpoints kube-dns

    Resultado del ejemplo:

    NAME       ENDPOINTS                                                        AGE
    kube-dns   192.168.2.218:53,192.168.3.117:53,192.168.2.218:53 + 1 more...   90d

    Nota: Si la lista de puntos de conexión está en blanco, compruebe el estado de los pods de CoreDNS.

  3. Compruebe que no haya un grupo de seguridad o una lista de control de acceso de la red (ACL de la red) que bloqueen los pods durante la comunicación con CoreDNS.

    Para obtener más información, consulte ¿Por qué mis pods no se conectan a otros pods de Amazon EKS?

Comprobación del funcionamiento del pod kube-proxy

Revise sus registros para ver si hay errores de tiempo de espera en el plano de control para comprobar que el pod kube-proxy tenga acceso a los servidores de la API de su clúster. Además, compruebe si hay errores 403 no autorizados.

Obtenga los registros de kube-proxy:

kubectl logs -n kube-system --selector 'k8s-app=kube-proxy'

Nota: El kube-proxy obtiene los puntos de conexión del plano de control y crea las reglas iptables en cada nodo.

Comprobación del uso de la CPU de los pods de CoreDNS en el momento del problema

El complemento CoreDNS de Amazon EKS añade solo el límite de 170 Mi a la memoria del pod de CoreDNS. El pod de CoreDNS no define un límite de la CPU, por lo que el contenedor puede usar todos los recursos de la CPU disponibles en el nodo en el que se ejecute. Si la utilización de la CPU del nodo alcanza el 100 %, es posible que se muestren errores de tiempo de espera de DNS en los registros de la aplicación de Amazon EKS. Esto se debe a que el pod de CoreDNS no tiene suficientes recursos de CPU para gestionar todas las consultas de DNS.

Conexión al pod de la aplicación para solucionar el problema de DNS

Siga estos pasos:

  1. Para ejecutar comandos dentro de los pods de la aplicación, ejecute el siguiente comando con el fin de acceder a un shell dentro del pod en ejecución:

    $ kubectl exec -it your-pod-name -- sh

    Si el pod de la aplicación no tiene un binario de shell disponible, se mostrará un error similar al siguiente:

    «OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "exec: \"sh\": executable file not found in $PATH»: unknown command terminated with exit code 126

    Para depurarlo, actualice la imagen que se utiliza en su archivo de manifiesto por otra imagen, como la imagen busybox del sitio web de Docker.

  2. Compruebe que la dirección IP del clúster del servicio kube-dns se encuentre en el archivo /etc/resolv.conf del pod. Ejecute el siguiente comando en el shell dentro del pod:

    cat /etc/resolv.conf

    En el siguiente ejemplo, el archivo resolv.conf muestra un pod configurado para señalar a 10.100.0.10 en el caso de las solicitudes de DNS. La dirección IP debe coincidir con la ClusterIP de su servicio kube-dns:

    nameserver 10.100.0.10
    search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal
    options ndots:5

    Nota: Puede administrar la configuración de DNS de su pod con el campo dnsPolicy de la especificación del pod. Si no rellena este campo, se utilizará la política de DNS ClusterFirst de forma predeterminada. Para obtener más información sobre la política de DNS ClusterFirst, consulte Pod's DNS policy en el sitio web de Kubernetes. 

  3. Para comprobar si su pod puede usar la ClusterIP predeterminada para resolver un dominio interno, ejecute el siguiente comando en el shell dentro del pod:

    nslookup kubernetes.default 10.100.0.10

    Resultado del ejemplo:

    Server:     10.100.0.10
    Address:    10.100.0.10#53
    Name:       kubernetes.default.svc.cluster.local
    Address:    10.100.0.1
  4. Para comprobar si su pod puede usar la ClusterIP predeterminada para resolver un dominio externo, ejecute el siguiente comando en el shell dentro del pod:

    nslookup amazon.com 10.100.0.10

    Resultado del ejemplo:

    Server:     10.100.0.10
    Address:    10.100.0.10#53
    Non-authoritative answer:
    Name:   amazon.com
    Address: 176.32.98.166
    Name:    amazon.com
    Address: 205.251.242.103
    Name:    amazon.com
    Address: 176.32.103.205
  5. Compruebe si su pod puede utilizar la dirección IP del pod de CoreDNS para resoluciones directas. Ejecute los siguientes comandos en el shell dentro del pod:

    nslookup kubernetes COREDNS_POD_IP
    
    nslookup amazon.com COREDNS_POD_IP

    Nota: Sustituya COREDNS_POD_IP por una de las direcciones IP de los puntos de conexión de obtención de kubectl.

Obtención de registros más detallados de los pods de CoreDNS para la depuración

Siga estos pasos:

  1. Active el registro de depuración de los pods de CoreDNS y añada el complemento de registro a ConfigMap de CoreDNS:

    kubectl -n kube-system edit configmap coredns

    Nota: Para obtener más información, consulte log plugin en el sitio web de CoreDNS.

  2. En la pantalla del editor que aparece en la salida, añada la cadena de registro:

    kind: ConfigMap
    apiVersion: v1
    data:
      Corefile: |
        .:53 {
            log    # Enabling CoreDNS Logging
            errors
            health
            kubernetes cluster.local in-addr.arpa ip6.arpa {
              pods insecure
              upstream
              fallthrough in-addr.arpa ip6.arpa
            }
            ...
    ...

    Nota: Volver a cargar la configuración de CoreDNS lleva varios minutos. Para aplicar los cambios inmediatamente, reinicie los pods uno por uno.

  3. Compruebe si los registros de CoreDNS fallan o si reciben alguna respuesta del pod de la aplicación:

    kubectl logs --follow -n kube-system --selector 'k8s-app=kube-dns'

Actualización del valor de ndots

El valor de ndots es el número de puntos que deben aparecer en un nombre de dominio para resolver una consulta antes de la consulta absoluta inicial.

Por ejemplo, puede establecer la opción ndots en el valor predeterminado 5 en un nombre de dominio que no esté totalmente cualificado. A continuación, todos los dominios externos que no estén incluidos en el dominio interno cluster.local se anexarán a los dominios de búsqueda antes de realizar la consulta.

El siguiente ejemplo tiene la configuración de archivo /etc/resolv.conf del pod de la aplicación:

nameserver 10.100.0.10
search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal
options ndots:5

CoreDNS busca cinco puntos en el dominio de la consulta. Si el pod realiza una llamada de resolución de DNS para amazon.com, sus registros tendrán un aspecto similar al siguiente:

[INFO] 192.168.3.71:33238 - 36534 "A IN amazon.com.default.svc.cluster.local. udp 54 false 512" NXDOMAIN qr,aa,rd 147 0.000473434s
[INFO] 192.168.3.71:57098 - 43241 "A IN amazon.com.svc.cluster.local. udp 46 false 512" NXDOMAIN qr,aa,rd 139 0.000066171s
[INFO] 192.168.3.71:51937 - 15588 "A IN amazon.com.cluster.local. udp 42 false 512" NXDOMAIN qr,aa,rd 135 0.000137489s
[INFO] 192.168.3.71:52618 - 14916 "A IN amazon.com.ec2.internal. udp 41 false 512" NXDOMAIN qr,rd,ra 41 0.001248388s
[INFO] 192.168.3.71:51298 - 65181 "A IN amazon.com. udp 28 false 512" NOERROR qr,rd,ra 106 0.001711104s

Nota: NXDOMAIN significa que no se encontró el registro de dominio, mientras que NOERROR significa que sí se encontró el registro de dominio.

Cada dominio de búsqueda va precedido de amazon.com antes de realizar la última llamada al dominio absoluto al final. Un nombre de dominio final que se añade con un punto (.) al final es un nombre de dominio totalmente cualificado. Por lo tanto, por cada consulta de nombre de dominio externo puede haber de cuatro a cinco llamadas adicionales, lo que puede sobrecargar el pod de CoreDNS.

Para solucionar este problema, cambie ndots a 1 para buscar solo un punto. También puede añadir un punto (.) al final del dominio que consulte o utilice:

nslookup example.com.

Cumplimiento de los límites del solucionador de VPC (AmazonProvidedDNS)

El solucionador de Amazon Virtual Private Cloud (Amazon VPC) puede aceptar un límite estricto máximo de tan solo 1024 paquetes por segundo por interfaz de red. Si hay más de un pod de CoreDNS en el mismo nodo, las probabilidades de alcanzar este límite son mayores en el caso de las consultas de dominio externo.

Para usar las reglas de PodAntiAffinity con el fin de programar los pods de CoreDNS en instancias distintas, añada las siguientes opciones al despliegue de CoreDNS:

podAntiAffinity:
  preferredDuringSchedulingIgnoredDuringExecution:
  - podAffinityTerm:
      labelSelector:
        matchExpressions:
        - key: k8s-app
          operator: In
          values:
          - kube-dns
      topologyKey: kubernetes.io/hostname
    weight: 100

Nota: Para obtener más información sobre PodAntiAffinity, consulte Inter-pod affinity and anti-affinity en el sitio web de Kubernetes.

Utilización de tcpdump para capturar paquetes de CoreDNS de los nodos de trabajo de Amazon EKS

Utilice la herramienta tcpdump para realizar una captura de paquetes que ayude a diagnosticar problemas de resolución de DNS:

  1. Busque un nodo de trabajo en el que se esté ejecutando un pod de CoreDNS:

    kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide
  2. Utilice SSH para conectarse al nodo de trabajo donde se esté ejecutando un pod de CoreDNS e instale la herramienta tcpdump:

    sudo yum install tcpdump –y
  3. Busque el ID del proceso del pod de CoreDNS en el nodo de trabajo:

    ps ax | grep coredns
  4. Desde el nodo de trabajo, realice una captura de paquetes en la red del pod de CoreDNS para supervisar el tráfico de red en el puerto UDP 53:

    sudo nsenter -n -t PID tcpdump udp port 53
  5. Desde un terminal independiente, obtenga el servicio CoreDNS y la dirección IP del pod:

    kubectl describe svc kube-dns -n kube-system

    Nota: Anote la dirección IP del servicio, que se encuentra en el campo IP, y la dirección IP del pod, que se encuentra en el campo Puntos de conexión.

  6. Inicie un pod para probar el servicio DNS. En el siguiente ejemplo se utiliza una imagen de contenedor de Ubuntu:

    kubectl run ubuntu --image=ubuntu sleep 1d
    
    kubectl exec -it ubuntu sh
  7. Utilice la herramienta nslookup para realizar una consulta de DNS a un dominio, como amazon.com:

    nslookup amazon.com

    Realice la misma consulta de forma explícita con la dirección IP del servicio CoreDNS:

    nslookup amazon.com COREDNS_SERVICE_IP

    Realice la consulta con cada una de las direcciones IP del pod de CoreDNS:

    nslookup amazon.com COREDNS\_POD\_IP

    Nota: Si tiene varios pods de CoreDNS en ejecución, realice varias consultas para que se envíe al menos una consulta al pod desde el que está capturando el tráfico.

  8. Revise los resultados de la captura de paquetes.

    Si el pod de CoreDNS supervisado experimenta tiempos de espera para las consultas de DNS y no ve la consulta en la captura de paquetes, compruebe la conectividad de la red. Asegúrese de comprobar la accesibilidad de la red entre los nodos de trabajo.

    Si observa que se agota el tiempo de espera de una consulta de DNS en relación con una dirección IP de pod que no está capturando, realice otra captura de paquetes en el nodo de trabajo relacionado.

    Para guardar los resultados de una captura de paquetes, añada el marcador -w FILE_NAME al comando tcpdump. En el ejemplo siguiente, los resultados se escriben en un archivo denominado capture.pcap:

    tcpdump -w capture.pcap udp port 53

Información relacionada

CoreDNS GA for Kubernetes cluster DNS

en el sitio web de Kubernetes

OFICIAL DE AWS
OFICIAL DE AWSActualizada hace 6 meses