Passer au contenu

Comment installer NodeLocalDNS dans mon cluster EKS et résoudre les problèmes ?

Lecture de 9 minute(s)
0

Je souhaite installer NodeLocalDNS dans mon cluster Amazon Elastic Kubernetes Service (Amazon EKS) et résoudre les problèmes.

Résolution

Prérequis :

Installer NodeLocalDNS

NodeLocalDNS utilise une adresse IP link-local pour assurer la mise en cache DNS sur chaque nœud. Les adresses link-local sont des adresses IP comprises dans la plage 169.254.0.0/16 qui ne sont valides que dans le segment réseau.

Remarque : l'adresse IP link-local standard pour NodeLocalDNS est 169.254.20.10. Ne modifiez cette valeur qu’en cas de conflit spécifique dans votre environnement.

Pour installer NodeLocalDNS dans le cluster Amazon EKS, procédez comme suit :

  1. Exécutez la commande curl suivante pour télécharger le manifeste NodeLocalDNS depuis le référentiel Kubernetes :

    curl -Lo nodelocaldns.yaml.template https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml
  2. Pour récupérer l'adresse IP du service kube-dns du cluster, exécutez la commande suivante :

    kubectl get svc kube-dns -n kube-system -o jsonpath='{.spec.clusterIP}'

    Remarque : notez l'adresse IP de la sortie.

  3. Pour récupérer le domaine de cluster, exécutez la commande suivante :

    kubectl get configmap coredns -n kube-system -o yaml | grep 'kubernetes'

    La sortie indique le domaine de cluster.

  4. Pour déterminer le mode kube-proxy, exécutez la commande suivante :

    kubectl get configmap kube-proxy-config -n kube-system -o yaml | grep mode

    La sortie affiche iptables ou ipvs comme valeur de mode.

  5. Modifiez le manifeste NodeLocalDNS en fonction du mode kube-proxy.

    Pour le mode iptables, modifiez le manifeste à l'aide des commandes suivantes :

    # Set environment variables for node-local-dns
    kubedns=$(kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP})
    domain=cluster.local
    localdns=`169.254.20.10`
    
    # Update the manifest with your cluster's specific values:
    sed "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__/$kubedns/g" nodelocaldns.yaml.template > nodelocaldns.yaml

    Remarque : remplacez cluster.local par le domaine de cluster à partir de l'étape 3 si le cluster utilise un domaine différent. Remplacez 169.254.20.10 par l'adresse IP link-local du cluster si elle est différente.

    Pour le mode IPVS, modifiez le manifeste à l'aide des commandes suivantes :

    # Set environment variables for node-local-dns
    kubedns=$(kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP})
    domain=cluster.local
    localdns=169.254.20.10
    
    # Update the manifest with your cluster's specific values:
    sed "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/,__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/$kubedns/g" nodelocaldns.yaml.template > nodelocaldns.yaml

    Remarque : remplacez cluster.local par le domaine de cluster à partir de l'étape 3 si le cluster utilise un domaine différent. Remplacez 169.254.20.10 par l'adresse IP link-local du cluster si elle est différente. En mode IPVS, vous devez configurer les pods afin qu’ils utilisent NodeLocalDNS. Consultez la section « Configurer les pods pour utiliser NodeLocalDNS (mode IPVS uniquement) ».

  6. Pour appliquer le manifeste NodeLocalDNS, exécutez la commande suivante :

    kubectl apply -f nodelocaldns.yaml
  7. Pour vérifier que les pods NodeLocalDNS sont à l’état En cours d'exécution, exécutez la commande suivante :

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

Configurer les pods pour utiliser NodeLocalDNS (mode IPVS uniquement)

Important : cette section s'applique uniquement si le cluster utilise le mode IPVS pour kube-proxy. Si le cluster utilise le mode iptables, le trafic DNS est automatiquement redirigé vers NodeLocalDNS.

Pour les clusters en mode IPVS, vous devez configurer manuellement les pods afin qu’ils utilisent NodeLocalDNS. Pour diriger les pods vers NodeLocalDNS, vous pouvez configurer des pods individuels ou configurer des clusters avec kubelet.

Configurer des pods individuels

Pour configurer des pods individuels, ajoutez la configuration suivante à la spécification de votre pod :

