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çovanilla
quiser 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 chocolate
e 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.conf
todos os pods. Se você olhar para o conteúdo de /etc/resolv.conf
qualquer 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.conf
conté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.dev
no pod:$ nslookup mrkaran.dev
Server: 10.152.183.10
Address: 10.152.183.10
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). NXDOMAIN
significa que nenhum registro foi encontrado para esse nome de domínio. Como mrkaran.dev
nã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 ndots
e ver como esse parâmetro se comporta. A ideia é simples: ndots
determina 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 ndots
como 1, o cliente dirá: “Oh, google
nã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
** 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á mrkaran
um único ponto, a pesquisa foi realizada em toda a lista de sufixos.Nota: na prática, o valor máximo é ndots
limitado 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 dnsConfig
e dnsPolicy
concedeu 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 dig
este artigo. dig
adiciona 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: