Passer au contenu

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

Lecture de 11 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.

L'objet de service kube-dns résume 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

Remarque : Dans la résolution suivante, la valeur ClusterIP CoreDNS est 10.100.0.10.

Pour vérifier votre configuration DNS, procédez comme suit :

  1. Pour obtenir le ClusterIP de votre service CoreDNS, exécutez la commande suivante :

    kubectl get service kube-dns -n kube-system
  2. Pour vérifier que les points de terminaison DNS sont exposés et pointent vers les pods CoreDNS, exécutez la commande suivante :

    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 que vos groupes de sécurité et votre liste de contrôle d'accès au réseau (ACL réseau) ne bloquent pas les pods lorsqu'ils communiquent avec CoreDNS.

Pour en savoir plus, consultez la section 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 délai d’expiration dans le plan de contrôle. Vérifiez également la présence d'erreurs 403 unauthorized.

Pour obtenir les journaux kube-proxy, exécutez la commande suivante :

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 du pod CoreDNS au moment du problème

Le module complémentaire Amazon EKS CoreDNS ajoute uniquement le quota de 170 Mo à la mémoire du pod CoreDNS. Le pod CoreDNS ne définit pas de quota 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 délai d’expiration du DNS peuvent apparaître dans vos journaux d’application Amazon EKS. Cela est dû au fait que le pod CoreDNS ne dispose pas de ressources de processeur suffisantes pour gérer toutes les requêtes DNS.

Pour vérifier l'utilisation actuelle du processeur et de la mémoire des pods CoreDNS, exécutez la commande suivante :

kubectl top pods -n kube-system -l k8s-app=kube-dns

Pour vérifier l'utilisation actuelle du processeur et de la mémoire des nœuds du cluster Amazon EKS, exécutez la commande suivante :

kubectl top nodes

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

Procédez comme suit :

  1. Pour exécuter des commandes dans vos pods d’application, exécutez la commande suivante :

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

    Remarque : Remplacez your-pod-name par le nom de votre pod.
    La commande précédente vous permet d'accéder à un shell à l'intérieur du pod en cours d'exécution. 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 résoudre ce problème, mettez à jour l'image que vous utilisez dans votre fichier manifeste pod-manifest.yaml avec une autre image. busybox sur le site Web de Docker en est un exemple.

  2. Pour vérifier 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 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 à la valeur 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, Amazon EKS utilise la politique DNS ClusterFirst par défaut. Pour plus d'informations sur la politique DNS de ClusterFirst, consultez la page Politique DNS du 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 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 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. Pour obtenir les points de terminaison kube-dns, exécutez la commande suivante :

    kubectl get endpoints kube-dns -n kube-system
  6. Pour vérifier que votre pod peut utiliser l'adresse IP du pod CoreDNS pour résoudre directement, exécutez la commande suivante dans le shell du pod :

    nslookup kubernetes COREDNS_POD_IP
    nslookup amazon.com COREDNS_POD_IP

    Remarque : Remplacez COREDNS_POD_IP par les adresses IP des points de terminaison kube-dns.

Obtenir des journaux plus détaillés à partir des pods CoreDNS pour déboguer d’autres problèmes

Procédez comme suit :

  1. Pour activer le journal de débogage du pod CoreDNS et ajouter le plug-in de journal au CoreDNS ConfigMap, exécutez la commande suivante :
    kubectl -n kube-system edit configmap coredns
    Remarque : Pour plus d'informations, consultez la page journal sur le site Web de CoreDNS.
  2. Dans l'écran de l'éditeur de sortie de commande, ajoutez la chaîne de journal suivante :
    kind: ConfigMap
    apiVersion: v1
    data:
      Corefile: |
        .:53 {
            log    # Activating 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. Pour vérifier si les journaux CoreDNS échouent ou si le trafic provient du pod d'application, exécutez la commande suivante :
    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 pouvez définir ndots sur la valeur par défaut 5 dans un nom de domaine non complet. Dans ce scénario, 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 d'application :

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

Dans l'exemple de configuration précédent, CoreDNS recherche cinq points dans le domaine demandé. 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 le pod n'a pas trouvé l'enregistrement de domaine. NOERROR signifie que le pod a trouvé avec succès l'enregistrement de domaine.

Chaque domaine de recherche possède le préfixe amazon.com avant d'effectuer le dernier appel sur le domaine absolu qui se trouve à la fin. Un nom de domaine final que vous avez ajouté un point (.) se trouve à la fin un nom de domaine complet. 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 également ajouter un point à la fin du domaine que vous recherchez ou utilisez : Exemple :

nslookup example.com.

Vérifiez les quotas de résolveurs VPC AmazonProvidedDNS

Le résolveur Amazon Virtual Private Cloud (Amazon VPC) peut accepter un quota maximum de 1 024 paquets par seconde pour chaque interface réseau Elastic. Si plusieurs pods CoreDNS se trouvent sur le même nœud, vous pouvez atteindre ce quota 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, consultez la page 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 diagnostiquer les problèmes de résolution DNS, procédez comme suit pour utiliser l'outil tcpdump afin d'effectuer une capture de paquets :

  1. Pour localiser un composant master sur lequel un pod CoreDNS est en cours d'exécution, exécutez la commande suivante :

    kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide
  2. Pour utiliser SSH pour vous connecter au composant master et installer l'outil tcpdump, exécutez la commande suivante :

    sudo yum install tcpdump - y
  3. Pour localiser l'ID de processus CoreDNS Pod sur le composant master, exécutez la commande suivante :

    ps ax | grep coredns
  4. À partir du composant master, exécutez la commande suivante pour effectuer une capture de paquets sur le trafic réseau du pod CoreDNS sur le port UDP 53 :

    sudo nsenter -n -t PID tcpdump udp port 53
  5. À partir d'un terminal distinct, exécutez la commande suivante pour obtenir le service CoreDNS et l'adresse IP du pod :

    kubectl describe svc kube-dns -n kube-system

    Remarque : Notez l'adresse IP du service dans le champ IP et l'adresse IP du pod dans le champ Points de terminaison.

  6. Lancez un pod pour 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. Exécutez la commande suivante pour utiliser l'outil nslookup afin d'effectuer une requête DNS sur le domaine amazon.com :

    nslookup amazon.com

    Pour exécuter explicitement la même requête sur l'adresse IP du service CoreDNS, exécutez la commande suivante :

    nslookup amazon.com COREDNS_SERVICE_IP

    Remarque : Remplacez COREDNS_SERVICE_IP par l'adresse IP de votre service CoreDNS.
    Pour exécuter la requête sur l'adresse IP de chaque pod CoreDNS, exécutez la commande suivante :

    nslookup amazon.com COREDNS_POD_IP

    Remarque : Remplacez COREDNS_POD_IP par l'adresse IP de votre pod CoreDNS. Si vous exécutez plusieurs pods CoreDNS, effectuez plusieurs requêtes. De cette façon, Amazon EKS envoie au moins une requête au pod à partir duquel vous capturez le trafic.

  8. Passez en revue les résultats de capture de paquets.
    Si le pod CoreDNS 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. Vérifiez l'accessibilité du réseau entre les composants master.
    Si vous constatez des délais d'expiration des requêtes DNS sur une adresse IP de pod que vous n'avez pas capturée, effectuez une autre capture de paquets sur le composant master correspondant.
    Pour enregistrer les résultats d'une capture de paquets, ajoutez l'indicateur -w FILE_NAME à la commande tcpdump. L'exemple suivant écrit les résultats dans le fichier 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 OFFICIELA mis à jour il y a un an