spec:
  dnsPolicy: "None"
  dnsConfig:
    nameservers:
      - [169.254.20.10]
    searches:
      - default.svc.cluster.local
      - svc.cluster.local
      - cluster.local
    options:
      - name: ndots
        value: "5"

Remarque : remplacez 169.254.20.10 par l'adresse IP link-local du cluster. Remplacez cluster.local par le domaine de cluster si celui-ci utilise un autre domaine.

Configurer des clusters avec Kubelet

En mode IPVS, NodeLocalDNS n'écoute que sur l'adresse link-local 169.254.20.10. Vous devez modifier la configuration de kubelet afin qu'il pointe vers cette adresse link-local.

Pour configurer tous les pods du cluster afin qu'ils utilisent NodeLocalDNS et modifier la configuration de kubelet sur chaque nœud, procédez comme suit :

  1. Modifiez le fichier de configuration de kubelet. Utilisez la configuration suivante :

    {  "clusterDNS": ["169.254.20.10"],
      "clusterDomain": "cluster.local"
    }

    Remarque : remplacez 169.254.20.10 par l'adresse IP link-local du cluster. Remplacez cluster.local par le domaine de cluster si celui-ci utilise un autre domaine.

  2. Pour redémarrer le service kubelet sur chaque nœud, exécutez la commande sudo suivante :

    sudo systemctl restart kubelet
  3. Pour vérifier la configuration de kubelet, exécutez la commande suivante :

    cat /etc/kubernetes/kubelet/config.json | grep clusterDNS

    Remarque : la sortie affiche 169.254.20.10 comme adresse IP link-local de NodeLocalDNS.

Remarque : pour un déploiement automatique, vous pouvez modifier la configuration de kubelet dans la section userdata du modèle de lancement. Pour plus d'informations, consultez la section Comment utiliser les données utilisateur personnalisées avec les nœuds Amazon EKS AL2023 ?

Vérifier que vous avez correctement installé NodeLocalDNS

Pour vérifier que NodeLocalDNS fonctionne correctement, procédez comme suit :

  1. Pour créer un pod de test, exécutez la commande suivante :

    kubectl run test-dns --image=busybox:1.28 --restart=Never --rm -it -- nslookup kubernetes.default
  2. Si les pods NodeLocalDNS présentent un statut CrashLoopBackOff avec des erreurs indiquant que le port 53 est déjà utilisé. Puis, examinez le résultat pour confirmer que la requête DNS a été correctement résolue.

  3. Pour vérifier que les requêtes DNS utilisent NodeLocalDNS, exécutez la commande suivante :

    kubectl logs -n kube-system -l k8s-app=node-local-dns --tail=50

    Les journaux indiquent les requêtes DNS traitées par NodeLocalDNS.

    Remarque : par défaut, la journalisation n'est pas activée dans NodeLocalDNS. Pour consulter le journal, activez la journalisation dans la ConfigMap node-local-dns.

    # kubectl edit configmaps -n kube-system node-local-dns
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: node-local-dns
      namespace: kube-system
    data:
      Corefile: |
        cluster.local:53 {
           log  # Enable logging
           errors
           cache 30
           ...
        }

Résoudre les problèmes liés à NodeLocalDNS

Remarque : si des erreurs surviennent lorsque vous exécutez des commandes de l'interface de la ligne de commande AWS (AWS CLI), consultez la section Résoudre des erreurs liées à l’AWS CLI. Vérifiez également que vous utilisez bien la version la plus récente de l'AWS CLI.

Résoudre les erreurs CrashLoopBackoff dues aux conflits de ports

Si les pods NodeLocalDNS passent à CrashLoopBackoff avec des erreurs de port 53, cela signifie que les nœuds en mode automatique Amazon EKS réservent le port 53. Pour résoudre ce problème, choisissez l’une des méthodes suivantes :

Méthode 1 : Ajouter des règles d'affinité de nœud pour exclure les nœuds en mode automatique

Procédez comme suit :

  1. Modifiez le daemonset NodeLocalDNS :

    kubectl edit daemonset node-local-dns -n kube-system
  2. Ajoutez la configuration d'affinité suivante sous spec.template.spec :

    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: eks.amazonaws.com/compute-type
              operator: NotIn
              values:
              - auto
  3. Enregistrez les modifications, puis vérifiez que les pods redémarrent correctement.

Méthode 2 : Modifier la ConfigMap de NodeLocalDNS pour changer le port de surveillance de l'état

