Nesta página, explicamos como melhorar a latência de busca DNS em um cluster do Google Kubernetes Engine (GKE) usando o NodeLocal DNSCache.
Observação: para clusters do GKE Autopilot, o NodeLocal DNSCache está ativado por padrão e não pode ser modificado.
Arquitetura
O NodeLocal DNSCache é um complemento do GKE que pode ser executado além do kube-dns.
O GKE implementa o NodeLocal DNSCache como um DaemonSet que executa um cache DNS em cada nó do cluster.
Quando um pod faz uma solicitação DNS, ela vai para o cache DNS em execução no mesmo nó que o pod. Se o cache não conseguir resolver a solicitação DNS, ele encaminhará a solicitação 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 kube-dns. Os pods node-local-dns usam o Serviço kube-dns-upstream para acessar os pods kube-dns. No diagrama a seguir, o endereço IP do Serviço kube-dns é10.0.0.10:53
. - Domínios de stub personalizados ou servidores de nomes upstream: as consultas são encaminhadas diretamente dos pods do NodeLocal DNSCache.
- Cloud DNS: todas as demais consultas são encaminhadas para o servidor de metadados local, que é executado no mesmo nó que o pod da consulta de origem; O servidor de metadados local acessa o Cloud DNS.
Quando você ativa o NodeLocal DNSCache em um cluster atual, o GKE recria todos os nós do cluster que executam a versão 1.15 e mais recentes do GKE, conforme o processo de upgrade do nó.
Depois que o GKE recria os nós, ele adiciona automaticamente
o identificador addon.gke.io/node-local-dns-ds-ready=true
aos nós. Não
adicione esse identificador aos nós do cluster manualmente.
Benefícios do NodeLocal DNSCache
O NodeLocal DNSCache oferece as seguintes vantagens:
- Tempo médio da busca DNS reduzido
- As conexões de pods para o cache local não criam entradas de tabela conntrack. Isso evita conexões descartadas e rejeitadas devido ao esgotamento da tabela de conexões e condições de corrida.
- É possível usar o NodeLocal DNSCache com o Cloud DNS para GKE.
- As consultas DNS para URLs externos (URLs que não se referem a recursos de cluster) são encaminhadas diretamente para o servidor de metadados local do Cloud DNS, ignorando kube-dns.
- Os caches de DNS local automaticamente selecionam os domínios de stub e os servidores de nomes upstream especificados no kube-dns ConfigMap.
Requisitos e limitações
- O NodeLocal DNSCache consome recursos de computação em cada nó do cluster.
- O NodeLocal DNSCache não é compatível com os pools de nós do Windows Server.
- O NodeLocal DNSCache requer a versão 1.15 ou posterior do GKE.
- O NodeLocal DNSCache acessa pods kube-dns usando TCP.
- O NodeLocal DNSCache acessa
upstreamServers
estubDomains
usando TCP e UDP na versão 1.18 ou posterior do GKE. O servidor DNS precisa ser acessível usando TCP e UDP. - Os registros DNS são armazenados em cache pelos seguintes períodos:
- O time to live (TTL) do registro ou então 30 segundos, se o TTL tiver mais de 30 segundos.
- Cinco segundos se a resposta DNS for
NXDOMAIN
.
- Os pods NodeLocal DNSCache monitoram as portas 53, 9253, 9353 e 8080 dos nós. Se
você executar qualquer outro pod
hostNetwork
ou configurar umhostPorts
com essas portas, o NodeLocal DNSCache falhará e ocorrerão erros no DNS. Os pods NodeLocal DNSCache não usam o modohostNetwork
ao usar o GKE Dataplane V2 e o Cloud DNS para GKE. - O cache DNS local é executado apenas em pools de nós que executam versões 1.15 e posteriores do GKE. Se você ativar o NodeLocal DNSCache em um cluster com nós executando versões anteriores, os pods desses nós usarão o kube-dns.
Ativar NodeLocal DNSCache
Em clusters do Autopilot, o NodeLocal DNSCache é ativado por padrão e não pode ser substituído.
Para clusters padrão, é possível ativar o NodeLocal DNSCache em clusters novos ou atuais usando a CLI do Google Cloud. É possível ativar o NodeLocal DNSCache em novos clusters usando o Console do Google Cloud.
Como ativar o NodeLocal DNSCache em um novo cluster
gcloud
Para ativar o NodeLocal DNSCache em um novo cluster, use a sinalização --addons
com o
argumento NodeLocalDNS
:
gcloud container clusters create CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--addons=NodeLocalDNS
Substitua:
CLUSTER_NAME
: o nome do novo cluster;COMPUTE_LOCATION
: a região do Compute Engine para o cluster.
Console
Para ativar o NodeLocal DNSCache em um novo cluster, siga estas etapas:
Acesse a página Google Kubernetes Engine no console do Google Cloud.
Ao lado de "Standard", clique em Configurar.
Configure o cluster como quiser.
No painel de navegação, clique em Rede.
Na seção Opções de rede avançadas, marque a caixa de seleção Ativar NodeLocal DNSCache.
Clique em Criar.
Como ativar o NodeLocal DNSCache em um cluster atual
Para ativar o NodeLocal DNSCache em um cluster atual, use a
sinalização --update-addons
com o argumento NodeLocalDNS=ENABLED
:
gcloud container clusters update CLUSTER_NAME \
--update-addons=NodeLocalDNS=ENABLED
Substitua:
CLUSTER_NAME
: o nome do cluster.
Essa mudança requer a recriação dos nós, o que pode causar interrupções nas cargas de trabalho em execução. Para detalhes sobre essa mudança específica, encontre a linha correspondente na tabela mudanças manuais que recriam os nós usando uma estratégia de upgrade de nó e respeitando as políticas de manutenção. Para saber mais sobre as atualizações de nós, consulte Planejar para interrupções de atualização de nós.
Verificar se o NodeLocal DNSCache está ativado
Para verificar se o NodeLocal DNSCache está em execução, liste os pods
node-local-dns
:
kubectl get pods -n kube-system -o wide | grep node-local-dns
O resultado será assim:
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>
A saída mostra um pod node-local-dns
para cada nó que executa
a versão 1.15 ou posterior do GKE.
Desativar o NodeLocal DNSCache
Desative o NodeLocal DNSCache usando o seguinte comando:
gcloud container clusters update CLUSTER_NAME \
--update-addons=NodeLocalDNS=DISABLED
Substitua:
CLUSTER_NAME
: o nome do cluster a ser desativado.
Essa mudança requer a recriação dos nós, o que pode causar interrupções nas cargas de trabalho em execução. Para detalhes sobre essa mudança específica, encontre a linha correspondente na tabela mudanças manuais que recriam os nós usando uma estratégia de upgrade de nó e respeitando as políticas de manutenção. Para saber mais sobre as atualizações de nós, consulte Planejar para interrupções de atualização de nós.
Solução de problemas do NodeLocal DNSCache
Veja informações gerais sobre como diagnosticar problemas de DNS do Kubernetes em Como depurar a resolução de DNS.
O NodeLocal DNSCache não é ativado imediatamente
Quando você ativa o NodeLocal DNSCache em um cluster atual, o GKE pode não atualizar os nós imediatamente se o cluster tiver uma janela ou exclusão de manutenção configurada. Para mais informações, consulte Atenção para janelas de recriação e manutenção de nós.
Se você preferir não
esperar, aplique manualmente as alterações aos nós chamando o comando
gcloud container clusters upgrade
e transmitindo a sinalização --cluster-version
com a mesma
versão do GKE que o pool de nós já está em execução. Use a Google Cloud CLI para essa solução alternativa.
NodeLocal DNSCache com o Cloud DNS
Se você usar o NodeLocal DNSCache com o Cloud DNS, o cluster usará o endereço IP 169.254.20.10
do servidor de nomes, conforme mostrado no diagrama a seguir:
Como resultado, o endereço IP do serviço kube-dns
pode ser diferente do
endereço IP do servidor de nomes usado pelos pods. Essa diferença nos endereços IP
é esperado, porque o endereço IP do servidor de nomes 169.254.20.10
é obrigatório
para que o Cloud DNS funcione corretamente.
Para verificar os endereços IP, execute os seguintes comandos:
Veja o endereço IP do serviço
kube-dns
:kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
A saída é o endereço IP de
kube-dns
, como10.0.0.10:53
Abra uma sessão do shell no pod:
kubectl exec -it POD_NAME -- /bin/bash
Na sessão do shell do pod, leia o conteúdo do arquivo
/etc/resolv.conf
:cat /etc/resolv.conf
O resultado é
169.254.20.10
Política de rede com NodeLocal DNSCache
Se você usar a política de rede
com o NodeLocal DNSCache e não estiver usando o
Cloud DNS ou o
GKE Dataplane V2, é preciso configurar regras para permitir que suas cargas de trabalho e os pods node-local-dns
enviem consultas DNS.
Use uma regra ipBlock
no manifesto para permitir a comunicação entre
pods e kube-dns.
O manifesto a seguir 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. Você pode receber o endereço IP do serviço kube-dns usando o
seguinte comando:
kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
Problemas conhecidos
Tempo limite do DNS em ClusterFirstWithHostNet dnsPolicy ao usar o NodeLocal DNSCache e o GKE Dataplane V2
Em clusters que usam o Dataplane V2 e o NodeLocal DNSCache, pods com hostNetwork
definido como true
e dnsPolicy
definido como ClusterFirstWithHostNet
não podem alcançar
back-ends de DNS do cluster. Os registros DNS podem conter entradas semelhantes a estas:
nslookup: write to 'a.b.c.d': Operation not permitted
;; connection timed out; no servers could be reached
A saída indica que as solicitações DNS não conseguem alcançar os servidores de back-end.
Uma alternativa é definir os seguintes dnsPolicy
e dnsConfig
para 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:
NAMESPACE
: o namespace do podhostNetwork
.PROJECT_ID
: o ID do seu projeto do Google Cloud.KUBE_DNS_UPSTREAM
: o ClusterIP do serviço upstream kube-dns. É possível conseguir esse valor usando o seguinte comando:kubectl get svc -n kube-system kube-dns-upstream -o jsonpath="{.spec.clusterIP}"
As solicitações de DNS do pod agora podem acessar o kube-dns e ignorar o NodeLocal DNSCache.
Erros de tempo limite do NodeLocal DNSCache
Em clusters com o NodeLocal DNSCache ativado, os registros podem conter entradas semelhantes a estas:
[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 de IP do cluster
kube-dns-upstream
. Neste exemplo, a resposta a uma solicitação DNS não foi recebida do
kube-dns em dois segundos. A causa pode ser:
- Um problema de conectividade de rede subjacente.
- Aumento significativo nas consultas DNS da carga de trabalho ou devido ao aumento do pool de nós.
Como resultado, os pods kube-dns
atuais não podem processar todas as solicitações a tempo. A alternativa é aumentar o número de réplicas do kube-dns, ajustando os parâmetros de escalonamento automático.
Como escalonar o kube-dns
Use um valor menor para nodesPerReplica
para garantir que mais pods kube-dns
sejam criados à medida que os nós do cluster forem escalonados verticalmente. É altamente recomendável definir um
valor max
explícito para garantir que a máquina
virtual (VM) do plano de controle do GKE não fique sobrecarregada devido ao grande número de pods kube-dns que assistem
à API Kubernetes.
É possível definir max
com o número de nós do cluster. Se o cluster tiver mais
de 500 nós, defina max
como 500.
Para clusters padrão, modifique o número de réplicas do kube-dns editando o
ConfigMap kube-dns-autoscaler
. Essa configuração não é compatível com clusters do Autopilot.
kubectl edit configmap kube-dns-autoscaler --namespace=kube-system
O resultado será assim:
linear: '{"coresPerReplica":256, "nodesPerReplica":16,"preventSinglePointFailure":true}'
O número de réplicas do kube-dns é calculado usando a seguinte fórmula:
réplicas = max( ceil( cores × 1/coresPerReplica ) , ceil( nodes × 1/nodesPerReplica ), maxValue )
Para escalonar verticalmente, altere nodesPerReplica
para um valor menor e inclua um
valor max
.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
Essa configuração cria um pod kube-dns para cada oito nós no cluster. Um cluster de 24 nós
terá três réplicas, e um cluster de 40 nós terá cinco réplicas. Se o
cluster ultrapassar 120 nós, o número de réplicas do kube-dns não
ultrapassará 15, o valor max
.
Para garantir um nível básico de disponibilidade de DNS no cluster, defina uma contagem mínima de réplicas para o kube-dns.
A saída do ConfigMap kube-dns-autoscaler
com o campo min
seria semelhante ao seguinte:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
A seguir
- Leia uma visão geral de como o GKE fornece DNS gerenciado.
- Leia DNS para serviços e pods para uma visão geral de como o DNS é usado nos clusters do Kubernetes.
- Saiba como usar o Cloud DNS para GKE.