Ce document a été traduit à l'aide d'une technologie de traduction automatique. Bien que nous nous efforcions de fournir des traductions exactes, nous ne fournissons aucune garantie quant à l'exhaustivité, l'exactitude ou la fiabilité du contenu traduit. En cas de divergence, la version originale anglaise prévaut et fait foi.

DNS

Les commandes/étapes listées sur cette page peuvent être utilisées pour vérifier les problèmes de résolution de noms dans votre cluster.

Assurez-vous d’avoir configuré le bon kubeconfig (par exemple, export KUBECONFIG=$PWD/kube_config_cluster.yml pour Rancher HA) ou d’utiliser le kubectl intégré via l’interface utilisateur.

Avant d’exécuter les vérifications DNS, assurez-vous que le réseau superposé fonctionne correctement pour votre fournisseur DNS, car cela peut également être la raison pour laquelle la résolution DNS échoue (partiellement).

Vérifiez si les pods DNS sont en cours d’exécution

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

Exemple de sortie lors de l’utilisation de CoreDNS :

NAME                       READY   STATUS    RESTARTS   AGE
coredns-799dffd9c4-6jhlz   1/1     Running   0          76m

Exemple de sortie lors de l’utilisation de kube-dns :

NAME                        READY   STATUS    RESTARTS   AGE
kube-dns-5fd74c7488-h6f7n   3/3     Running   0          4m13s

Vérifiez si le service DNS est présent avec le bon cluster-ip

kubectl -n kube-system get svc -l k8s-app=kube-dns
NAME               TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
service/kube-dns   ClusterIP   10.43.0.10   <none>        53/UDP,53/TCP   4m13s

Vérifiez si les noms de domaine se résolvent

Vérifiez si les noms internes du cluster se résolvent (dans cet exemple, kubernetes.default), l’IP affichée après Server: devrait être la même que le CLUSTER-IP du service kube-dns.

kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- nslookup kubernetes.default

Exemple de sortie :

Server:    10.43.0.10
Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes.default
Address 1: 10.43.0.1 kubernetes.default.svc.cluster.local
pod "busybox" deleted

Vérifiez si les noms externes se résolvent (dans cet exemple, www.google.com)

kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- nslookup www.google.com

Exemple de sortie :

Server:    10.43.0.10
Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local

Name:      www.google.com
Address 1: 2a00:1450:4009:80b::2004 lhr35s04-in-x04.1e100.net
Address 2: 216.58.211.100 ams15s32-in-f4.1e100.net
pod "busybox" deleted

Si vous souhaitez vérifier la résolution des noms de domaine sur tous les hôtes, exécutez les étapes suivantes :

  1. Enregistrez le fichier suivant sous ds-dnstest.yml

     apiVersion: apps/v1
     kind: DaemonSet
     metadata:
       name: dnstest
     spec:
       selector:
           matchLabels:
             name: dnstest
       template:
         metadata:
           labels:
             name: dnstest
         spec:
           tolerations:
           - operator: Exists
           containers:
           - image: busybox:1.28
             imagePullPolicy: Always
             name: alpine
             command: ["sleep", "infinity"]
             terminationMessagePath: /dev/termination-log
  2. Lancez-le en utilisant kubectl create -f ds-dnstest.yml

  3. Attendez que kubectl rollout status ds/dnstest -w renvoie : daemon set "dnstest" successfully rolled out.

  4. Configurez la variable d’environnement DOMAIN avec un nom de domaine complet que l’hôte doit être capable de résoudre (nous utilisons www.google.com comme exemple) et exécutez la commande suivante pour permettre à chaque conteneur sur chaque hôte de résoudre le nom de domaine configuré (c’est une commande sur une seule ligne).

     export DOMAIN=www.google.com; echo "=> Start DNS resolve test"; kubectl get pods -l name=dnstest --no-headers -o custom-columns=NAME:.metadata.name,HOSTIP:.status.hostIP | while read pod host; do kubectl exec $pod -- /bin/sh -c "nslookup $DOMAIN > /dev/null 2>&1"; RC=$?; if [ $RC -ne 0 ]; then echo $host cannot resolve $DOMAIN; fi; done; echo "=> End DNS resolve test"
  5. Lorsque cette commande a terminé son exécution, la sortie indiquant que tout est correct est :

     => Start DNS resolve test
     => End DNS resolve test

Si vous voyez une erreur dans la sortie, cela signifie que l’hôte mentionné n’est pas capable de résoudre le nom de domaine complet donné.

Exemple de sortie d’erreur d’une situation où l’hôte avec l’IP 209.97.182.150 avait les ports UDP bloqués.

=> Start DNS resolve test
command terminated with exit code 1
209.97.182.150 cannot resolve www.google.com
=> End DNS resolve test

Nettoyez le DaemonSet alpine en exécutant kubectl delete ds/dnstest.

Spécifique à CoreDNS

Vérifiez la journalisation de CoreDNS

kubectl -n kube-system logs -l k8s-app=kube-dns

