Configure a DNSCache local do nó

Este documento descreve como usar o NodeLocal DNSCache para reduzir a latência de procura de DNS e melhorar o desempenho da sua aplicação no cluster do Google Kubernetes Engine (GKE).

O NodeLocal DNSCache é um suplemento do GKE que melhora o desempenho do DNS através da execução de uma cache de DNS diretamente em cada nó do cluster como um DaemonSet. Quando os seus Pods fazem um pedido DNS, o pedido é primeiro enviado para a cache local no mesmo nó. O processamento de pedidos localmente reduz significativamente os tempos médios de procura de DNS e diminui a carga no fornecedor de DNS central do cluster, como o kube-dns ou o Cloud DNS para GKE. Para uma explicação detalhada da arquitetura DNS e das vantagens da DNSCache local do nó, consulte o artigo Acerca da deteção de serviços.

Nos clusters do GKE Autopilot, o NodeLocal DNSCache está ativado por predefinição e não o pode desativar. Nos clusters padrão do GKE que executam a versão 1.33.1 e posteriores, o NodeLocal DNSCache está ativado por predefinição, mas pode desativá-lo.

Este documento destina-se a utilizadores do GKE, incluindo programadores, administradores e arquitetos. Para saber mais sobre as funções comuns e exemplos de tarefas no Google Cloud, consulte o artigo Funções de utilizador e tarefas comuns do GKE Enterprise.

Este documento pressupõe que conhece o seguinte:

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 que é executada 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 kube-dns. Os pods node-local-dns usam o serviço kube-dns-upstream para aceder aos pods kube-dns.
  • Domínios stub personalizados ou servidores de nomes a montante: as consultas são encaminhadas diretamente a partir de pods NodeLocal DNSCache.
  • Cloud DNS: todas as outras consultas são encaminhadas para o servidor de metadados local que é executado no mesmo nó onde a consulta foi originada. O servidor de metadados local acede ao Cloud DNS.

O caminho de um pedido de DNS, conforme descrito no parágrafo anterior.

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. Este comportamento impede ligações rejeitadas e interrompidas causadas por esgotamento da tabela de conntrack e condições de concorrência.
  • Pode usar a NodeLocal DNSCache com o Cloud DNS para GKE.
  • As consultas de DNS para URLs externos (URLs que não se referem a recursos do cluster) são encaminhadas diretamente para o servidor de metadados local e ignoram 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 kube-dns pods através de TCP.
  • O NodeLocal DNSCache acede a upstreamServers e stubDomains 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 pod ou configurar um hostPorts com essas portas, o NodeLocal DNSCache falha e ocorrem erros de DNS. Os pods NodeLocal DNSCache não usam o modo hostNetwork quando usam o GKE Dataplane V2 e não usam o Cloud DNS para GKE.
  • A cache DNS local é executada apenas em conjuntos de nós que executam 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 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 CLI gcloud. Se instalou anteriormente a CLI gcloud, execute o comando gcloud components update para 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 Google Cloud 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:

Consola

Para ativar a NodeLocal DNSCache num novo cluster, siga estes passos:

  1. Aceda à página Google Kubernetes Engine na Google Cloud consola.

    Aceda aos clusters do Kubernetes

  2. Clique no nome do cluster que quer modificar.

  3. Em Networking, no campo DNS provider, clique em Edit DNS provider.

  4. Selecione a caixa de verificação Ativar NodeLocal DNSCache.

  5. 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 executa a versão 1.15 ou posterior do GKE.

Desative a NodeLocal DNSCache

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:

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 Resolução de problemas de 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:

NodeLocal DNSCache com arquitetura do Cloud DNS.

Como resultado, o endereço IP do serviço pode ser diferente do endereço IP do servidor de nomes que os seus pods usam.kube-dns 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:

  1. 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, como 10.0.0.10

  2. Abra uma sessão de shell no seu pod:

    kubectl exec -it POD_NAME -- /bin/bash
    
  3. Na sessão da 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 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

Esta secção apresenta problemas conhecidos com o NodeLocal DNSCache.

Tempo limite de DNS na dnsPolicy ClusterFirstWithHostNet quando usa NodeLocal DNSCache e GKE Dataplane V2

Nos clusters que usam o GKE Dataplane V2 e o NodeLocal DNSCache, os pods com o campo hostNetwork definido como true e o campo 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:

dnslookup: 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 consiste em definir os campos dnsPolicy e dnsConfig para os pods hostNetwork:

spec:
 dnsPolicy: "None"
 dnsConfig:
   nameservers:
     - KUBE_DNS_UPSTREAM
   searches:
     - NAMESPACE.svc.cluster.local
     - svc.cluster.local
     - cluster.local
     - c.PROJECT_ID.internal
     - google.internal
   options:
     - name: ndots
       value: "5"

Substitua o seguinte:

  • NAMESPACE: o espaço de nomes da cápsula hostNetwork.
  • PROJECT_ID: o ID do seu projeto Google 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 kube-dns e ignorar o NodeLocal DNSCache.

Erros de tempo limite do DNSCache local do nó

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 dois segundos. Este problema 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 do aumento da capacidade do conjunto de nós.

Como resultado, os kube-dnspods existentes não conseguem processar todos os pedidos a tempo. A solução alternativa é aumentar o número de réplicas kube-dns aumentando a escala do kube-dns.

A aumentar a escala de kube-dns

Pode usar um valor inferior para o campo nodesPerReplica para ajudar a garantir que são criados mais kube-dns pods à medida que os nós do cluster são dimensionados. Recomendamos vivamente que defina um valor max explícito para ajudar a garantir que a máquina virtual (VM) do plano de controlo do GKE não é sobrecarregada pelo grande número de pods kube-dns a monitorizar a API Kubernetes.

Pode definir o campo max para o número de nós no cluster. Se o cluster tiver mais de 500 nós, defina o campo max como 500.

Para clusters padrão, pode modificar o número de kube-dnsréplicas editando o kube-dns-autoscalerConfigMap. 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 kube-dns é calculado através da seguinte fórmula:

replicas = max(ceil(cores * 1/coresPerReplica), ceil(nodes * 1/nodesPerReplica))

Se definir os campos min e max no ConfigMap, as réplicas são limitadas por estes valores. Para aumentar a escala, altere o valor do campo nodesPerReplica para um valor mais pequeno e inclua um valor para o campo max:

linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'

A configuração cria um kube-dnspod para cada oito nós no cluster. Um cluster de 24 nós tem três réplicas e um cluster de 40 nós tem cinco réplicas. Se o cluster crescer para mais de 120 nós, o número de réplicas não cresce para mais de 15, que é o valor max.kube-dns

Para ajudar a garantir um nível base de disponibilidade de DNS no seu cluster, defina uma quantidade mínima de réplicas para kube-dns.

A saída para o kube-dns-autoscaler ConfigMap que tem um campo min definido seria semelhante ao seguinte:

linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'

O que se segue?