Usar o kube-dns

Esta página descreve como o Google Kubernetes Engine (GKE) implementa a deteção de serviços usando o kube-dns, o fornecedor de DNS predefinido para clusters do GKE.

Para clusters do Autopilot, não pode modificar a configuração kube-dns predefinida.

Arquitetura

Quando cria um cluster, o GKE implementa automaticamente pods kube-dns no espaço de nomes kube-system. Os pods acedem à implementação do kube-dns através de um serviço correspondente que agrupa os pods do kube-dns e atribui-lhes um único endereço IP (ClusterIP). Por predefinição, todos os pods num cluster usam este serviço para resolver consultas de DNS. O diagrama seguinte mostra a relação entre os pods e o serviço kube-dns.

Relação dos pods kube-dns com o serviço kube-dns.

O kube-dns é dimensionado para satisfazer as exigências de DNS do cluster. Este dimensionamento é controlado pelo kube-dns-autoscaler, um pod implementado por predefinição em todos os clusters do GKE. O kube-dns-autoscaler ajusta o número de réplicas na implementação do kube-dns com base no número de nós e núcleos no cluster.

O kube-dns suporta até 1000 pontos finais por serviço sem cabeça.

Como o DNS do pod está configurado

O kubelet em execução em cada nó configura o etc/resolv.conf do pod para usar o ClusterIP do serviço kube-dns. A configuração de exemplo seguinte mostra que o endereço IP do serviço kube-dns é 10.0.0.10. Este endereço IP é diferente noutros clusters.

nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local c.my-project-id.internal google.internal
options ndots:5

O kube-dns é o servidor de nomes oficial para o domínio do cluster (cluster.local) e resolve nomes externos recursivamente. Os nomes curtos que não estão totalmente qualificados, como myservice, são concluídos primeiro com caminhos de pesquisa locais.

Adicionar resolvedores personalizados para domínios stub

Pode modificar o ConfigMap para o kube-dns de modo a definir domínios stub como parte da infraestrutura DNS nos seus clusters.

Os domínios stub permitem-lhe configurar resoluções personalizadas por domínio para que o kube-dns encaminhe os pedidos DNS para servidores DNS upstream específicos quando resolve estes domínios.

O seguinte manifesto ConfigMap de kube-dns inclui uma configuração stubDomains que define resolvedores personalizados para o domínio example.com.

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
  name: kube-dns
  namespace: kube-system
data:
  stubDomains: |
    {
      "example.com": [
        "8.8.8.8",
        "8.8.4.4",
        "1.1.1.1",
        "1.0.0.1"
      ]
    }

Execute o seguinte comando para abrir um editor de texto:

kubectl edit configmap kube-dns -n kube-system

Substitua o conteúdo do ficheiro pelo manifesto e, em seguida, saia do editor de texto para aplicar o manifesto ao cluster.

Servidores de nomes a montante

Se modificar o ConfigMap para o kube-dns de modo a incluir upstreamNameservers, o kube-dns encaminha todos os pedidos DNS, exceto *.cluster.local, para esses servidores. Isto inclui metadata.internal e *.google.internal, que não são resolvidos pelo servidor a montante.

Se ativar a federação de identidades da carga de trabalho para o GKE ou quaisquer cargas de trabalho que dependam da resolução metadata.internal, para reter a resolução de nomes *.internal, adicione um stubDomain ao ConfigMap.

data:
  stubDomains: |
    {
      "internal": [
        "169.254.169.254"
      ]
    }
  upstreamNameservers: |
    ["8.8.8.8"]

Resolução de problemas

Para obter informações sobre a resolução de problemas do kube-dns, consulte as seguintes páginas:

Limitações

Leia as secções seguintes para ver informações sobre as limitações do kube-dns.

Limite de domínios de pesquisa

Existe um limite de 32 domínios de pesquisa DNS para /etc/resolv.conf. Se definir mais de 32 domínios de pesquisa, a criação do Pod falha com o seguinte erro:

The Pod "dns-example" is invalid: spec.dnsConfig.searches: Invalid value: []string{"ns1.svc.cluster-domain.example", "my.dns.search.suffix1", "ns2.svc.cluster-domain.example", "my.dns.search.suffix2", "ns3.svc.cluster-domain.example", "my.dns.search.suffix3", "ns4.svc.cluster-domain.example", "my.dns.search.suffix4", "ns5.svc.cluster-domain.example", "my.dns.search.suffix5", "ns6.svc.cluster-domain.example", "my.dns.search.suffix6", "ns7.svc.cluster-domain.example", "my.dns.search.suffix7", "ns8.svc.cluster-domain.example", "my.dns.search.suffix8", "ns9.svc.cluster-domain.example", "my.dns.search.suffix9", "ns10.svc.cluster-domain.example", "my.dns.search.suffix10", "ns11.svc.cluster-domain.example", "my.dns.search.suffix11", "ns12.svc.cluster-domain.example", "my.dns.search.suffix12", "ns13.svc.cluster-domain.example", "my.dns.search.suffix13", "ns14.svc.cluster-domain.example", "my.dns.search.suffix14", "ns15.svc.cluster-domain.example", "my.dns.search.suffix15", "ns16.svc.cluster-domain.example", "my.dns.search.suffix16", "my.dns.search.suffix17"}: must not have more than 32 search paths.

