Cette page explique comment améliorer la latence de la résolution DNS dans un cluster Google Kubernetes Engine (GKE) à l'aide de NodeLocal DNSCache.
Pour les clusters GKE Autopilot, NodeLocal DNSCache est activé par défaut et ne peut pas être remplacé.
Architecture
NodeLocal DNSCache est un module complémentaire GKE que vous pouvez exécuter en plus de kube-dns.
GKE implémente NodeLocal DNSCache en tant que DaemonSet qui exécute un cache DNS sur chaque nœud de votre cluster.
Lorsqu'un pod effectue une requête DNS, celle-ci est envoyée au cache DNS exécuté sur le même nœud que le pod. Si le cache ne peut pas résoudre la requête DNS, il la transfère vers l'un des emplacements suivants en fonction de la destination de la requête :
- kube-dns : toutes les requêtes pour le domaine DNS du cluster (
cluster.local
) sont transférées à kube-dns. Les pods node-local-dns utilisent le service kube-dns-upstream pour accéder aux pods kube-dns. Dans le schéma suivant, l'adresse IP du service kube-dns est10.0.0.10:53
. - Domaines de simulation personnalisés ou serveurs de noms en amont : les requêtes sont transférées directement à partir des pods NodeLocal DNSCache.
- Cloud DNS : toutes les autres requêtes sont transférées au serveur de métadonnées local qui s'exécute sur le même nœud que le pod à l'origine de la requête. Le serveur de métadonnées local accède à Cloud DNS.
Lorsque vous activez NodeLocal DNSCache sur un cluster existant, GKE recrée tous les nœuds de cluster exécutant la version 1.15 ou ultérieure de GKE en fonction du processus de mise à niveau des nœuds.
Après avoir recréé les nœuds, GKE ajoute automatiquement l'étiquette addon.gke.io/node-local-dns-ds-ready=true
aux nœuds. Vous ne devez pas ajouter cette étiquette manuellement aux nœuds du cluster.
Avantages de NodeLocal DNSCache
NodeLocal DNSCache offre les avantages suivants :
- Durée moyenne de résolution DNS réduite
- Les correspondances entre les pods et leur cache local ne créent pas d'entrées de table conntrack. Cela évite les correspondances supprimées et rejetées en raison de l'épuisement de la table conntrack et des conditions de concurrence.
- Vous pouvez utiliser NodeLocal DNSCache avec Cloud DNS pour GKE.
- Les requêtes DNS pour les URL externes (URL qui ne font pas référence aux ressources du cluster) sont transmises directement au serveur de métadonnées Cloud DNS local, et contournent ainsi kube-dns.
- Les caches DNS locaux récupèrent automatiquement des domaines de simulation et des serveurs de noms en amont spécifiés dans le fichier ConfigMap de kube-dns.
Conditions requises et limites
- NodeLocal DNSCache consomme des ressources de calcul sur chaque nœud de votre cluster.
- NodeLocal DNSCache n'est pas compatible avec les pools de nœuds Windows Server.
- NodeLocal DNSCache nécessite la version 1.15 ou ultérieure de GKE.
- NodeLocal DNSCache accède aux pods kube-dns via TCP.
- NodeLocal DNSCache accède à
upstreamServers
etstubDomains
à l'aide du protocole TCP et UDP sur GKE version 1.18 ou ultérieure. Le serveur DNS doit être accessible via TCP et UDP. - Les enregistrements DNS sont mis en cache dans les périodes suivantes :
- Valeur TTL (Time To Live) de l'enregistrement, ou 30 secondes si la valeur TTL est supérieure à 30 secondes.
- 5 secondes si la réponse DNS est
NXDOMAIN
.
- Les pods NodeLocal DNSCache écoutent les ports 53, 9253, 9353 et 8080 sur les nœuds. Si vous exécutez un autre pod
hostNetwork
ou configurez unhostPorts
avec ces ports, NodeLocal DNSCache échoue et des erreurs DNS se produisent. Les pods NodeLocal DNSCache n'utilisent pas le modehostNetwork
lors de l'utilisation de GKE Dataplane V2 et de Cloud DNS pour GKE. - Le cache DNS local s'exécute uniquement sur les pools de nœuds exécutant les versions 1.15 et ultérieures de GKE. Si vous activez NodeLocal DNSCache dans un cluster dont certains nœuds exécutent des versions précédentes, les pods sur ces nœuds utilisent kube-dns.
Activer NodeLocal DNSCache
Pour les clusters Autopilot, NodeLocal DNSCache est activé par défaut et ne peut pas être remplacé.
Pour les clusters standards, vous pouvez activer NodeLocal DNSCache sur des clusters nouveaux ou existants à l'aide de Google Cloud CLI. Vous pouvez activer NodeLocal DNSCache dans les nouveaux clusters à l'aide de la console Google Cloud.
gcloud
Activer NodeLocal DNSCache dans un nouveau cluster
Pour activer NodeLocal DNSCache dans un nouveau cluster, utilisez l'option --addons
avec l'argument NodeLocalDNS
:
gcloud container clusters create CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--addons=NodeLocalDNS
Remplacez les éléments suivants :
CLUSTER_NAME
: nom de votre nouveau clusterCOMPUTE_LOCATION
: emplacement Compute Engine du cluster.
Activer NodeLocal DNSCache dans un cluster existant
Pour activer NodeLocal DNSCache dans un cluster existant, utilisez l'option --update-addons
avec l'argument NodeLocalDNS=ENABLED
:
gcloud container clusters update CLUSTER_NAME \
--update-addons=NodeLocalDNS=ENABLED
Remplacez les éléments suivants :
CLUSTER_NAME
: nom du cluster
Console
Pour activer NodeLocal DNSCache sur un nouveau cluster, procédez comme suit :
Accédez à la page Google Kubernetes Engine dans Google Cloud Console.
À côté de "Standard", cliquez sur Configurer.
Configurez le cluster comme vous le souhaitez.
Dans le volet de navigation, cliquez sur Mise en réseau.
Dans la section Options de mise en réseau avancées, cochez la case Activer NodeLocal DNSCache.
Cliquez sur Créer.
Vérifier que NodeLocal DNSCache est activé
Vous pouvez vérifier que NodeLocal DNSCache est en cours d'exécution en répertoriant les pods node-local-dns
.
kubectl get pods -n kube-system -o wide | grep node-local-dns
Le résultat ressemble à ce qui suit :
node-local-dns-869mt 1/1 Running 0 6m24s 10.128.0.35 gke-test-pool-69efb6b8-5d7m <none> <none>
node-local-dns-htx4w 1/1 Running 0 6m24s 10.128.0.36 gke-test-pool-69efb6b8-wssk <none> <none>
node-local-dns-v5njk 1/1 Running 0 6m24s 10.128.0.33 gke-test-pool-69efb6b8-bhz3 <none> <none>
Le résultat affiche un pod node-local-dns
pour chaque nœud exécutant la version 1.15 ou une version ultérieure de GKE.
Désactiver NodeLocal DNSCache
Vous pouvez désactiver NodeLocal DNSCache à l'aide de la commande suivante :
gcloud container clusters update CLUSTER_NAME \
--update-addons=NodeLocalDNS=DISABLED
Remplacez les éléments suivants :
CLUSTER_NAME
: nom du cluster à désactiver
Résoudre les problèmes liés à NodeLocal DNSCache
Pour obtenir des informations générales sur l'analyse des problèmes de DNS de Kubernetes, consultez la section Déboguer la résolution DNS.
NodeLocal DNSCache n'est pas activé immédiatement
Lorsque vous activez NodeLocal DNSCache sur un cluster existant, GKE peut ne pas mettre à jour immédiatement les nœuds si le cluster dispose d'une exclusion ou d'un intervalle de maintenance configuré. Pour en savoir plus, consultez la section Mise en garde à propos des intervalles de recréation et de maintenance des nœuds.
Pour éviter d'attendre, vous pouvez appliquer manuellement les modifications aux nœuds en appelant la commande gcloud container clusters upgrade
et en transmettant l'argument --cluster-version
avec la même version de GKE que celle exécutée par le pool de nœuds. Vous devez utiliser Google Cloud CLI pour contourner ce problème.
NodeLocal DNSCache avec Cloud DNS
Si vous utilisez NodeLocal DNSCache avec Cloud DNS, le cluster utilise l'adresse IP du serveur de noms 169.254.20.10
, comme indiqué dans le schéma suivant :
Par conséquent, l'adresse IP du service kube-dns
peut être différente de l'adresse IP du serveur de noms utilisé par vos pods. Cette différence d'adresses IP est attendue, car l'adresse IP du serveur de noms 169.254.20.10
est requise pour que Cloud DNS fonctionne correctement.
Pour vérifier les adresses IP, exécutez les commandes suivantes :
Affichez l'adresse IP du service
kube-dns
:kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
Le résultat correspond à l'adresse IP de
kube-dns
, par exemple10.0.0.10:53
.Ouvrez une session shell dans le pod :
kubectl exec -it POD_NAME -- /bin/bash
Dans la session shell du pod, lisez le contenu du fichier
/etc/resolv.conf
:cat /etc/resolv.conf
Le résultat est
169.254.20.10
.
Règle de réseau avec NodeLocal DNSCache
Si vous utilisez une règle de réseau avec NodeLocal DNSCache, et que vous n'utilisez pas Cloud DNS ou GKE Dataplane V2, vous devez configurer des règles pour autoriser vos charges de travail et les pods node-local-dns
à envoyer des requêtes DNS.
Utilisez une règle ipBlock
dans votre fichier manifeste pour autoriser la communication entre les pods et kube-dns.
Le fichier manifeste suivant décrit une règle de réseau qui utilise une règle ipBlock
:
spec:
egress:
- ports:
- port: 53
protocol: TCP
- port: 53
protocol: UDP
to:
- ipBlock:
cidr: KUBE_DNS_SVC_CLUSTER_IP/32
podSelector: {}
policyTypes:
- Egress
Remplacez KUBE_DNS_SVC_CLUSTER_IP
par l'adresse IP du service kube-dns. Vous pouvez obtenir l'adresse IP du service kube-dns à l'aide de la commande suivante :
kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
Problèmes connus
Délai avant expiration DNS dans ClusterFirstWithHostNet dnsPolicy lors de l'utilisation de NodeLocal DNSCache et GKE Dataplane V2
Sur les clusters utilisant GKE Dataplane V2 et NodeLocal DNSCache, les pods avec hostNetwork
définis sur true
et dnsPolicy
définis sur ClusterFirstWithHostNet
ne peuvent pas atteindre les backends DNS de cluster. Les journaux DNS peuvent contenir des entrées semblables à ce qui suit :
nslookup: write to 'a.b.c.d': Operation not permitted
;; connection timed out; no servers could be reached
Le résultat indique que les requêtes DNS ne peuvent pas atteindre les serveurs de backend.
Pour contourner ce problème, définissez les valeurs dnsPolicy
et dnsConfig
pour les pods hostNetwork
:
spec:
dnsPolicy: "None"
dnsConfig:
nameservers:
- KUBE_DNS_UPSTREAM
searches:
- cluster.local
- svc.cluster.local
- NAMESPACE.svc.cluster.local
- c.PROJECT_ID.internal
- google.internal
options:
- name: ndots
value: "5"
Remplacez les éléments suivants :
NAMESPACE
: espace de noms du podhostNetwork
.PROJECT_ID
: ID de votre projet Google CloudKUBE_DNS_UPSTREAM
: adresse IP de cluster du service kube-dns en amont. Vous pouvez obtenir cette valeur à l'aide de la commande suivante :kubectl get svc -n kube-system kube-dns-upstream -o jsonpath="{.spec.clusterIP}"
Les requêtes DNS du pod peuvent désormais atteindre kube-dns et contourner NodeLocal DNSCache.
Erreurs de délai avant expiration de NodeLocal DNSCache
Sur les clusters sur lesquels NodeLocal DNSCache est activé, les journaux peuvent contenir des entrées semblables à ce qui suit :
[ERROR] plugin/errors: 2 <hostname> A: read tcp <node IP: port>-><kubedns IP>:53: i/o timeout
Le résultat inclut l'adresse IP du service IP du cluster kube-dns-upstream
. Dans cet exemple, la réponse à une requête DNS n'a pas été reçue par kube-dns après deux secondes. Cela peut être dû à l'une des raisons suivantes :
- un problème de connectivité réseau sous-jacent
- Augmentation considérable des requêtes DNS de la charge de travail ou scaling à la hausse du pool de nœuds
Par conséquent, les pods kube-dns
existants ne peuvent pas traiter toutes les requêtes à temps. La solution consiste à augmenter le nombre d'instances répliquées kube-dns en ajustant les paramètres d'autoscaling.
Faire évoluer kube-dns à la hausse
Vous pouvez utiliser une valeur inférieure pour nodesPerReplica
, afin de vous assurer de la création d'un plus grand nombre de pods kube-dns au fur et à mesure du scaling à la hausse des nœuds du cluster. Nous vous recommandons vivement de définir une valeur max
explicite pour vous assurer que la machine virtuelle (VM) du plan de contrôle GKE n'est pas submergée par un grand nombre de pods kube-dns qui surveillent l'API Kubernetes.
Vous pouvez définir max
sur le nombre de nœuds du cluster. Si le cluster comporte plus de 500 nœuds, définissez max
sur 500.
Pour les clusters standards, vous pouvez modifier le nombre d'instances dupliquées kube-dns en modifiant le fichier ConfigMap kube-dns-autoscaler
. Cette configuration n'est pas compatible avec les clusters Autopilot.
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 dupliquées de kube-dns est calculé à l'aide de la formule suivante :
replicas = max( ceil( cores × 1/coresPerReplica ) , ceil( nodes × 1/nodesPerReplica ), maxValue )
Pour effectuer un scaling à la hausse, réduisez la valeur de nodesPerReplica
et incluez une valeur 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 aura trois instances dupliquées et un cluster de 40 nœuds en aura cinq. Si le cluster dépasse 120 nœuds, le nombre d'instances dupliquées kube-dns ne dépasse pas 15, la valeur max
.
Pour garantir un niveau de disponibilité du DNS de base dans votre cluster, définissez un nombre minimal d'instances dupliquées pour kube-dns.
Une sortie de ConfigMap kube-dns-autoscaler
avec le champ min
ressemblerait à ce qui suit :
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
Étape suivante
- Consultez une présentation de la façon dont GKE fournit le DNS géré.
- 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 utiliser Cloud DNS pour GKE.