Vérifiez la configuration

La configuration de CoreDNS est stockée dans le configmap coredns dans l’espace de noms kube-system.

kubectl -n kube-system get configmap coredns -o go-template={{.data.Corefile}}

Vérifiez les serveurs de noms en amont dans resolv.conf

Par défaut, les serveurs de noms configurés sur l’hôte (dans /etc/resolv.conf) seront utilisés comme serveurs de noms en amont pour CoreDNS. Vous pouvez vérifier ce fichier sur l’hôte ou exécuter le Pod suivant avec dnsPolicy défini sur Default, qui héritera du /etc/resolv.conf de l’hôte sur lequel il s’exécute.

kubectl run -i --restart=Never --rm test-${RANDOM} --image=ubuntu --overrides='{"kind":"Pod", "apiVersion":"v1", "spec": {"dnsPolicy":"Default"}}' -- sh -c 'cat /etc/resolv.conf'

Activer la consignation des requêtes

L’activation de la consignation des requêtes peut être effectuée en activant le plug-in de log dans la configuration du Corefile dans le configmap coredns. Vous pouvez le faire en utilisant kubectl -n kube-system edit configmap coredns ou en utilisant la commande ci-dessous pour remplacer la configuration sur place :

kubectl get configmap -n kube-system coredns -o json | sed -e 's_loadbalance_log\\n    loadbalance_g' | kubectl apply -f -

Toutes les requêtes seront désormais consignées et peuvent être vérifiées en utilisant la commande dans Vérifiez la journalisation de CoreDNS.

Spécifique à kube-dns

Vérifier les serveurs de noms en amont dans le conteneur kubedns

Par défaut, les serveurs de noms configurés sur l’hôte (dans /etc/resolv.conf) seront utilisés comme serveurs de noms en amont pour kube-dns. Parfois, l’hôte exécutera un serveur de noms DNS de mise en cache local, ce qui signifie que l’adresse dans /etc/resolv.conf pointera vers une adresse dans la plage de bouclage (127.0.0.0/8) qui sera inaccessible par le conteneur. Dans le cas d’Ubuntu 18.04, cela se fait par systemd-resolved. Nous détectons si systemd-resolved est en cours d’exécution et utiliserons automatiquement le fichier /etc/resolv.conf avec les serveurs de noms en amont corrects (qui se trouve à /run/systemd/resolve/resolv.conf).

Utilisez la commande suivante pour vérifier les serveurs de noms en amont utilisés par le conteneur kubedns :

kubectl -n kube-system get pods -l k8s-app=kube-dns --no-headers -o custom-columns=NAME:.metadata.name,HOSTIP:.status.hostIP | while read pod host; do echo "Pod ${pod} on host ${host}"; kubectl -n kube-system exec $pod -c kubedns cat /etc/resolv.conf; done

Exemple de sortie :

Pod kube-dns-667c7cb9dd-z4dsf on host x.x.x.x
nameserver 1.1.1.1
nameserver 8.8.4.4

Si la sortie montre une adresse dans la plage de bouclage (127.0.0.0/8), vous pouvez corriger cela de deux manières :

  • Assurez-vous que les serveurs de noms corrects figurent dans /etc/resolv.conf sur vos nœuds du cluster. Veuillez consulter la documentation de votre système d’exploitation pour savoir comment procéder. Assurez-vous d’exécuter cela avant de provisionner un cluster, ou redémarrez les nœuds après avoir effectué la modification.

  • Configurez le kubelet pour utiliser un fichier différent pour la résolution des noms, en utilisant extra_args comme indiqué ci-dessous (où /run/resolvconf/resolv.conf est le fichier avec les serveurs de noms corrects) :

services:
  kubelet:
    extra_args:
      resolv-conf: "/run/resolvconf/resolv.conf"

Comme le kubelet s’exécute à l’intérieur d’un conteneur, les chemins des fichiers situés dans /etc et /usr se trouvent dans /host/etc et /host/usr à l’intérieur du conteneur kubelet.

Voir « Modifier le cluster en YAML » pour savoir comment appliquer ce changement. Lorsque le provisionnement du cluster est terminé, vous devez supprimer le pod kube-dns pour activer le nouveau paramètre dans le pod :

kubectl delete pods -n kube-system -l k8s-app=kube-dns
pod "kube-dns-5fd74c7488-6pwsf" deleted

Essayez de résoudre le nom à nouveau en utilisant Vérifiez si les noms de domaine se résolvent.

Si vous souhaitez vérifier la configuration de kube-dns dans votre cluster (par exemple, pour vérifier s’il y a des serveurs de noms en amont différents configurés), vous pouvez exécuter la commande suivante pour lister la configuration de kube-dns :

kubectl -n kube-system get configmap kube-dns -o go-template='{{range $key, $value := .data}}{{ $key }}{{":"}}{{ $value }}{{"\n"}}{{end}}'

Exemple de sortie :

upstreamNameservers:["1.1.1.1"]