Esta mensagem de erro é devolvida pelo kube-apiserver em resposta a uma tentativa de criação de um grupo de anúncios.

Para resolver este problema, remova os caminhos de pesquisa adicionais da configuração.

Considere o limite de upstreamNameservers

O Kubernetes impõe um limite de até três valores upstreamNameservers. Se definir mais de três upstreamNameservers, é apresentado o seguinte erro no Cloud Logging nos registos de implementação kube-dns:

Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update

Quando isto acontece, o kube-dns comporta-se como se não tivesse upstreamNameserversconfigurado. Para resolver este problema, remova o upstreamNameservers adicional da configuração.

Limitações de desempenho com kube-dns

Se estiver a ter uma latência elevada com as pesquisas de DNS ou falhas de resolução de DNS com o fornecedor kube-dns predefinido, isto pode ser causado por:

  • Realizar procuras de DNS frequentes na sua carga de trabalho
  • Implementar uma densidade de agrupamentos mais elevada por nó.
  • Exceder o limite de consultas por segundo (CPS) de 20 para cada pod kube-dns.
  • Executar o kube-dns em VMs spot ou preemptíveis, o que pode levar a eliminações inesperadas de nós e a problemas de resolução de DNS subsequentes.

Para melhorar os tempos de procura de DNS, pode escolher uma das seguintes opções:

  • Evite executar componentes críticos do sistema, como o kube-dns, em VMs preemptíveis ou Spot. A utilização de VMs de Spot ou preemptíveis para DNS pode causar falhas e interromper o seu cluster.
  • Como práticas recomendadas, crie, pelo menos, um conjunto de nós composto por VMs padrão (não Spot nem preemptíveis) para alojar componentes críticos do sistema, como o kube-dns. Para garantir que as cargas de trabalho críticas só são agendadas no conjunto de nós fiável, o que impede a respetiva execução em VMs preemptivas ou do Spot, pode usar taints e tolerâncias para VMs do Spot.
  • Ative a NodeLocal DNSCache.
  • Aumente a escala do kube-dns.
  • Certifique-se de que a sua aplicação usa funções baseadas em dns.resolve* em vez de funções baseadas em dns.lookup, uma vez que dns.lookup é síncrono. As funções dns.resolve* executam sempre uma consulta DNS assíncrona na rede.

Registos de DNS de serviço

O kube-dns só cria registos de DNS para serviços que tenham pontos finais.

TTL grande dos servidores upstream de DNS

Se o kube-dns receber uma resposta DNS de um resolvedor de DNS a montante com um TTL grande ou "infinito", mantém este valor de TTL para a entrada DNS na cache. A entrada nunca expira e pode criar uma discrepância entre a entrada e o endereço IP real resolvido para o nome TTL.

O GKE resolve este problema nas seguintes versões do plano de controlo ao definir um valor de TTL máximo de 30 segundos para qualquer resposta DNS que tenha um TTL superior a 30 segundos:

  • 1.21.14-gke.9100
  • 1.22.15-gke.2100
  • 1.23.13-gke.500
  • 1.24.7-gke.500
  • 1.25.2-gke.500 ou posterior

Este comportamento é semelhante ao NodeLocal DNSCache.

Registe métricas do kube-dns ou dnsmasq

Pode obter métricas sobre consultas DNS no cluster do GKE. Esta é uma forma rápida de obter métricas do kube-dns ou do dnsmasq sem modificar a implementação.

  1. Apresente os pods na implementação kube-dns.

    $ kubectl get pods -n kube-system --selector=k8s-app=kube-dns
    

    O resultado será semelhante ao seguinte:

    NAME                        READY     STATUS    RESTARTS   AGE
    kube-dns-548976df6c-98fkd   4/4       Running   0          48m
    kube-dns-548976df6c-x4xsh   4/4       Running   0          47m
    
  2. Escolha um Pod e defina o respetivo nome para uma variável.

    POD="kube-dns-548976df6c-98fkd"
    
  3. Configure o encaminhamento de porta para o pod kube-dns escolhido.

    $ kubectl port-forward pod/${POD} -n kube-system 10054:10054 10055:10055
    

    O resultado será semelhante ao seguinte:

    Forwarding from 127.0.0.1:10054 -> 10054
    Forwarding from 127.0.0.1:10055 -> 10055
    
  4. Obtenha as métricas executando o seguinte comando curl no ponto final.

    $ curl http://127.0.0.1:10054/metrics; curl http://127.0.0.1:10055/metrics

    A porta 10054 contém métricas dnsmasq e a porta 10055 contém métricas kube-dns.

    O resultado será semelhante ao seguinte:

    kubedns_dnsmasq_errors 0
    kubedns_dnsmasq_evictions 0
    kubedns_dnsmasq_hits 3.67351e+06
    kubedns_dnsmasq_insertions 254114
    kubedns_dnsmasq_max_size 1000
    kubedns_dnsmasq_misses 3.278166e+06
    
    

O que se segue?