/etc/resolv.conf för Kubernetes-poddar, ndots:5-alternativet, hur detta kan påverka applikationsprestanda negativt

/etc/resolv.conf för Kubernetes-poddar, ndots:5-alternativet, hur detta kan påverka applikationsprestanda negativt

Vi lanserade nyligen Kubernetes 1.9 på AWS med Kops. Igår, medan jag smidigt rullade ut ny trafik till de största av våra Kubernetes-kluster, började jag märka ovanliga DNS-namnupplösningsfel som loggats av vår applikation.

Det finns ganska mycket om detta på GitHub sa, så jag bestämde mig för att ta reda på det också. Till slut insåg jag att i vårt fall beror detta på den ökade belastningen på kube-dns и dnsmasq. Det mest intressanta och nya för mig var själva orsaken till den betydande ökningen av DNS-förfrågningstrafik. Mitt inlägg handlar om detta och vad man ska göra åt det.

DNS-upplösning inuti behållaren - som i alla Linux-system - bestäms av konfigurationsfilen /etc/resolv.conf. Standard Kubernetes dnsPolicy detta ClusterFirst, vilket innebär att alla DNS-begäranden kommer att vidarebefordras till dnsmasq, springer i en pod kube-dns inne i klustret, som i sin tur vidarebefordrar förfrågan till applikationen kube-dns, om namnet slutar med ett klustersuffix, eller på annat sätt till en högre nivå DNS-server.

fil /etc/resolv.conf inuti varje behållare kommer standarden att se ut så här:

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

Som du kan se finns det tre direktiv:

  1. Namnservern är tjänstens IP kube-dns
  2. 4 lokala sökdomäner angivna search
  3. Det finns ett alternativ ndots:5

Den intressanta delen av denna konfiguration är hur de lokala sökdomänerna och inställningarna ndots:5 komma överens. För att förstå detta måste du förstå hur DNS-upplösning för okvalificerade namn fungerar.

Vad är ett fullständigt namn?

Ett fullständigt kvalificerat namn är ett namn för vilket ingen lokal uppslagning kommer att utföras och namnet kommer att betraktas som absolut under namnupplösning. Enligt konventionen anser DNS-programvara att ett namn är fullt kvalificerat om det slutar med en punkt (.), och annars inte är helt kvalificerat. Det är google.com. helt definierad och google.com - Nej.

Hur hanteras ett okvalificerat namn?

När en applikation ansluter till fjärrvärden som anges i namnet, görs DNS-namnupplösning vanligtvis med hjälp av ett systemanrop, t.ex. getaddrinfo(). Men om namnet är okvalificerat (slutar inte med .) undrar jag om systemanropet kommer att försöka lösa namnet som ett absolut namn först, eller gå igenom de lokala sökdomänerna först? Det beror på alternativet ndots.

Från manualen resolv.conf:

ndots:n

устанавливает порог для количества точек, которые должны появиться в имени, прежде чем будет сделан начальный абсолютный запрос. Значение по умолчанию для n равно 1, что означает, что если в имени есть какие-либо точки, имя будет сначала опробовано как абсолютное имя, прежде чем к нему будут добавлены какие-либо элементы списка поиска.

Detta innebär att om för ndots givet ett värde på 5 och namnet innehåller mindre än 5 punkter, kommer systemanropet att försöka lösa det sekventiellt, först passera alla lokala sökdomäner och, om det misslyckas, så löser det så småningom det som ett absolut namn.

Varför då ndots:5 kan det påverka applikationens prestanda negativt?

Som du kan föreställa dig, om din applikation använder mycket extern trafik, för varje upprättad TCP-anslutning (eller mer exakt, för varje löst namn), kommer den att utfärda 5 DNS-frågor innan namnet är korrekt löst, eftersom det först går igenom 4 lokal sökdomän, och kommer i slutet att utfärda en absolut begäran om namnupplösning.

Följande diagram visar den totala trafiken på våra 3 kube-dns-moduler före och efter att vi bytte de få värdnamn som konfigurerats i vår applikation till fullt kvalificerade.

/etc/resolv.conf för Kubernetes-poddar, ndots:5-alternativet, hur detta kan påverka applikationsprestanda negativt

Följande diagram visar programfördröjningen före och efter att vi bytte flera värdnamn som konfigurerats i vår applikation till fullständiga namn (den vertikala blå linjen är distributionen):

/etc/resolv.conf för Kubernetes-poddar, ndots:5-alternativet, hur detta kan påverka applikationsprestanda negativt

Lösning #1 - Använd fullständigt kvalificerade namn

Om du har få statiska externa namn (dvs. definierade i applikationskonfigurationen) som du skapar ett stort antal anslutningar till, är kanske den enklaste lösningen att byta dem till fullt kvalificerade genom att helt enkelt lägga till dem. i slutet.

Detta är inte en slutgiltig lösning, men det hjälper till att snabbt, om än inte rent, förbättra situationen. Vi tillämpade den här patchen för att lösa vårt problem, vars resultat visades i skärmdumparna ovan.

Lösning #2 - anpassning ndots в dnsConfig

I Kubernetes 1.9 dök funktionalitet upp i alfaläge (betaversion v1.10), vilket låter dig bättre kontrollera DNS-parametrar genom pod-egenskapen i dnsConfig. Det låter dig bland annat konfigurera värdet ndots för en specifik pod, dvs.

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

källor

Läs även andra artiklar på vår blogg:

Källa: will.com

Lägg en kommentar