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 DNSCache NodeLocal 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.
gcloud
Como ativar o NodeLocal DNSCache em um novo cluster
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.
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.
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.
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.
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:
Você pode ver o endereço IP do IP do cluster usando o seguinte comando:
kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
O resultado será assim:
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.