Procédez comme suit :

  1. Pour afficher la ConfigMap NodeLocalDNS actuelle, exécutez la commande suivante :

    kubectl get configmap node-local-dns -n kube-system -o yaml
  2. Pour modifier la ConfigMap afin de modifier le port de surveillance de l'état, exécutez la commande suivante :

    kubectl edit configmap node-local-dns -n kube-system
  3. Dans la ConfigMap, localisez la configuration du plug-in d’état et modifiez le port. La structure de la ConfigMap se présente comme suit :

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: node-local-dns
      namespace: kube-system
    data:
      Corefile: |
        cluster.local:53 {
           errors
           cache {
              success 9984 30
              denial 9984 5
           }
           reload
           loop
           bind IP_ADDRESS
           forward. __PILLAR__CLUSTER__DNS__ {
              force_tcp
           }
           prometheus :9253
           health 169.254.20.10:8081
        }

    Remarque : remplacez le port 8081 dans la ligne health par le port souhaité. Remplacez 169.254.20.10 par l'adresse IP link-local du cluster si elle est différente.

  4. Enregistrez les modifications.

  5. Pour redémarrer les pods NodeLocalDNS, exécutez la commande suivante :

    kubectl rollout restart daemonset node-local-dns -n kube-system
  6. Pour mettre à jour la configuration de la surveillance de l'état du daemonset afin qu'elle corresponde au nouveau port, exécutez la commande suivante :

    kubectl edit daemonset node-local-dns -n kube-system
  7. Localisez les sections livenessProbe et readinessProbe, puis mettez à jour le port afin qu'il corresponde au nouveau port de surveillance de l'état.

Résoudre les erreurs de délai d'expiration des requêtes DNS

Si vos pods subissent des délais d'attente pour les requêtes DNS, vérifiez que les groupes de sécurité et l'ACL réseau autorisent le trafic TCP et UDP sur le port 53. Ce trafic est requis pour la communication entre pods.

Procédez comme suit :

  1. Pour identifier les groupes de sécurité associés aux nœuds, exécutez la commande describe-instances de l’AWS CLI suivante :

    aws ec2 describe-instances --filters "Name=tag:eks:cluster-name,Values=YOUR-CLUSTER-NAME" --query "Reservations[*].Instances[*].SecurityGroups[*].[GroupId,GroupName]" --output table

    Remarque : remplacez YOUR-CLUSTER-NAME par le nom du cluster Amazon EKS.

  2. Ouvrez la console Amazon EC2.

  3. Dans le volet de navigation, choisissez Groupes de sécurité.

  4. Sélectionnez le groupe de sécurité identifié à l'étape 1 de cette section.

  5. Choisissez l'onglet Règles entrantes.

  6. Vérifiez que des règles existent pour autoriser le trafic TCP et UDP sur le port 53 à partir de la plage CIDR du pod.
    Remarque : si les règles n'existent pas, choisissez Modifier les règles entrantes. Ajoutez ensuite des règles pour TCP et UDP sur le port 53 avec la source définie sur la plage CIDR de votre pod.

Résoudre les messages d'erreur « Connection refused »

Si le message d'erreur « Connection refused » s'affiche lorsque les pods tentent d'utiliser NodeLocalDNS, vérifiez qu'au moins un pod CoreDNS est en cours d'exécution.

Pour vérifier l'état du pod CoreDNS, exécutez la commande suivante :

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

Si aucun espace CoreDNS n'est en cours d'exécution ou si les pods sont en état d'échec, redémarrez le déploiement de CoreDNS. Pour redémarrer le déploiement, exécutez la commande suivante :

kubectl rollout restart deployment coredns -n kube-system

Pour vérifier que les pods CoreDNS sont en cours d'exécution, exécutez la commande suivante :

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

Une fois les pods CoreDNS exécutés, pour redémarrer le daemonset NodeLocalDNS, exécutez la commande suivante :

kubectl rollout restart daemonset node-local-dns -n kube-system

Informations connexes

Utilisation de CoreDNS pour la découverte de service sur le site Web de Kubernetes

Exécuter kube-proxy en mode IPVS sur le site Web de Kubernetes

Automatiser l'infrastructure de cluster avec le mode automatique EKS

Gérer les modules complémentaires de mise en réseau pour les clusters Amazon EKS

AWS OFFICIELA mis à jour il y a 4 mois