Si vous exécutez des applications dans des clusters Standard, kube-dns est le fournisseur DNS par défaut qui vous aide à activer la découverte et la communication des services. Ce document explique comment gérer le DNS avec kube-dns, y compris son architecture, sa configuration et les bonnes pratiques pour optimiser la résolution DNS dans votre environnement GKE.
Ce document s'adresse aux développeurs, aux administrateurs et aux architectes chargés de gérer le DNS dans GKE. Pour en savoir plus sur les rôles et les tâches courants dans Google Cloud, consultez Rôles utilisateur et tâches courantes de l'utilisateur dans GKE Enterprise.
Avant de commencer, assurez-vous de maîtriser les services Kubernetes et les concepts généraux de DNS.
Comprendre l'architecture kube-dns
kube-dns fonctionne dans votre cluster GKE pour permettre la résolution DNS entre les pods et les services.
Le schéma suivant montre comment vos pods interagissent avec le service kube-dns :
Composants clés
kube-dns inclut les composants clés suivants :
kube-dnsPods : ces pods exécutent le logiciel serveurkube-dns. Plusieurs répliques de ces pods s'exécutent dans l'espace de nomskube-system. Elles offrent une haute disponibilité et une redondance.- Service
kube-dns: ce service Kubernetes de typeClusterIPregroupe les podskube-dnset les expose en tant que point de terminaison unique et stable.ClusterIPfait office de serveur DNS pour le cluster, que les pods utilisent pour envoyer des requêtes DNS.kube-dnsaccepte jusqu'à 1 000 points de terminaison par service sans adresse IP de cluster. kube-dns-autoscaler: ce pod ajuste le nombre de répliqueskube-dnsen fonction de la taille du cluster, qui inclut le nombre de nœuds et de cœurs de processeur. Cette approche permet de s'assurer quekube-dnspeut gérer différentes charges de requêtes DNS.
Résolution DNS interne
Lorsqu'un pod doit résoudre un nom DNS dans le domaine du cluster, tel que myservice.my-namespace.svc.cluster.local, le processus suivant se produit :
- Configuration DNS du pod : le fichier
kubeletde chaque nœud configure le fichier/etc/resolv.confdu pod. Ce fichier utilise leClusterIPdu service comme serveur de noms.kube-dns - Requête DNS : le pod envoie une requête DNS au service
kube-dns. - Résolution du nom :
kube-dnsreçoit la requête. Il recherche l'adresse IP correspondante dans ses enregistrements DNS internes et répond au pod. - Communication : le pod utilise ensuite l'adresse IP résolue pour communiquer avec le service cible.
Résolution DNS externe
Lorsqu'un pod doit résoudre un nom DNS externe ou un nom qui se trouve en dehors du domaine du cluster, kube-dns agit comme un résolveur récursif. Il transmet la requête aux serveurs DNS en amont configurés dans son fichier ConfigMap. Vous pouvez également configurer des résolveurs personnalisés pour des domaines spécifiques, également appelés domaines de simulation. Cette configuration indique à kube-dns de transférer les requêtes pour ces domaines vers des serveurs DNS spécifiques en amont.
Configurer le DNS de pod
Dans GKE, l'agent kubelet sur chaque nœud configure les paramètres DNS pour les pods qui s'exécutent sur ce nœud.
Configurer le fichier /etc/resolv.conf
Lorsque GKE crée un pod, l'agent kubelet modifie le fichier /etc/resolv.conf du pod. Ce fichier configure le serveur DNS pour la résolution de noms et spécifie les domaines de recherche. Par défaut, kubelet configure le pod pour qu'il utilise le service DNS interne du cluster, kube-dns, comme serveur de noms. Il remplit également les domaines de recherche dans le fichier. Ces domaines de recherche vous permettent d'utiliser des noms non qualifiés dans les requêtes DNS. Par exemple, si un pod interroge myservice, Kubernetes tente d'abord de résoudre myservice.default.svc.cluster.local, puis myservice.svc.cluster.local, puis d'autres domaines de la liste search.
L'exemple suivant montre une configuration /etc/resolv.conf par défaut :
nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local c.my-project-id.internal google.internal
options ndots:5
Ce fichier contient les entrées suivantes :
nameserver: définit leClusterIPdu servicekube-dns.search: définit les domaines de recherche qui sont ajoutés aux noms non qualifiés lors des recherches DNS.options ndots:5: définit le seuil à partir duquel GKE considère qu'un nom est complet. Un nom est considéré comme complet s'il comporte au moins cinq points.
Les pods configurés avec le paramètre hostNetwork: true héritent de leur configuration DNS de l'hôte et n'interrogent pas directement kube-dns.
Personnaliser kube-dns
kube-dns fournit une résolution DNS par défaut robuste. Vous pouvez adapter son comportement à des besoins spécifiques, comme améliorer l'efficacité de la résolution ou utiliser des résolveurs DNS préférés. Les domaines de simulation et les serveurs de noms en amont sont configurés en modifiant le ConfigMap kube-dns dans l'espace de noms kube-system.
Modifier le fichier ConfigMap kube-dns
Pour modifier le ConfigMap kube-dns, procédez comme suit :
Ouvrez le ConfigMap pour le modifier :
kubectl edit configmap kube-dns -n kube-systemDans la section
data, ajoutez les champsstubDomainsetupstreamNameserversà :apiVersion: v1 kind: ConfigMap metadata: labels: addonmanager.kubernetes.io/mode: EnsureExists name: kube-dns namespace: kube-system data: stubDomains: | { "example.com": [ "8.8.8.8", "8.8.4.4" ], "internal": [ # Required if your upstream nameservers can't resolve GKE internal domains "169.254.169.254" # IP of the metadata server ] } upstreamNameservers: | [ "8.8.8.8", # Google Public DNS "1.1.1.1" # Cloudflare DNS ]Enregistrez le ConfigMap.
kube-dnsrecharge automatiquement la configuration.
Domaines de simulation
Les domaines de simulation vous permettent de définir des résolveurs DNS personnalisés pour des domaines spécifiques. Lorsqu'un pod interroge un nom dans ce domaine stub, kube-dns transmet la requête au résolveur spécifié au lieu d'utiliser son mécanisme de résolution par défaut.
Vous incluez une section stubDomains dans le kube-dns ConfigMap.
Cette section spécifie le domaine et les serveurs de noms en amont correspondants.
kube-dns transmet ensuite les requêtes de noms dans ce domaine aux serveurs désignés. Par exemple, vous pouvez acheminer toutes les requêtes DNS pour internal.mycompany.com vers 192.168.0.10 et ajouter "internal.mycompany.com": ["192.168.0.10"] à stubDomains.
Lorsque vous configurez un résolveur personnalisé pour un domaine de simulation, tel que example.com, kube-dns transfère toutes les requêtes de résolution de noms pour ce domaine, y compris les sous-domaines tels que *.example.com, vers les serveurs spécifiés.
Serveurs de noms en amont
Vous pouvez configurer kube-dns pour qu'il utilise des serveurs de noms en amont personnalisés afin de résoudre les noms de domaine externes. Cette configuration indique à kube-dns de transférer toutes les requêtes DNS, à l'exception de celles concernant le domaine interne du cluster (*.cluster.local), vers les serveurs en amont désignés. Il est possible que vos serveurs en amont personnalisés ne puissent pas résoudre les domaines internes tels que metadata.internal et *.google.internal. Si vous activez la fédération d'identité de charge de travail pour GKE ou si vous avez des charges de travail qui dépendent de ces domaines, ajoutez un domaine stub pour internal dans ConfigMap. Utilisez 169.254.169.254, l'adresse IP du serveur de métadonnées, comme résolveur pour ce domaine stub.
Gérer un déploiement kube-dns personnalisé
Dans un cluster GKE standard, kube-dns s'exécute en tant que déploiement. Un déploiement kube-dns personnalisé signifie que vous, en tant qu'administrateur de cluster, pouvez contrôler le déploiement et le personnaliser en fonction de vos besoins, au lieu d'utiliser le déploiement par défaut fourni par GKE.
Motifs de déploiement personnalisé
Envisagez un déploiement kube-dns personnalisé pour les raisons suivantes :
- Allocation des ressources : ajustez les ressources de processeur et de mémoire pour les pods
kube-dnsafin d'optimiser les performances dans les clusters à fort trafic DNS. - Version de l'image : utilisez une version spécifique de l'image
kube-dnsou passez à un autre fournisseur DNS, comme CoreDNS. - Configuration avancée : personnalisez les niveaux de journalisation, les règles de sécurité et le comportement de mise en cache DNS.
Autoscaling pour les déploiements personnalisés
La fonction intégrée kube-dns-autoscaler fonctionne avec le déploiement kube-dns par défaut.
Si vous créez un déploiement kube-dns personnalisé, l'autoscaler intégré ne le gère pas. Par conséquent, vous devez configurer un autoscaler distinct, spécifiquement conçu pour surveiller et ajuster le nombre de répliques de votre déploiement personnalisé.
Cette approche consiste à créer et à déployer votre propre configuration d'autoscaler dans votre cluster.
Lorsque vous gérez un déploiement personnalisé, vous êtes responsable de tous ses composants, comme la mise à jour de l'image de l'autoscaler. L'utilisation de composants obsolètes peut entraîner une dégradation des performances ou des échecs DNS.
Pour obtenir des instructions détaillées sur la configuration et la gestion de votre propre déploiement kube-dns, consultez Configurer un déploiement kube-dns personnalisé.
Résoudre les problèmes
Pour savoir comment résoudre les problèmes liés à kube-dns, consultez les pages suivantes :
- Pour obtenir des conseils sur
kube-dnsdans GKE, consultez Résoudre les problèmes liés àkube-dnsdans GKE. - Pour obtenir des conseils généraux sur l'analyse des problèmes de DNS de Kubernetes, consultez Déboguer la résolution DNS.
Optimiser la résolution DNS
Cette section décrit les problèmes courants et les bonnes pratiques pour gérer le DNS dans GKE.
Limite de domaines de recherche dnsConfig d'un pod
Kubernetes limite le nombre de domaines de recherche DNS à 32. Si vous essayez de définir plus de 32 domaines de recherche dans le dnsConfig d'un pod, le kube-apiserver ne créera pas le pod et affichera une erreur semblable à la suivante :
The Pod "dns-example" is invalid: spec.dnsConfig.searches: Invalid value: []string{"ns1.svc.cluster-domain.example", "my.dns.search.suffix1", "ns2.svc.cluster-domain.example", "my.dns.search.suffix2", "ns3.svc.cluster-domain.example", "my.dns.search.suffix3", "ns4.svc.cluster-domain.example", "my.dns.search.suffix4", "ns5.svc.cluster-domain.example", "my.dns.search.suffix5", "ns6.svc.cluster-domain.example", "my.dns.search.suffix6", "ns7.svc.cluster-domain.example", "my.dns.search.suffix7", "ns8.svc.cluster-domain.example", "my.dns.search.suffix8", "ns9.svc.cluster-domain.example", "my.dns.search.suffix9", "ns10.svc.cluster-domain.example", "my.dns.search.suffix10", "ns11.svc.cluster-domain.example", "my.dns.search.suffix11", "ns12.svc.cluster-domain.example", "my.dns.search.suffix12", "ns13.svc.cluster-domain.example", "my.dns.search.suffix13", "ns14.svc.cluster-domain.example", "my.dns.search.suffix14", "ns15.svc.cluster-domain.example", "my.dns.search.suffix15", "ns16.svc.cluster-domain.example", "my.dns.search.suffix16", "my.dns.search.suffix17"}: must not have more than 32 search paths.
kube-apiserver renvoie ce message d'erreur en réponse à une tentative de création de pod. Pour résoudre ce problème, supprimez les chemins de recherche supplémentaires de la configuration.
Limite nameservers en amont pour kube-dns
kube-dns limite le nombre de valeurs upstreamNameservers à trois. Si vous en définissez plus de trois, Cloud Logging affiche une erreur semblable à la suivante :
Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update
Dans ce cas, kube-dns ignore la configuration upstreamNameservers et continue d'utiliser la configuration valide précédente. Pour résoudre ce problème, supprimez les upstreamNameservers supplémentaires de ConfigMap kube-dns.
Augmenter la capacité de kube-dns
Dans les clusters Standard, vous pouvez utiliser une valeur inférieure pour nodesPerReplica afin de créer davantage de pods kube-dns lorsque les nœuds du cluster évoluent. Nous vous recommandons vivement de définir une valeur explicite pour le champ max afin de vous assurer que la machine virtuelle (VM) du plan de contrôle GKE n'est pas submergée par le grand nombre de pods kube-dns qui surveillent l'API Kubernetes.
Vous pouvez définir la valeur du champ max sur le nombre de nœuds du cluster.
Si le cluster comporte plus de 500 nœuds, définissez la valeur du champ max sur 500.
Vous pouvez modifier le nombre de répliques kube-dns en modifiant le ConfigMap kube-dns-autoscaler.
kubectl edit configmap kube-dns-autoscaler --namespace=kube-system
Le résultat ressemble à ce qui suit :
linear: '{"coresPerReplica":256, "nodesPerReplica":16,"preventSinglePointFailure":true}'
Le nombre d'instances répliquées kube-dns est calculé à l'aide de la formule suivante :
replicas = max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) )
Pour effectuer un scaling à la hausse, réduisez la valeur du champ nodesPerReplica et incluez une valeur pour le champ max.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
Cette configuration crée un pod kube-dns pour chacun des huit nœuds du cluster. Un cluster de 24 nœuds comporte trois instances dupliquées, tandis qu'un cluster de 40 nœuds en comporte cinq. Si le cluster dépasse 120 nœuds, le nombre d'instances dupliquées kube-dns ne dépasse pas 15, qui est la valeur du champ max.
Pour garantir un niveau de disponibilité du DNS de base dans votre cluster, définissez un nombre minimal d'instances dupliquées pour le champ kube-dns.
Le résultat pour kube-dns-autoscaler ConfigMap avec le champ min configuré ressemble à ce qui suit :
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
Améliorer les durées des résolution DNS
Plusieurs facteurs peuvent entraîner une latence élevée avec les résolutions DNS ou des échecs de résolution DNS avec le fournisseur kube-dns par défaut. Les applications peuvent rencontrer ces problèmes sous la forme d'erreurs getaddrinfo EAI_AGAIN, qui indiquent un échec temporaire de la résolution de noms. Voici quelques exemples de causes :
- Résolutions DNS fréquentes dans votre charge de travail.
- Densité de pods élevée par nœud.
- Vous exécutez
kube-dnssur des VM Spot ou préemptives, ce qui peut entraîner des suppressions inattendues de nœuds. - Volume de requêtes élevé qui dépasse la capacité de l'instance
dnsmasqdans le podkube-dns. Une seule instancekube-dnsest limitée à 200 connexions TCP simultanées dans GKE 1.31 et versions ultérieures, et à 20 connexions TCP simultanées dans GKE 1.30 et versions antérieures.
Pour améliorer les durées des résolution DNS :
- Évitez d'exécuter des composants système critiques tels que
kube-dnssur des VM Spot ou préemptives. Créez au moins un pool de nœuds doté de VM standards, mais pas de VM Spot ni de VM préemptives. Utilisez des rejets et des tolérances pour vous assurer que les charges de travail critiques sont planifiées sur ces nœuds fiables. - Activez NodeLocal DNSCache. NodeLocal DNSCache met en cache les réponses DNS directement sur chaque nœud, ce qui réduit la latence et la charge sur le service
kube-dns. Si vous activez NodeLocal DNSCache et que vous utilisez des règles de réseau avec des règles de refus par défaut, ajoutez une règle pour autoriser les charges de travail à envoyer des requêtes DNS aux podsnode-local-dns. - Effectuez un scaling à la hausse de
kube-dns. - Assurez-vous que votre application utilise des fonctions basées sur
dns.resolve*plutôt que surdns.lookup, cardns.lookupest synchrone. - Utilisez des noms de domaine complets, par exemple
https://google.com./au lieu dehttps://google.com/.
Des échecs de résolution DNS peuvent survenir lors des mises à niveau du cluster GKE en raison de mises à niveau simultanées des composants du plan de contrôle, y compris kube-dns.
Ces échecs affectent généralement un faible pourcentage de nœuds. Testez soigneusement les mises à niveau de cluster dans un environnement hors production avant de les appliquer aux clusters de production.
Assurer la visibilité des services
kube-dns ne crée des enregistrements DNS que pour les services qui possèdent des points de terminaison. Si un service ne possède aucun point de terminaison, kube-dns ne crée pas d'enregistrements DNS pour ce service.
Gérer les différences de TTL DNS
Si kube-dns reçoit une réponse DNS d'un résolveur DNS en amont avec une valeur TTL élevée ou infinie, il conserve cette valeur TTL. Ce comportement peut créer un écart entre l'entrée mise en cache et l'adresse IP réelle.
GKE résout ce problème dans des versions spécifiques du plan de contrôle, telles que 1.21.14-gke.9100 et ultérieures, ou 1.22.15-gke.2100 et ultérieures. Ces versions définissent une valeur TTL maximale de 30 secondes pour toute réponse DNS dont la valeur TTL est supérieure. Ce comportement est semblable à celui de NodeLocal DNSCache.
Afficher les métriques kube-dns
Vous pouvez récupérer les métriques sur les requêtes DNS dans votre cluster directement à partir des pods kube-dns.
Recherchez les pods
kube-dnsdans l'espace de nomskube-system:kubectl get pods -n kube-system --selector=k8s-app=kube-dnsLe résultat ressemble à ce qui suit :
NAME READY STATUS RESTARTS AGE kube-dns-548976df6c-98fkd 4/4 Running 0 48m kube-dns-548976df6c-x4xsh 4/4 Running 0 47mChoisissez l'un des pods et configurez le transfert de port pour accéder aux métriques de ce pod :
- Le port
10055expose les métriqueskube-dns. - Le port
10054expose les métriquesdnsmasq.
Remplacez
POD_NAMEpar le nom du pod de votre choix.POD_NAME="kube-dns-548976df6c-98fkd" # Replace with your pod name kubectl port-forward pod/${POD_NAME} -n kube-system 10055:10055 10054:10054Le résultat ressemble à ce qui suit :
Forwarding from 127.0.0.1:10054 -> 10054 Forwarding from 127.0.0.1:10055 -> 10055- Le port
Dans une nouvelle session de terminal, utilisez la commande
curlpour accéder aux points de terminaison des métriques.# Get kube-dns metrics curl http://127.0.0.1:10055/metrics # Get dnsmasq metrics curl http://127.0.0.1:10054/metricsLe résultat doit ressembler à ce qui suit :
kubedns_dnsmasq_errors 0 kubedns_dnsmasq_evictions 0 kubedns_dnsmasq_hits 3.67351e+06 kubedns_dnsmasq_insertions 254114 kubedns_dnsmasq_max_size 1000 kubedns_dnsmasq_misses 3.278166e+06
Étapes suivantes
- Consultez la présentation des services DNS de cluster dans GKE.
- Consultez la page DNS pour les services et les pods pour obtenir une présentation générale de l'utilisation du DNS dans les clusters Kubernetes.
- Découvrez comment configurer NodeLocal DNSCache.
- Découvrez comment configurer un déploiement kube-dns personnalisé.