Pesquisa de DNS no Kubernetes

Nota perev. : O problema de DNS no Kubernetes, ou melhor, nas configurações de parâmetros ndots, é surpreendentemente popular e este não é o primeiro ano . Em outro artigo sobre esse tópico, seu autor, engenheiro de DevOps de uma grande corretora na Índia, conta de maneira muito simples e concisa o que é útil saber para colegas que usam o Kubernetes.



Uma das principais vantagens da implantação de aplicativos no Kubernetes é a descoberta contínua de aplicativos. A interação intracluster é bastante simplificada pelo conceito de serviço ( Service ), que é um IP virtual, suportando um conjunto de endereços IP pod'ov. Por exemplo, se um serviçovanillaquiser entrar em contato com o serviçochocolate, ele poderá acessar o IP virtual diretamente parachocolate. Surge a pergunta: para quem, neste caso, resolverá a consulta DNS chocolatee como?

A resolução de nomes DNS é configurada no cluster Kubernetes usando o CoreDNS . O Kubelet registra os pods com o CoreDNS como o servidor de nomes nos arquivos de /etc/resolv.conftodos os pods. Se você olhar para o conteúdo de /etc/resolv.confqualquer pod, será algo como isto:

search hello.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.152.183.10
options ndots:5

Essa configuração é usada pelos clientes DNS para redirecionar solicitações para um servidor DNS. O arquivo resolv.confcontém as seguintes informações:

  • nameserver : o servidor para o qual as consultas DNS serão roteadas. No nosso caso, este é o endereço do serviço CoreDNS;
  • search: . , google.com mrkaran.dev FQDN ( ). , resolver' DNS, (FDQN) , «.», . resolver' . , mrkaran.dev. — (FQDN), mrkaran.dev — ;
  • ndots: ( ). ndots , «» . , DNS-.



Vamos ver o que acontece quando solicitamos mrkaran.devno pod:

$ nslookup mrkaran.dev
Server: 10.152.183.10
Address: 10.152.183.10#53

Non-authoritative answer:
Name: mrkaran.dev
Address: 157.230.35.153
Name: mrkaran.dev
Address: 2400:6180:0:d1::519:6001

Para este experimento, defino o nível de log do CoreDNS como all(o que o torna muito detalhado). Vejamos os registros do pod coredns:

[INFO] 10.1.28.1:35998 - 11131 "A IN mrkaran.dev.hello.svc.cluster.local. udp 53 false 512" NXDOMAIN qr,aa,rd 146 0.000263728s
[INFO] 10.1.28.1:34040 - 36853 "A IN mrkaran.dev.svc.cluster.local. udp 47 false 512" NXDOMAIN qr,aa,rd 140 0.000214201s
[INFO] 10.1.28.1:33468 - 29482 "A IN mrkaran.dev.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.000156107s
[INFO] 10.1.28.1:58471 - 45814 "A IN mrkaran.dev. udp 29 false 512" NOERROR qr,rd,ra 56 0.110263459s
[INFO] 10.1.28.1:54800 - 2463 "AAAA IN mrkaran.dev. udp 29 false 512" NOERROR qr,rd,ra 68 0.145091744s

Fuh. Duas coisas chamam atenção aqui:

  • A solicitação passa por todas as etapas da pesquisa até que a resposta contenha um código NOERROR(os clientes DNS entendem e armazenam como resultado). NXDOMAINsignifica que nenhum registro foi encontrado para esse nome de domínio. Como mrkaran.devnão é um nome FQDN (de acordo com ndots=5), o resolvedor examina o caminho da pesquisa e determina a ordem das consultas;
  • . , /etc/resolv.conf , IPv4 IPv6. , single-request resolv.conf.

: glibc , musl — , Alpine .

ndots


Vamos experimentar um pouco mais ndotse ver como esse parâmetro se comporta. A ideia é simples: ndotsdetermina se o cliente DNS considera o domínio absoluto ou relativo. Por exemplo, como, no caso do google simples, o cliente DNS sabe se esse domínio é absoluto? Se definido ndotscomo 1, o cliente dirá: “Oh, googlenão há um único ponto; Provavelmente examinarei toda a lista de pesquisa. " No entanto, se solicitado google.com, a lista de sufixos será completamente ignorada, porque o nome solicitado atende ao limite ndots(há pelo menos um ponto).

Vamos nos certificar disso:

$ cat /etc/resolv.conf
options ndots:1
$ nslookup mrkaran
Server: 10.152.183.10
Address: 10.152.183.10#53

** server can't find mrkaran: NXDOMAIN

Registros CoreDNS:

[INFO] 10.1.28.1:52495 - 2606 "A IN mrkaran.hello.svc.cluster.local. udp 49 false 512" NXDOMAIN qr,aa,rd 142 0.000524939s
[INFO] 10.1.28.1:59287 - 57522 "A IN mrkaran.svc.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.000368277s
[INFO] 10.1.28.1:53086 - 4863 "A IN mrkaran.cluster.local. udp 39 false 512" NXDOMAIN qr,aa,rd 132 0.000355344s
[INFO] 10.1.28.1:56863 - 41678 "A IN mrkaran. udp 25 false 512" NXDOMAIN qr,rd,ra 100 0.034629206s

Como não há mrkaranum único ponto, a pesquisa foi realizada em toda a lista de sufixos.

Nota: na prática, o valor máximo é ndotslimitado a 15; O padrão Kubernetes é 5.

Aplicação de produção


Se o aplicativo fizer muitas chamadas de rede externas, o DNS poderá se tornar um gargalo no caso de tráfego ativo, porque, ao resolver um nome, muitas consultas desnecessárias são executadas (antes que o sistema atinja a correta). Os aplicativos geralmente não adicionam uma zona raiz aos nomes de domínio, no entanto, isso é um hack. Ou seja, em vez de perguntar api.twitter.com, você pode codificar api.twitter.com.(com um ponto ) no aplicativo, o que solicitará aos clientes DNS que executem pesquisas autorizadas imediatamente no domínio absoluto.

Além disso, a partir da versão Kubernetes 1.14, extensão dnsConfige dnsPolicyconcedeu o status de estável. Assim, ao implantar um pod, você pode diminuir o valorndots, digamos, até 3 (e até 1!). Por esse motivo, cada mensagem dentro do nó precisará incluir um domínio completo. Esse é um dos compromissos clássicos quando você precisa escolher entre desempenho e portabilidade. Parece-me que se preocupar com isso só é necessário se latências ultra-baixas forem vitais para o seu aplicativo, pois os resultados do DNS também são armazenados em cache internamente.

Referências


Pela primeira vez, aprendi sobre esse recurso no K8s-meetup em 25 de janeiro. Houve uma discussão lá, incluindo sobre esse problema.

Aqui estão alguns links para um estudo mais aprofundado:


Nota: Eu escolhi não usar digeste artigo. digadiciona automaticamente um ponto (identificador de zona raiz), tornando o domínio "cheio" (FQDN), sem primeiro executá-lo na lista de pesquisa. Ele escreveu sobre isso em uma das publicações anteriores . No entanto, é bastante surpreendente que, em geral, um sinalizador padrão tenha que ser definido para o comportamento padrão.

Bom DNS'ing! Até logo!

PS do tradutor


Leia também no nosso blog:


All Articles