Comment puis-je corriger les défaillances du DNS avec Amazon EKS ?

Lecture de 10 minute(s)
0

Les applications ou les pods qui utilisent CoreDNS dans mon cluster Amazon Elastic Kubernetes Service (Amazon EKS) échouent aux niveau des résolutions de noms DNS internes ou externes.

Brève description

Les pods qui s'exécutent au sein du cluster Amazon EKS utilisent l'adresse IP du cluster CoreDNS comme serveur de noms pour interroger les enregistrements DNS internes et externes. En cas de problèmes liés aux pods CoreDNS, à la configuration du service ou à la connectivité, les applications peuvent échouer au niveau des résolutions DNS.

Un objet de service appelé kube-dns extrait les pods CoreDNS. Pour résoudre les problèmes liés à vos pods CoreDNS, vérifiez l'état de fonctionnement de tous les composants du service kube-dns tels que les options de point de terminaison du service et les règles iptables.

Résolution

La résolution suivante s'applique au CoreDNS ClusterIP 10.100.0.10.

Procédez comme suit :

  1. Obtenez le ClusterIP de votre service CoreDNS :

    kubectl get service kube-dns -n kube-system
  2. Vérifiez que les points de terminaison DNS sont exposés et pointent vers des pods CoreDNS :

    kubectl -n kube-system get endpoints kube-dns

    Exemple de sortie :

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

    Remarque : si la liste des points de terminaison est vide, vérifiez l'état des pods CoreDNS.

  3. Vérifiez qu'aucun groupe de sécurité ou liste de contrôle d'accès au réseau (ACL réseau) ne bloque les pods lorsqu'ils communiquent avec CoreDNS.

    Pour en savoir plus, reportez-vous à Pourquoi mes pods ne se connectent-ils pas à d'autres pods dans Amazon EKS ?

Vérifier que le pod kube-proxy fonctionne

Pour vérifier que le pod kube-proxy a accès aux serveurs API de votre cluster, consultez vos journaux pour détecter d'éventuelles erreurs de temporisation dans le plan de contrôle. Vérifiez également la présence d'erreurs 403 non autorisées.

Obtenez les journaux de kube-proxy :

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

Remarque : le kube-proxy obtient les points de terminaison depuis le plan de contrôle et crée les règles iptables sur chaque nœud.

Vérifier l'utilisation du processeur des pods CoreDNS au moment du problème

Le module complémentaire Amazon EKS CoreDNS ajoute uniquement la limite de 170 Mo à la mémoire du pod CoreDNS. Le pod CoreDNS ne définit pas de limite de processeur, de sorte que le conteneur peut utiliser toutes les ressources de processeur disponibles sur le nœud sur lequel il s'exécute. Si l'utilisation du processeur du nœud atteint 100 %, des erreurs de temporisation DNS peuvent apparaître dans les journaux de vos applications Amazon EKS. Cela est dû au fait que les ressources processeur du pod CoreDNS ne suffisent pas pour gérer toutes les requêtes DNS.

Se connecter au module d'application pour résoudre le problème de DNS

