/etc/resolv.conf para os pods do Kubernetes, opção ndots: 5, pois isso pode afetar adversamente o desempenho do aplicativo


Há pouco tempo, lançamos o Kubernetes 1.9 na AWS usando o Kops. Ontem, enquanto lançava um novo tráfego sem problemas para o maior de nossos clusters Kubernetes, comecei a perceber erros incomuns de resolução de nomes DNS registrados pelo nosso aplicativo.


O GitHub falou sobre isso por um bom tempo, então eu também decidi descobrir. No final, percebi que, no nosso caso, isso se deve ao aumento da carga no kube-dns e no dnsmasq . O mais interessante e novo para mim foi o motivo de um aumento significativo no tráfego de consultas DNS. Sobre isso e o que fazer com isso, meu post.


A resolução do DNS dentro do contêiner - como em qualquer sistema Linux - é determinada pelo arquivo de configuração /etc/resolv.conf . Por padrão, o Kubernetes dnsPolicy é ClusterFirst , o que significa que qualquer consulta DNS será redirecionada para o dnsmasq em execução na kube-dns dentro do cluster, que, por sua vez, redirecionará a consulta para o aplicativo kube-dns se o nome terminar com um sufixo do cluster ou caso contrário, para um servidor DNS de nível superior.


O arquivo /etc/resolv.conf dentro de cada container terá a seguinte aparência por padrão:


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

Como você pode ver, existem três diretivas:


  1. O servidor de nomes é o serviço IP do kube-dns
  2. 4 domínios de pesquisa local especificados
  3. Há uma opção ndots:5

Uma parte interessante dessa configuração é como os domínios e ndots:5 pesquisa local ndots:5 configurações se dão bem. Para entender isso, você precisa entender como a resolução DNS funciona para nomes parciais.


Qual é o nome completo?


Um nome totalmente qualificado é um nome para o qual nenhuma pesquisa local será realizada e o nome será considerado absoluto durante a resolução do nome. Por convenção, o software DNS considera um nome totalmente qualificado se terminar com um ponto (.). E não é totalmente definido de outra forma. Esse é o google.com. totalmente definido, mas google.com não.


Como é tratado um nome incompleto?


Quando um aplicativo se conecta ao host remoto especificado no nome, a resolução de nomes DNS geralmente é feita usando uma chamada do sistema, por exemplo, getaddrinfo() . Mas se o nome estiver incompleto (não termina com.), Pergunto-me se a chamada do sistema tentará resolver o nome como absoluto primeiro ou se passará pelos domínios de pesquisa local primeiro? Depende da opção ndots .


Do manual no resolv.conf :


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

Isso significa que, se ndots estiver definido como 5 e o nome contiver menos de 5 pontos, a chamada do sistema tentará resolvê-lo sequencialmente, primeiro percorrendo todos os domínios de pesquisa local e, se malsucedido, acabará por resolvê-lo como um nome absoluto.


Por que os ndots:5 podem afetar adversamente o desempenho do aplicativo?


Como você entende, se o seu aplicativo usar muito tráfego externo, para cada conexão TCP estabelecida (ou, mais precisamente, para cada nome resolvido), ele emitirá 5 consultas DNS antes que o nome seja resolvido corretamente, pois passará por 4 primeiro domínio de pesquisa local e, no final, emitirá uma solicitação de resolução de nome absoluta.


O diagrama a seguir mostra o tráfego total em nossos 3 módulos kube-dns antes e depois da troca de vários nomes de host configurados em nosso aplicativo para nomes totalmente definidos.


imagem


O diagrama a seguir mostra o atraso do aplicativo antes e depois da troca de vários nomes de host configurados em nosso aplicativo (a linha azul vertical é a implantação):


imagem


Solução 1 - use nomes totalmente qualificados


Se você tiver poucos nomes externos estáticos (ou seja, definidos na configuração do aplicativo) aos quais você cria um grande número de conexões, talvez a solução mais simples seja trocá-los por nomes totalmente definidos, simplesmente adicionando-os. no final.


Esta não é uma decisão final, mas ajuda a melhorar rapidamente, embora não de forma limpa, a situação. Aplicamos esse patch para resolver nosso problema, cujos resultados foram mostrados nas capturas de tela acima.


Solução # 2 - personalizando ndots no dnsConfig


No Kubernetes 1.9, um recurso apareceu no modo alfa (versão beta v1.10), que permite um melhor controle dos parâmetros DNS através da propriedade pod no dnsConfig . Entre outras coisas, permite ajustar o valor de ndots para uma lareira específica, ou seja,


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

Fontes



Leia também outros artigos em nosso blog:


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


All Articles