/etc/resolv.conf pour les pods Kubernetes, option ndots: 5, car cela peut nuire aux performances de l'application


Il n'y a pas si longtemps, nous avons lancé Kubernetes 1.9 sur AWS à l'aide de Kops. Hier, tout en déployant en douceur un nouveau trafic vers le plus grand de nos clusters Kubernetes, j'ai commencé à remarquer des erreurs de résolution de noms DNS inhabituelles enregistrées par notre application.


GitHub en a parlé pendant un bon moment, j'ai donc également décidé de le comprendre. En fin de compte, j'ai réalisé que dans notre cas, cela est dû à l'augmentation de la charge sur kube-dns et dnsmasq . Le plus intéressant et le plus nouveau pour moi est la raison même d'une augmentation significative du trafic des requêtes DNS. À ce sujet et que faire avec, mon message.


La résolution du DNS à l'intérieur du conteneur - comme avec tout système Linux - est déterminée par le fichier de configuration /etc/resolv.conf . Par défaut, Kubernetes dnsPolicy est ClusterFirst , ce qui signifie que toute requête DNS sera redirigée vers dnsmasq exécuté dans la kube-dns à l'intérieur du cluster, qui à son tour redirigera la requête vers l'application kube-dns si le nom se termine par un suffixe de cluster, ou sinon, vers un serveur DNS de niveau supérieur.


Le fichier /etc/resolv.conf à l'intérieur de chaque conteneur ressemblera à ceci par défaut:


 nameserver 100.64.0.10 search namespace.svc.cluster.local svc.cluster.local cluster.local eu-west-1.compute.internal options ndots:5 

Comme vous pouvez le voir, il existe trois directives:


  1. Le serveur de noms est le service IP de kube-dns
  2. 4 domaines de recherche locaux spécifiés
  3. Il y a une option ndots:5

Une partie intéressante de cette configuration est de savoir comment les domaines de recherche locaux et les ndots:5 paramètres s'entendent. Pour comprendre cela, vous devez comprendre le fonctionnement de la résolution DNS pour les noms partiels.


Quel est le nom complet?


Un nom complet est un nom pour lequel aucune recherche locale ne sera effectuée et le nom sera considéré comme absolu lors de la résolution de nom. Par convention, le logiciel DNS considère qu'un nom est pleinement qualifié s'il se termine par un point (.), Et n'est pas entièrement défini autrement. C'est google.com. entièrement défini, mais pas google.com .


Comment un nom incomplet est-il traité?


Lorsqu'une application se connecte à l'hôte distant spécifié dans le nom, la résolution de nom DNS est généralement effectuée à l'aide d'un appel système, par exemple, getaddrinfo() . Mais si le nom est incomplet (ne se termine pas par.), Je me demande si l'appel système essaiera d'abord de résoudre le nom en absolu, ou passera-t-il d'abord par les domaines de recherche locaux? Cela dépend de l'option ndots .


Depuis le manuel sur resolv.conf :


 ndots:n     ,     ,       .     n  1,  ,      - ,       ,       -   . 

Cela signifie que si ndots est défini sur 5 et que le nom contient moins de 5 points, l'appel système essaiera de le résoudre de manière séquentielle, d'abord en parcourant tous les domaines de recherche locaux et, en cas d'échec, le résoudra éventuellement en tant que nom absolu.


Pourquoi ndots:5 peut- ndots:5 nuire aux performances des applications?


Comme vous le comprenez, si votre application utilise beaucoup de trafic externe, pour chaque connexion TCP établie (ou, plus précisément, pour chaque nom résolu), elle émettra 5 requêtes DNS avant que le nom ne soit résolu correctement, car elle passera par 4 en premier domaine de recherche local, et à la fin émettra une demande de résolution de nom absolue.


Le diagramme suivant montre le trafic total sur nos 3 modules kube-dns avant et après le basculement de plusieurs noms d'hôtes configurés dans notre application vers des noms entièrement définis.


image


Le diagramme suivant montre le délai d'application avant et après le basculement de plusieurs noms d'hôtes configurés dans notre application (la ligne bleue verticale représente le déploiement):


image


Solution # 1 - Utilisez des noms pleinement qualifiés


Si vous avez peu de noms externes statiques (c'est-à-dire définis dans la configuration de l'application) vers lesquels vous créez un grand nombre de connexions, la solution la plus simple consiste peut-être à les passer à des noms entièrement définis en les ajoutant simplement. à la fin.


Ce n'est pas une décision finale, mais cela aide à améliorer rapidement, mais pas proprement, la situation. Nous avons appliqué ce patch pour résoudre notre problème, dont les résultats ont été montrés dans les captures d'écran ci-dessus.


Solution # 2 - Personnalisation des ndots dans dnsConfig


Dans Kubernetes 1.9, une fonctionnalité est apparue en mode alpha (version bêta v1.10), qui permet un meilleur contrôle des paramètres DNS via la propriété pod dans dnsConfig . Entre autres choses, il vous permet d'ajuster la valeur de ndots pour un foyer spécifique, c'est-à-dire


 apiVersion: v1 kind: Pod metadata: namespace: default name: dns-example spec: containers: - name: test image: nginx dnsConfig: options: - name: ndots value: "1" 

Les sources



Lisez également d'autres articles sur notre blog:


Source: https://habr.com/ru/post/fr464371/


All Articles