/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

Onlangs hebben we Kubernetes 1.9 op AWS gelanceerd met behulp van Kops. Gisteren, tijdens een geleidelijke uitrol van nieuwe verkeer naar een van onze grootste Kubernetes-clusters, begon ik ongebruikelijke DNS-resolutiefouten op te merken die door onze applicatie werden gelogd.

Dit is al een tijdje op GitHub besproken, dus besloot ik ook het uit te zoeken. Uiteindelijk ontdekte ik dat dit in ons geval werd veroorzaakt door een verhoogde belasting op kube-dns en dnsmasq. Het meest interessante en nieuwe voor mij was de oorzaak van de aanzienlijke toename van DNS-verkeer. Daarover en wat we daaraan kunnen doen, gaat mijn post.

De DNS-resolutie binnen een container - net als in elk Linux-systeem - wordt bepaald door een configuratiebestand /etc/resolv.conf. Standaard heeft Kubernetes dnsPolicy het ClusterFirst, wat betekent dat elk DNS-verzoek wordt doorgestuurd naar dnsmasq, dat binnen de pod is gestart kube-dns in de cluster, dat het verzoek vervolgens zal doorsturen naar de applicatie kube-dns, als de naam eindigt op de clustersuffix, of anders naar een hoger gelegen DNS-server.

Bestand /etc/resolv.conf Binnen elke container ziet het standaard er als volgt uit:

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

Zoals te zien is, zijn er drie richtlijnen:

  1. De naamserver is het IP-adres van de service kube-dns
  2. Er zijn 4 lokale zoekdomeinen opgegeven search
  3. Er is een optie ndots:5

Een interessant aspect van deze configuratie is hoe de lokale zoekdomeinen en instellingen ndots:5 samenleven. Om dit te begrijpen, is het nodig om te begrijpen hoe DNS-resolutie voor onvolledige namen werkt.

Wat is een volledig naam?

Een volledig gekwalificeerde naam is een naam waarvoor geen lokale zoekopdracht wordt uitgevoerd, en de naam wordt als absoluut beschouwd tijdens de naamresolutie. Volgens afspraak beschouwt DNS-software een naam als volledig gekwalificeerd als deze eindigt op een punt (.), En als niet volledig gekwalificeerd in andere gevallen. Dat wil zeggen, google.com. is volledig gekwalificeerd, en google.com is dat niet.

Hoe wordt een onvolledige naam verwerkt?

Wanneer een applicatie verbinding maakt met een externe host die in de naam is opgegeven, wordt de DNS-resolutie meestal uitgevoerd met een systeemaanroep, zoals getaddrinfo(). Maar als de naam onvolledig is (niet eindigend op .), is het interessant of de systeemaanroep eerst zal proberen de naam als absoluut op te lossen, of dat deze eerst door de lokale zoekdomeinen gaat? Dit hangt af van de optie ndots.

Uit de handleiding voor resolv.conf:

ndots:n

stelt de drempel in voor het aantal punten dat in de naam moet verschijnen voordat er een initiële absolute aanvraag wordt gedaan. De standaardwaarde voor n is 1, wat betekent dat als er enige punten in de naam staan, de naam eerst als absolute naam wordt geprobeerd voordat er elementen van de zoeklijst aan worden toegevoegd.

Dit betekent dat als voor ndots de waarde 5 is ingesteld en de naam minder dan 5 punten bevat, de systeembel wordt geprobeerd deze opeenvolgend te resolven, eerst door alle lokale zoekdomeinen en, in geval van mislukking, uiteindelijk als absolute naam.

Waarom kan ndots:5 een negatieve impact hebben op de prestaties van de applicatie?

Zoals u begrijpt, als uw applicatie veel extern verkeer gebruikt, zal voor elke TCP-verbinding die is ingesteld (of, nauwkeuriger, voor elke opgeloste naam) het 5 DNS-verzoeken genereren voordat de naam correct wordt opgelost, omdat het eerst door 4 lokale zoekdomeinen gaat en uiteindelijk een verzoek voor de oplossing van de absolute naam genereert.

In het volgende diagram wordt het totale verkeer op onze 3 kube-dns-modules weergegeven voor en na het schakelen van een aantal hostnamen die in onze applicatie zijn ingesteld naar volledig gedefinieerde namen.

/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

In het volgende diagram wordt de vertraging van de applicatie weergegeven voor en na het schakelen van een aantal hostnamen die in onze applicatie zijn ingesteld naar volledige namen (de verticale blauwe lijn is de implementatie):

/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

Oplossing #1 - gebruik volledig gedefinieerde namen

Als u weinig statische externe namen heeft (d.w.z. gedefinieerd in de applicatieconfiguratie) waar u een groot aantal verbindingen mee maakt, is het mogelijk de eenvoudigste oplossing om ze op volledig gedefinieerd te schakelen door gewoon aan het einde toe te voegen.

Dit is geen definitieve oplossing, maar helpt snel, zij het niet perfect, om de situatie te verbeteren. Deze patch hebben we toegepast om ons probleem op te lossen, waarvan de resultaten in de bovenstaande screenshots zijn weergegeven.

Oplossing #2 - maatwerk ndots in dnsConfig

In Kubernetes 1.9 werd er in alpha-modus functionaliteit geïntroduceerd (beta-versie v1.10), die beter controle biedt over de DNS-instellingen via de pod-eigenschap in dnsConfig. Onder andere stelt het in staat om de waarde ndots voor een specifieke pod in te stellen, d.w.z.

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

Bronnen

Lees ook andere artikelen op onze blog:

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster