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 NodeLocal DNSCache.
- 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
O 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
upstreamServers
estubDomains
atravé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
hostNetwork
podhostNetwork
ou configurar umhostPorts
com essas portas, o NodeLocal DNSCache falha e ocorrem erros de DNS. Os pods NodeLocal DNSCache não usam o modohostNetwork
quando 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 o GKE nas versões 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.
Ative a NodeLocal DNSCache
Para clusters do Autopilot, o NodeLocal DNSCache está ativado por predefinição e não pode ser substituído.
Para clusters padrão, pode ativar a NodeLocal DNSCache em clusters novos ou existentes através da CLI do Google Cloud. Pode ativar a NodeLocal DNSCache em novos clusters através da Trusted Cloud consola.
Ative a DNSCache local do nó num novo cluster
gcloud
Para ativar o NodeLocal DNSCache num novo cluster, use a flag --addons
com o argumento NodeLocalDNS
:
gcloud container clusters create CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--addons=NodeLocalDNS
Substitua o seguinte:
CLUSTER_NAME
: o nome do novo 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 Trusted Cloud consola.
Junto a Padrão, clique em Configurar.
Configure o cluster como quiser.
No painel de navegação, clique em Rede.
Na secção Opções de rede avançadas, selecione a caixa de verificação Ativar NodeLocal DNSCache.
Clique em Criar.
Ative a DNSCache local do nó num cluster existente
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.
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 o NodeLocal DNSCache está ativado
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 advertências 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-dns
serviç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:53
Abra uma sessão de shell no seu pod:
kubectl exec -it POD_NAME -- /bin/bash
Na sessão de shell do pod, leia o conteúdo do ficheiro
/etc/resolv.conf
:cat /etc/resolv.conf
O 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 Trusted Cloud .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.