Esta página explica como melhorar a latência de procura de DNS num cluster do Google Kubernetes Engine (GKE) através da utilização de NodeLocal DNSCache.
Para clusters do GKE Autopilot, o NodeLocal DNSCache está ativado por predefinição e não pode ser substituído.
Arquitetura
O NodeLocal DNSCache é um suplemento do GKE que pode executar além do kube-dns.
O GKE implementa o NodeLocal DNSCache como um DaemonSet que executa uma cache DNS em cada nó no seu cluster.
Quando um Pod faz um pedido DNS, o pedido é enviado para a cache DNS em execução no mesmo nó que o Pod. Se a cache não conseguir resolver o pedido DNS, encaminha o pedido para um dos seguintes locais com base no destino da consulta:
- kube-dns: todas as consultas para o domínio DNS do cluster (
cluster.local) são encaminhadas para o kube-dns. Os pods node-local-dns usam o serviço kube-dns-upstream para aceder aos pods kube-dns. No diagrama seguinte, o endereço IP do serviço kube-dns é10.0.0.10:53. - Domínios stub personalizados ou servidores de nomes a montante: as consultas são encaminhadas diretamente dos pods DNSCache locais do nó.
- Cloud DNS: todas as outras consultas são encaminhadas para o servidor de metadados local que é executado no mesmo nó que o pod de onde a consulta se originou. O servidor de metadados local acede ao Cloud DNS.
Quando ativa o NodeLocal DNSCache num cluster existente, o GKE recria todos os nós do cluster que executam a versão 1.15 e posterior do GKE de acordo com o processo de atualização de nós.
Depois de o GKE recriar os nós, o GKE adiciona automaticamente a etiqueta addon.gke.io/node-local-dns-ds-ready=true aos nós. Não
deve adicionar esta etiqueta aos nós do cluster manualmente.
Vantagens da NodeLocal DNSCache
A NodeLocal DNSCache oferece as seguintes vantagens:
- Tempo médio de pesquisa de DNS reduzido
- As ligações dos Pods à respetiva cache local não criam entradas na tabela conntrack. Isto evita ligações rejeitadas e interrompidas causadas por condições de corrida e esgotamento da tabela de conntrack.
- Pode usar o NodeLocal DNSCache com o Cloud DNS para GKE.
- As consultas DNS para URLs externos (URLs que não se referem a recursos do cluster) são encaminhadas diretamente para o servidor de metadados do Cloud DNS local, ignorando o kube-dns.
- As caches DNS locais selecionam automaticamente domínios stub e servidores de nomes a montante especificados na secção Adicionar resolvedores personalizados para domínios stub.
Requisitos e limitações
- O NodeLocal DNSCache consome recursos de computação em cada nó do cluster.
- O NodeLocal DNSCache não é suportado com pools de nós do Windows Server.
- O NodeLocal DNSCache requer a versão 1.15 ou posterior do GKE.
- O NodeLocal DNSCache acede aos pods kube-dns através de TCP.
- O NodeLocal DNSCache acede a
upstreamServersestubDomainsatravés de TCP e UDP nas versões 1.18 ou posteriores do GKE. O servidor DNS tem de estar acessível através de TCP e UDP. - Os registos de DNS são colocados em cache durante os seguintes períodos:
- O tempo de vida (TTL) do registo ou 30 segundos se o TTL for superior a 30 segundos.
- 5 segundos se a resposta de DNS for
NXDOMAIN.
- Os pods NodeLocal DNSCache ouvem nas portas 53, 9253, 9353 e 8080 nos nós. Se executar qualquer outro
hostNetworkpodhostNetworkou configurar umhostPortscom essas portas, o NodeLocal DNSCache falha e ocorrem erros de DNS. Os pods NodeLocal DNSCache não usam o modohostNetworkquando usam o GKE Dataplane V2 e não usam o Cloud DNS para GKE. - A cache DNS local só é executada em conjuntos de nós com versões do GKE 1.15 e posteriores. Se ativar a NodeLocal DNSCache num cluster com nós que executam versões anteriores, os pods nesses nós usam o kube-dns.
Antes de começar
Antes de começar, certifique-se de que realizou as seguintes tarefas:
- Ative a API Google Kubernetes Engine. Ative a API Google Kubernetes Engine
- Se quiser usar a CLI gcloud para esta tarefa,
instale-a e, em seguida,
inicialize-a. Se instalou anteriormente a CLI gcloud, execute o comando
gcloud components updatepara obter a versão mais recente. As versões anteriores da CLI gcloud podem não suportar a execução dos comandos neste documento.
- Certifique-se de que tem um cluster do Autopilot ou Standard existente. Se precisar de um, crie um cluster do Autopilot. Para os clusters do Autopilot, o NodeLocal DNSCache está ativado por predefinição e não pode ser substituído.
Ative a NodeLocal DNSCache
Para clusters padrão, pode ativar a NodeLocal DNSCache através da CLI Google Cloud ou da Cloud de Confiance consola.
gcloud
Para ativar o NodeLocal DNSCache num cluster existente, use a flag --update-addons com o argumento NodeLocalDNS=ENABLED:
gcloud container clusters update CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--update-addons=NodeLocalDNS=ENABLED
Substitua o seguinte:
CLUSTER_NAME: o nome do cluster.COMPUTE_LOCATION: a localização do Compute Engine para o cluster.
Consola
Para ativar a NodeLocal DNSCache num novo cluster, siga estes passos:
Aceda à página do Google Kubernetes Engine na Cloud de Confiance consola.
Clique no nome do cluster que quer modificar.
Em Networking, no campo DNS provider, clique em edit Edit DNS provider.
Selecione a caixa de verificação Ativar NodeLocal DNSCache.
Clique em Guardar alterações.
Esta alteração requer a recriação dos nós, o que pode causar interrupções nas suas cargas de trabalho em execução. Para ver detalhes acerca desta alteração específica, encontre a linha correspondente na tabela alterações manuais que recriam os nós através de uma estratégia de atualização de nós e respeitam as políticas de manutenção. Para saber mais sobre as atualizações de nós, consulte o artigo Planeamento de interrupções de atualizações de nós.
Verifique se a NodeLocal DNSCache está ativada
Pode verificar se o NodeLocal DNSCache está em execução listando os node-local-dns
Pods:
kubectl get pods -n kube-system -o wide | grep node-local-dns
O resultado é semelhante ao seguinte:
node-local-dns-869mt 1/1 Running 0 6m24s 10.128.0.35 gke-test-pool-69efb6b8-5d7m <none> <none>
node-local-dns-htx4w 1/1 Running 0 6m24s 10.128.0.36 gke-test-pool-69efb6b8-wssk <none> <none>
node-local-dns-v5njk 1/1 Running 0 6m24s 10.128.0.33 gke-test-pool-69efb6b8-bhz3 <none> <none>
O resultado mostra um node-local-dns pod para cada nó que esteja a executar a versão 1.15 ou posterior do GKE.
Desative a DNSCache local do nó
Pode desativar o NodeLocal DNSCache através do seguinte comando:
gcloud container clusters update CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--update-addons=NodeLocalDNS=DISABLED
Substitua o seguinte:
CLUSTER_NAME: o nome do cluster a desativar.COMPUTE_LOCATION: a localização do Compute Engine para o cluster.
Esta alteração requer a recriação dos nós, o que pode causar interrupções nas suas cargas de trabalho em execução. Para ver detalhes acerca desta alteração específica, encontre a linha correspondente na tabela alterações manuais que recriam os nós através de uma estratégia de atualização de nós e respeitam as políticas de manutenção. Para saber mais sobre as atualizações de nós, consulte o artigo Planeamento de interrupções de atualizações de nós.
Resolva problemas de NodeLocal DNSCache
Para obter informações gerais sobre o diagnóstico de problemas de DNS do Kubernetes, consulte o artigo Depurar a resolução de DNS.
A NodeLocal DNSCache não é ativada imediatamente
Quando ativa a NodeLocal DNSCache num cluster existente, o GKE pode não atualizar os nós imediatamente se o cluster tiver uma janela de manutenção ou uma exclusão configurada. Para mais informações, consulte as restrições para a recriação de nós e os períodos de manutenção.
Se preferir não esperar, pode aplicar manualmente as alterações aos nós
chamando o comando gcloud container clusters upgrade e transmitindo a flag --cluster-version com a mesma versão do GKE que o conjunto de nós já está a executar. Tem de usar a CLI do Google Cloud para esta solução alternativa.
NodeLocal DNSCache com o Cloud DNS
Se usar o NodeLocal DNSCache com o Cloud DNS, o cluster usa o endereço IP do servidor de nomes 169.254.20.10, conforme mostrado no diagrama seguinte:
Como resultado, o endereço IP do serviço kube-dns pode ser diferente do endereço IP do servidor de nomes que os seus pods usam. Esta diferença nos endereços IP é esperada, uma vez que o endereço IP do servidor de nomes 169.254.20.10 é necessário para que o Cloud DNS funcione corretamente.
Para verificar os endereços IP, execute os seguintes comandos:
Veja o endereço IP do
kube-dnsserviço:kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"O resultado é o endereço IP de
kube-dns, como10.0.0.10:53Abra uma sessão de shell no seu pod:
kubectl exec -it POD_NAME -- /bin/bashNa sessão de shell do pod, leia o conteúdo do ficheiro
/etc/resolv.conf:cat /etc/resolv.confO resultado é
169.254.20.10
Política de rede com NodeLocal DNSCache
Se usar a política de rede
com a NodeLocal DNSCache e não estiver a usar o
Cloud DNS ou o
GKE Dataplane V2,
tem de configurar regras para permitir que as suas cargas de trabalho e os node-local-dns
pods enviem consultas DNS.
Use uma regra ipBlock no manifesto para permitir a comunicação entre os seus agrupamentos e o kube-dns.
O manifesto seguinte descreve uma política de rede que usa uma regra ipBlock:
spec:
egress:
- ports:
- port: 53
protocol: TCP
- port: 53
protocol: UDP
to:
- ipBlock:
cidr: KUBE_DNS_SVC_CLUSTER_IP/32
podSelector: {}
policyTypes:
- Egress
Substitua KUBE_DNS_SVC_CLUSTER_IP pelo endereço IP do serviço kube-dns. Pode obter o endereço IP do serviço kube-dns através do seguinte comando:
kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
Problemas conhecidos
Limite de tempo de DNS na dnsPolicy ClusterFirstWithHostNet quando usa NodeLocal DNSCache e GKE Dataplane V2
Em clusters que usam o GKE Dataplane V2 e o NodeLocal DNSCache, os pods com hostNetwork
definido como true e dnsPolicy definido como ClusterFirstWithHostNet não conseguem alcançar
os back-ends de DNS do cluster. Os registos de DNS podem conter entradas semelhantes às seguintes:
nslookup: write to 'a.b.c.d': Operation not permitted
;; connection timed out; no servers could be reached
O resultado indica que os pedidos DNS não conseguem alcançar os servidores de back-end.
Uma solução alternativa é definir o dnsPolicy e o dnsConfig para os pods hostNetwork:
spec:
dnsPolicy: "None"
dnsConfig:
nameservers:
- KUBE_DNS_UPSTREAM
searches:
- cluster.local
- svc.cluster.local
- NAMESPACE.svc.cluster.local
- c.PROJECT_ID.internal
- google.internal
options:
- name: ndots
value: "5"
Substitua o seguinte:
NAMESPACE: o espaço de nomes da cápsulahostNetwork.PROJECT_ID: o ID do seu projeto Cloud de Confiance .KUBE_DNS_UPSTREAM: o ClusterIP do serviço kube-dns a montante. Pode obter este valor através do seguinte comando:kubectl get svc -n kube-system kube-dns-upstream -o jsonpath="{.spec.clusterIP}"
Os pedidos DNS do pod podem agora alcançar o kube-dns e ignorar o NodeLocal DNSCache.
Erros de tempo limite do DNSCache NodeLocal
Em clusters com o NodeLocal DNSCache ativado, os registos podem conter entradas semelhantes às seguintes:
[ERROR] plugin/errors: 2 <hostname> A: read tcp <node IP: port>-><kubedns IP>:53: i/o timeout
A saída inclui o endereço IP do serviço kube-dns-upstream Cluster IP. Neste exemplo, a resposta a um pedido DNS não foi recebida de kube-dns em 2 segundos. Isto pode dever-se a um dos seguintes motivos:
- Um problema de conetividade de rede subjacente.
- Aumento significativo das consultas DNS da carga de trabalho ou devido ao aumento da escala do conjunto de nós.
Como resultado, os pods kube-dns existentes não conseguem processar todos os pedidos a tempo. A solução alternativa consiste em aumentar o número de réplicas do kube-dns ajustando os parâmetros de dimensionamento automático.
Aumentar a escala do kube-dns
Pode usar um valor inferior para nodesPerReplica para garantir que são criados mais pods kube-dns à medida que os nós do cluster são dimensionados. Recomendamos vivamente que defina um valor max explícito para garantir que a máquina virtual (VM) do plano de controlo do GKE não fica sobrecarregada devido ao grande número de pods kube-dns a monitorizar a API Kubernetes.
Pode definir max para o número de nós no cluster. Se o cluster tiver mais de 500 nós, defina max como 500.
Para clusters padrão, pode modificar o número de réplicas do kube-dns editando o kube-dns-autoscaler ConfigMap. Esta configuração não é suportada em clusters do Autopilot.
kubectl edit configmap kube-dns-autoscaler --namespace=kube-system
O resultado é semelhante ao seguinte:
linear: '{"coresPerReplica":256, "nodesPerReplica":16,"preventSinglePointFailure":true}'
O número de réplicas do kube-dns é calculado através da seguinte fórmula:
replicas = max( ceil( cores × 1/coresPerReplica ) , ceil( nodes × 1/nodesPerReplica ), maxValue )
Para aumentar a escala, altere nodesPerReplica para um valor mais pequeno e inclua um valor de max.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
A configuração cria 1 pod kube-dns para cada 8 nós no cluster. Um cluster de 24 nós tem 3 réplicas e um cluster de 40 nós tem 5 réplicas. Se o cluster crescer para além de 120 nós, o número de réplicas do kube-dns não cresce para além de 15, o valor max.
Para garantir um nível base de disponibilidade de DNS no seu cluster, defina uma contagem mínima de réplicas para o kube-dns.
A saída do kube-dns-autoscaler ConfigMap com o campo min seria semelhante ao seguinte:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
O que se segue?
- Leia uma vista geral de como o GKE fornece DNS gerido.
- Leia o artigo DNS para serviços e pods para uma vista geral de como o DNS é usado em clusters do Kubernetes.
- Saiba como usar o Cloud DNS para GKE.