Procédez comme suit :

  1. Pour exécuter des commandes dans les pods de votre application, exécutez la commande suivante pour accéder à un shell à l'intérieur du pod en cours d'exécution :

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

    Si aucun binaire shell n'est disponible dans le pod d'application, vous recevez un message d'erreur similaire à l'exemple suivant :

    « 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 »

    Pour déboguer, mettez à jour l'image utilisée dans votre fichier manifeste pour une autre image, telle que l'image busyboxsur le site Web de Docker.

  2. Vérifiez que l'adresse IP du cluster du service kube-dns se trouve dans le fichier /etc/resolv.conf de votre pod. Exécutez la commande suivante dans le shell qui se trouve à l'intérieur du pod :

    cat /etc/resolv.conf

    L'exemple de fichier resolv.conf suivant montre un pod configuré pour pointer vers 10.100.0.10 pour les requêtes DNS. L'adresse IP doit correspondre au ClusterIP de votre service kube-dns :

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

    Remarque : vous pouvez gérer la configuration DNS de votre pod à l'aide du champ dnsPolicy dans la spécification du pod. Si vous ne renseignez pas ce champ, la politique DNS ClusterFirst est utilisée par défaut. Pour plus d'informations sur la politique DNS de ClusterFirst, reportez-vous à Politique DNS de pod sur le site Web de Kubernetes.

  3. Pour vérifier que votre pod peut utiliser le ClusterIP par défaut pour résoudre un domaine interne, exécutez la commande suivante dans le shell qui se trouve à l'intérieur du pod :

    nslookup kubernetes.default 10.100.0.10

    Exemple de sortie :

    Server:     10.100.0.10
    Address:    10.100.0.10#53
    Name:       kubernetes.default.svc.cluster.local
    Address:    10.100.0.1
  4. Pour vérifier que votre pod peut utiliser le ClusterIP par défaut pour résoudre un domaine externe, exécutez la commande suivante dans le shell qui se trouve à l'intérieur du pod :

    nslookup amazon.com 10.100.0.10

    Exemple de sortie :

    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. Vérifiez que votre pod peut utiliser l'adresse IP du module CoreDNS pour effectuer une résolution directe. Exécutez les commandes suivantes dans le shell qui se trouve à l'intérieur du pod :

    nslookup kubernetes COREDNS_POD_IP
    
    nslookup amazon.com COREDNS_POD_IP

    Remarque : remplacez COREDNS_POD_IP par l'une des adresses IP des points de terminaison kubectl get.

Obtenir des journaux plus détaillés à partir des pods CoreDNS pour déboguer

Procédez comme suit :

  1. Activez le journal de débogage des pods CoreDNS, puis ajoutez le plug-in de journalisation au CoreDNS ConfigMap :

    kubectl -n kube-system edit configmap coredns

    Remarque : pour plus d'informations, reportez-vous au plug-in de journal sur le site Web de CoreDNS.

  2. Dans l'écran de l'éditeur qui apparaît dans la sortie, ajoutez la chaîne de journal :

    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
            }
            ...
    ...

    Remarque : le rechargement de la configuration CoreDNS prend plusieurs minutes. Pour appliquer immédiatement les modifications, redémarrez les pods un par un.

  3. Vérifiez si les journaux CoreDNS échouent ou si vous obtenez des accès depuis le module de l'application :

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

Mettre à jour la valeur ndots

La valeur ndots est le nombre de points qui doivent apparaître dans un nom de domaine pour résoudre une requête avant la requête absolue initiale.

Par exemple, vous définissez l'option ndots sur la valeur par défaut 5 dans un nom de domaine qui n'est pas entièrement qualifié. Ensuite, tous les domaines externes qui ne font pas partie du domaine interne cluster.local sont ajoutés aux domaines de recherche avant d'être interrogés.

L'exemple suivant présente le paramètre du fichier /etc/resolv.conf du pod de l'application :

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

CoreDNS recherche cinq points dans le domaine interrogé. Si le pod effectue un appel de résolution DNS pour amazon.com, vos journaux ressemblent à l'exemple suivant :

[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

Remarque : NXDOMAIN signifie que l'enregistrement de domaine n'a pas été trouvé et NOERROR signifie que l'enregistrement de domaine a été trouvé.

Chaque domaine de recherche est précédé d'amazon.com avant que le dernier appel ne soit effectué sur le domaine absolu qui se trouve à la fin. Un nom de domaine final auquel est ajouté un point (.) se trouve à la fin un nom de domaine pleinement qualifié. Par conséquent, pour chaque requête de nom de domaine externe, quatre à cinq appels supplémentaires peuvent surcharger le pod CoreDNS.

Pour résoudre ce problème, remplacez ndots par 1 pour ne rechercher qu'un seul point. Vous pouvez aussi choisir d'ajouter un point (.) à la fin du domaine que vous recherchez ou utilisez :

nslookup example.com.

Tenir compte des limites du résolveur (AmazonProvidedDNS) VPC

Le résolveur Amazon Virtual Private Cloud (Amazon VPC) peut accepter une limite stricte maximale de 1 024 paquets par seconde et par interface réseau. Si plusieurs pods CoreDNS se trouvent sur le même nœud, les chances d'atteindre cette limite sont plus élevées pour les requêtes de domaine externes.

Pour utiliser les règles PodAntiAffinity afin de planifier des pods CoreDNS sur des instances distinctes, ajoutez les options suivantes au déploiement CoreDNS :

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

Remarque : Pour plus d'informations sur PodAntiAffinity, reportez-vous à Affinité et anti-affinité inter-pod sur le site Web de Kubernetes.

Utiliser tcpdump pour capturer des paquets CoreDNS depuis les composants master Amazon EKS

Pour vous aider à diagnostiquer les problèmes de résolution DNS, utilisez l'outil tcpdump pour effectuer une capture de paquets :

  1. Localisez le composant master sur lequel un pod CoreDNS est en cours d'exécution :

    kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide
  2. Utilisez SSH pour vous connecter au composant master sur lequel un pod CoreDNS est exécuté, puis installez l'outil tcpdump :

    sudo yum install tcpdump –y
  3. Localisez l'ID de processus du pod CoreDNS sur le composant master :

    ps ax | grep coredns
  4. À partir du composant master, effectuez une capture de paquets sur le réseau du pod CoreDNS pour surveiller le trafic réseau sur le port UDP 53 :

    sudo nsenter -n -t PID tcpdump udp port 53
  5. À partir d'un autre terminal, obtenez le service CoreDNS et l'adresse IP du pod :

    kubectl describe svc kube-dns -n kube-system

    Remarque : notez l'adresse IP du service qui se trouve dans le champ IP et l'adresse IP du pod qui se trouve dans le champ Points de terminaison.

  6. Lancez un pod à partir duquel tester le service DNS. L'exemple suivant utilise une image de conteneur Ubuntu :

    kubectl run ubuntu --image=ubuntu sleep 1d
    
    kubectl exec -it ubuntu sh
  7. Utilisez l'outil nslookup pour lancer une requête DNS sur un domaine, notamment amazon.com :

    nslookup amazon.com

    Lancez explicitement la même requête sur l'adresse IP du service CoreDNS :

    nslookup amazon.com COREDNS_SERVICE_IP

    Lancez la requête sur chacune des adresses IP du pod CoreDNS :

    nslookup amazon.com COREDNS\_POD\_IP

    Remarque : si vous exécutez plusieurs pods CoreDNS, lancez plusieurs requêtes afin qu'au moins une requête soit envoyée au pod dont vous capturez le trafic.

  8. Passez en revue les résultats de capture de paquets.

    Si votre pod CoreDNS surveillé rencontre des problèmes de dépassement des délais d'attente pour les requêtes DNS et que vous ne voyez pas la requête dans la capture de paquets, vérifiez votre connectivité réseau. Assurez-vous de vérifier l'accessibilité du réseau entre les composant master.

    Si vous constatez un problème de dépassement du délai d'attente pour une requête DNS associée à l'adresse IP d'un pod que vous ne capturez pas, lancez une autre capture de paquets sur le composant master associé.

    Pour enregistrer les résultats d'une capture de paquets, ajoutez l'indicateur -w FILE_NAME à la commande tcpdump. L'exemple suivant enregistre les résultats dans un fichier nommé capture.pcap :

    tcpdump -w capture.pcap udp port 53

Informations connexes

CoreDNS GA pour le DNS du cluster Kubernetes

sur le site Web de Kubernetes

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 6 mois