Comment résoudre les problèmes DNS avec Amazon EKS ?

Date de la dernière mise à jour : 21/02/2020

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

Brève description

Les pods s'exécutant à l'intérieur du cluster Amazon EKS utilisent l'adresse IP du cluster du service CoreDNS comme serveur de noms par défaut pour interroger les enregistrements DNS internes et externes. Les applications peuvent échouer aux résolutions DNS en cas de problèmes avec les pods CoreDNS, la configuration du service ou la connectivité.

Les pods CoreDNS sont extraits par un objet de service appelé kube dns. Pour résoudre les problèmes liés à vos pods CoreDNS, vous devez vérifier que tous les composants du service kube dns fonctionnent. Ces composants incluent, sans s'y limiter, les options de point de terminaison de service et les règles iptables.

Solution

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

1.    Pour obtenir l'adresse 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

Le résultat devrait être similaire à celui-ci :

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 le statut des pods CoreDNS.

3.    Vérifiez que les pods ne sont pas bloqués par un groupe de sécurité ou une liste de contrôle d'accès réseau (ACL réseau) lors de la communication avec CoreDNS.

Pour plus d'informations, consultez Pourquoi mes pods ne se connectent-ils pas à d'autres pods dans Amazon EKS ?

Vérifiez que le pod kube-proxy fonctionne

Pour vérifier que le pod kube-proxy a accès aux serveurs d'API de votre cluster EKS, vous pouvez rechercher dans vos journaux les erreurs de dépassement de délai dans le plan de contrôle ou les erreurs 403 non autorisées.

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 du plan de contrôle et crée les règles iptables sur chaque nœud de travail.

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

1.    Pour exécuter des commandes à l'intérieur de vos pods d'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

Votre pod d'application peut ne pas avoir de binaire shell disponible, si vous recevez une erreur similaire à ce qui suit :

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, vous pouvez mettre à jour l'image utilisée dans votre fichier manifeste afin d'utiliser une autre image (par exemple, l'image busybox).

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 à l'intérieur du pod :

cat /etc/resolv.conf

L'exemple resolv.conf suivant montre un pod qui est configuré pour pointer vers 10.100.0.10 pour les demandes DNS. L'adresse IP doit correspondre à l'adresse 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 avec le champ dnsPolicy de la spécification de pod. Si ce champ n'est pas renseigné, lastratégie DNS ClusterFirst est utilisée par défaut.

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

nslookup kubernetes 10.100.0.10

Le résultat devrait être similaire à celui-ci :

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 résoudre un domaine externe à l'aide du clusterIP par défaut, exécutez la commande suivante dans le shell à l'intérieur du pod :

nslookup amazon.com 10.100.0.10

Le résultat devrait être similaire à celui-ci :

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 vérifier que votre pod peut résoudre directement à l'aide de l'adresse IP du pod CoreDNS, exécutez les commandes suivantes dans le shell à 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 de point de terminaison des points de terminaison kubectl get que vous avez utilisés précédemment.

Obtenir des journaux plus détaillés à partir de pods coreDNS pour le débogage

1.    Pour activer le journal de débogage des pods CoreDNS et ajouter le plug-in de journal au ConfigMap CoreDNS, exécutez la commande suivante :

kubectl -n kube-system edit configmap coredns

2.    Dans l'écran de l'éditeur qui s'affiche dans la sortie, ajoutez la chaîne de journal. Reportez-vous à l'exemple suivant :

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 par CoreDNS peut prendre plusieurs minutes. Vous pouvez redémarrer les pods un par un pour appliquer les modifications immédiatement.

3.    Pour vérifier si les journaux CoreDNS échouent ou obtiennent des accès à partir du pod d'application, exécutez la commande suivante :

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

Combinaison Recherche et ndots

DNS utilise le serveur de noms pour les résolutions de noms (généralement l'adresse IP de cluster d'un service kube dns). DNS utilise la recherche pour compléter un nom de requête en nom de domaine complet. Les domaines de recherche pour workerNode sont inclus. La valeur ndots correspond au nombre de points qui doivent apparaître dans un nom pour résoudre une requête avant qu'une requête absolue initiale ne soit effectuée.

Par exemple, vous pouvez définir l'option ndots sur la valeur par défaut 5 dans un nom de domaine qui n'est pas complet. Ensuite, tous les domaines externes qui ne relèvent pas du cluster de domaine interne .local sont ajoutés aux domaines de recherche avant d'interroger

Consultez l'exemple suivant avec le paramètre /etc/resolv.conf du pod d'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 se présentent comme suit :

[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 est introuvable et NOERROR signifie que l'enregistrement de domaine a été trouvé.

Chaque domaine de recherche est précédé d'amazon.com avant d'effectuer l'appel final sur le domaine absolu à la fin. Le nom de domaine final est ajouté avec un point (.) à la fin, ce qui en fait un nom de domaine complet. Cela signifie que pour chaque requête de nom de domaine externe, il peut y avoir quatre à cinq appels supplémentaires, ce qui peut surcharger le pod CoreDNS.

Pour résoudre ce problème, remplacez ndots par 1 (qui recherche uniquement un point unique) ou ajoutez un point (.) à la fin du domaine interrogé ou utilisé.

nslookup example.com.

Soyez conscient des limites du résolveur VPC (AmazonProvidedDNS)

Le résolveur VPC peut accepter uniquement 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 de travail, les chances d'atteindre cette limite sont plus élevées pour les requêtes de domaines 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 :

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

Cet article vous a-t-il été utile ?

Cette page peut-elle être améliorée ?


Vous avez besoin d'aide ?