Se estiver a executar aplicações em clusters padrão, o kube-dns é o fornecedor de DNS predefinido que ajuda a ativar a deteção de serviços e a comunicação. Este documento descreve como gerir o DNS com o kube-dns, incluindo a respetiva arquitetura, configuração e práticas recomendadas para otimizar a resolução de DNS no seu ambiente do GKE.
Este documento destina-se a programadores, administradores e arquitetos responsáveis pela gestão de DNS no GKE. Para ver o contexto das funções e tarefas comuns no Google Cloud, consulte o artigo Funções e tarefas comuns do utilizador do GKE Enterprise.
Antes de começar, certifique-se de que conhece os serviços Kubernetes e os conceitos DNS gerais.
Compreenda a arquitetura kube-dns
O kube-dns funciona no seu cluster do GKE para permitir a resolução de DNS entre Pods e serviços.
O diagrama seguinte mostra como os seus Pods interagem com o serviço kube-dns:
Componentes principais
O kube-dns inclui os seguintes componentes principais:
kube-dnsPods: estes pods executam okube-dnssoftware do servidor. São executadas várias réplicas destes pods no espaço de nomeskube-system, e oferecem elevada disponibilidade e redundância.kube-dnsServiço: este serviço do Kubernetes do tipoClusterIPagrupa oskube-dnspods e expõe-nos como um único ponto final estável. OClusterIPatua como o servidor DNS para o cluster, que os pods usam para enviar consultas DNS.kube-dnssuporta até 1000 pontos finais por serviço sem interface.kube-dns-autoscaler: este Pod ajusta o número de réplicas com base no tamanho do cluster, que inclui o número de nós e núcleos de CPU.kube-dnsEsta abordagem ajuda a garantir que okube-dnsconsegue processar cargas de consultas de DNS variáveis.
Resolução de DNS interna
Quando um Pod precisa de resolver um nome DNS no domínio do cluster, como
myservice.my-namespace.svc.cluster.local, ocorre o seguinte processo:
- Configuração de DNS do pod: o
kubeletem cada nó configura o ficheiro/etc/resolv.confdo pod. Este ficheiro usa okube-dnsdo serviçoClusterIPcomo servidor de nomes. - Consulta DNS: o Pod envia uma consulta DNS para o
kube-dnsserviço. - Resolução de nomes:
kube-dnsrecebe a consulta. Procura o endereço IP correspondente nos respetivos registos DNS internos e responde ao pod. - Comunicação: o pod usa o endereço IP resolvido para comunicar com o serviço de destino.
Resolução de DNS externa
Quando um Pod precisa de resolver um nome DNS externo ou um nome que esteja fora do domínio do cluster, o kube-dns atua como um resolvedor recursivo. Encaminha a consulta
para servidores DNS a montante configurados no respetivo ficheiro
ConfigMap. Também pode configurar resolvedores personalizados para domínios específicos, que também são conhecidos como domínios stub. Esta configuração direciona o kube-dns para encaminhar pedidos para esses domínios para servidores DNS upstream específicos.
Configure o DNS do pod
No GKE, o agente kubelet em cada nó configura as definições de DNS
para os pods que são executados nesse nó.
Configure o ficheiro /etc/resolv.conf
Quando o GKE cria um pod, o agente kubelet modifica o ficheiro /etc/resolv.conf do pod. Este ficheiro configura o servidor DNS para a resolução de nomes
e especifica domínios de pesquisa. Por predefinição, o kubelet configura o pod para usar o serviço DNS interno do cluster, kube-dns, como servidor de nomes. Também
preenche os domínios de pesquisa no ficheiro. Estes domínios de pesquisa permitem-lhe usar nomes não qualificados em consultas DNS. Por exemplo, se um Pod consultar myservice, o Kubernetes tenta primeiro resolver myservice.default.svc.cluster.local, depois myservice.svc.cluster.local e, em seguida, outros domínios da lista search.
O exemplo seguinte mostra uma configuração /etc/resolv.conf predefinida:
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
Este ficheiro tem as seguintes entradas:
nameserver: define oClusterIPdo serviçokube-dns.search: define os domínios de pesquisa que são anexados a nomes não qualificados durante as procuras de DNS.options ndots:5: define o limite para quando o GKE considera que um nome está totalmente qualificado. Um nome é considerado totalmente qualificado se tiver cinco ou mais pontos.
Os pods configurados com a definição hostNetwork: true herdam a respetiva configuração de DNS do anfitrião e não consultam diretamente o kube-dns.
Personalizar kube-dns
O kube-dns oferece uma resolução de DNS predefinida robusta. Pode personalizar o respetivo comportamento para necessidades específicas, como melhorar a eficiência da resolução ou usar resolvedores de DNS preferenciais. Os domínios stub e os servidores de nomes upstream são configurados através da modificação do kube-dns ConfigMap no espaço de nomes kube-system.
Modifique o kube-dns ConfigMap
Para modificar o kube-dns ConfigMap, faça o seguinte:
Abra o ConfigMap para edição:
kubectl edit configmap kube-dns -n kube-systemNa secção
data, adicione os camposstubDomainseupstreamNameserverspara: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" ], "internal": [ # Required if your upstream nameservers can't resolve GKE internal domains "169.254.169.254" # IP of the metadata server ] } upstreamNameservers: | [ "8.8.8.8", # Google Public DNS "1.1.1.1" # Cloudflare DNS ]Guarde o ConfigMap. O
kube-dnsrecarrega automaticamente a configuração.
Domínios stub
Os domínios stub permitem-lhe definir resolvedores de DNS personalizados para domínios específicos. Quando um pod consulta um nome nesse domínio fictício, o kube-dns encaminha a consulta para o resolvedor especificado em vez de usar o respetivo mecanismo de resolução predefinido.
Inclui uma secção stubDomains no kube-dns ConfigMap.
Esta secção especifica o domínio e os servidores de nomes a montante correspondentes.
Em seguida, o kube-dns encaminha as consultas de nomes nesse domínio para os servidores designados. Por exemplo, pode encaminhar todas as consultas DNS para internal.mycompany.com para 192.168.0.10 e adicionar "internal.mycompany.com": ["192.168.0.10"] a stubDomains.
Quando define um resolvedor personalizado para um domínio stub, como example.com,kube-dns encaminha todos os pedidos de resolução de nomes para esse domínio, incluindo subdomínios como *.example.com, para os servidores especificados.
Servidores de nomes a montante
Pode configurar o kube-dns para usar servidores de nomes upstream personalizados para resolver
nomes de domínios externos. Esta configuração indica ao kube-dns para encaminhar todos os pedidos DNS, exceto os pedidos para o domínio interno do cluster (*.cluster.local), para os servidores upstream designados. Os domínios internos, como metadata.internal e *.google.internal, podem não ser resolvidos pelos seus servidores upstream personalizados. Se ativar a federação de identidade da carga de trabalho para o GKE ou tiver cargas de trabalho que dependam destes domínios, adicione um domínio stub para internal no ConfigMap. Use 169.254.169.254, o endereço IP do servidor de metadados, como o resolvedor para este domínio fictício.
Faça a gestão de uma implementação personalizada do kube-dns
Num GKE padrão, o kube-dns é executado como uma implementação. Uma implementação
kube-dns personalizada significa que, como administrador do cluster, pode controlar
a implementação e personalizá-la de acordo com as suas necessidades, em vez de usar a implementação predefinida
fornecida pelo GKE.
Motivos para uma implementação personalizada
Pondere uma implementação kube-dns personalizada pelos seguintes motivos:
- Atribuição de recursos: ajuste os recursos de CPU e memória para
kube-dnsPods para otimizar o desempenho em clusters com elevado tráfego de DNS. - Versão da imagem: use uma versão específica da imagem
kube-dnsou mude para um fornecedor de DNS alternativo, como o CoreDNS. - Configuração avançada: personalize os níveis de registo, as políticas de segurança e o comportamento de colocação em cache de DNS.
Escala automática para implementações personalizadas
O kube-dns-autoscaler integrado funciona com a implementação kube-dns predefinida.
Se criar uma kube-dnsimplementação personalizada, o escalador automático incorporado não a gere. Como tal, tem de configurar um escalador automático separado que esteja especificamente configurado para monitorizar e ajustar a quantidade de réplicas da sua implementação personalizada.
Esta abordagem envolve a criação e a implementação da sua própria configuração do redimensionador automático no cluster.
Quando gere uma implementação personalizada, é responsável por todos os respetivos componentes, como manter a imagem do escalador automático atualizada. A utilização de componentes desatualizados pode provocar uma degradação do desempenho ou falhas de DNS.
Para obter instruções detalhadas sobre como configurar e gerir a sua própria implementação, consulte o artigo Configurar uma implementação kube-dns personalizada.kube-dns
Resolver problemas
Para informações sobre a resolução de problemas de kube-dns, consulte as seguintes páginas:
- Para obter aconselhamento sobre
kube-dnsno GKE, consulte o artigo Resolva problemas dekube-dnsno GKE. - Para obter aconselhamento geral sobre o diagnóstico de problemas de DNS do Kubernetes, consulte o artigo Depurar a resolução de DNS.
Otimize a resolução de DNS
Esta secção descreve problemas comuns e práticas recomendadas para gerir o DNS no GKE.
Limite de domínios de pesquisa de um dnsConfig
O Kubernetes limita o número de domínios de pesquisa DNS a 32. Se tentar definir mais de 32 domínios de pesquisa no dnsConfig de um Pod, o kube-apiserver não cria o Pod e apresenta um erro semelhante ao seguinte:
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.
O kube-apiserver devolve esta mensagem de erro 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.
Limite de nameservers upstream para kube-dns
kube-dns limita o número de valores upstreamNameservers a três. Se definir mais de três, o Cloud Logging apresenta um erro semelhante ao seguinte:
Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update
Neste cenário, kube-dns ignora a configuração upstreamNameservers e continua a usar a configuração válida anterior. Para resolver este problema, remova
o upstreamNameservers adicional de kube-dns ConfigMap.
Aumente a escala kube-dns
Nos clusters padrão, pode usar um valor inferior para nodesPerReplica
para que sejam criados mais kube-dnspods quando os nós do cluster forem dimensionados. Recomendamos vivamente que defina um valor explícito para o campo max para ajudar a 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 que estão a monitorizar a API Kubernetes.
Pode definir o valor do campo max para o número de nós no cluster.
Se o cluster tiver mais de 500 nós, defina o valor do campo max como
500.
Pode modificar o número de réplicas kube-dns editando o valor de kube-dns-autoscaler ConfigMap.
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 ) )
kube-dns
Para aumentar a escala, altere o valor do campo nodesPerReplica para um valor inferior e inclua um valor para o campo max.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
Esta 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 além de 120 nós, o número de réplicas não cresce para além de 15, que é o valor do campo max.kube-dns
Para ajudar a garantir um nível base de disponibilidade do DNS no seu cluster, defina uma quantidade mínima de réplicas para o campo kube-dns.
O resultado do kube-dns-autoscaler ConfigMap com o campo min configurado é semelhante ao seguinte:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
Melhore os tempos de procura de DNS
Vários fatores podem causar uma latência elevada com procuras de DNS ou falhas de resolução de DNS com o fornecedor kube-dns predefinido. As aplicações podem ter estes problemas como erros getaddrinfo EAI_AGAIN, que indicam uma falha temporária na resolução de nomes. As causas incluem o seguinte:
- Procuras de DNS frequentes na sua carga de trabalho.
- Densidade de pods elevada por nó.
- Executar o
kube-dnsem VMs Spot ou VMs preemptíveis, o que pode levar a eliminações inesperadas de nós. - Volume de consultas elevado que excede a capacidade da instância
dnsmasqno agrupamentokube-dns. Uma única instânciakube-dnstem um limite de 200 ligações TCP simultâneas na versão 1.31 e posteriores do GKE, e um limite de 20 ligações TCP simultâneas na versão 1.30 e anteriores do GKE.
Para melhorar os tempos de procura de DNS, faça o seguinte:
- Evite executar componentes críticos do sistema, como
kube-dns, em VMs de Spot ou VMs preemptíveis. Crie, pelo menos, um node pool com VMs padrão e sem VMs Spot nem VMs preemptivas. Use restrições e tolerâncias para ajudar a garantir que as cargas de trabalho críticas são agendadas nestes nós fiáveis. - Ative o NodeLocal
DNSCache. O NodeLocal
DNSCache armazena em cache as respostas DNS diretamente em cada nó, o que reduz a latência
e a carga no serviço
kube-dns. Se ativar o NodeLocal DNSCache e usar políticas de rede com regras de negação predefinidas, adicione uma política para permitir que as cargas de trabalho enviem consultas DNS para os pods.node-local-dns - Aumente a escala
kube-dns. - Certifique-se de que a sua aplicação usa funções baseadas em
dns.resolve*em vez de funções baseadas emdns.lookup, porquedns.lookupé síncrono. - Use nomes do domínio totalmente qualificados (FQDNs), por exemplo,
https://google.com./em vez dehttps://google.com/.
Podem ocorrer falhas de resolução de DNS durante as atualizações do cluster do GKE devido a atualizações simultâneas de componentes do plano de controlo, incluindo o kube-dns.
Normalmente, estas falhas afetam uma pequena percentagem de nós. Teste exaustivamente as atualizações de clusters num ambiente de não produção antes de as aplicar a clusters de produção.
Garanta a deteção de serviços
kube-dns só cria registos de DNS para serviços que tenham pontos finais. Se um serviço não tiver pontos finais, o kube-dns não cria registos DNS para esse serviço.
Faça a gestão das discrepâncias de TTL de DNS
Se kube-dns receber uma resposta DNS de um resolvedor DNS a montante com um TTL grande ou infinito, mantém este valor de TTL. Este comportamento pode criar uma discrepância entre a entrada em cache e o endereço IP real.
O GKE resolve este problema em versões específicas do plano de controlo, como 1.21.14-gke.9100 e posteriores ou 1.22.15-gke.2100 e posteriores. Estas versões definem um valor TTL máximo de 30 segundos para qualquer resposta DNS que tenha um TTL superior. Este comportamento é semelhante ao NodeLocal DNSCache.
Veja as métricas de kube-dns
Pode obter métricas sobre consultas DNS no seu cluster diretamente dos
kube-dns pods.
Encontre os
kube-dnspodskube-systemno espaço de nomeskube-system:kubectl get pods -n kube-system --selector=k8s-app=kube-dnsO resultado é 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 47mEscolha um dos pods e configure o encaminhamento de portas para aceder às métricas desse pod:
- A porta
10055expõe as métricaskube-dns. - A porta
10054expõe as métricasdnsmasq.
Substitua
POD_NAMEpelo nome do Pod escolhido.POD_NAME="kube-dns-548976df6c-98fkd" # Replace with your pod name kubectl port-forward pod/${POD_NAME} -n kube-system 10055:10055 10054:10054O resultado é semelhante ao seguinte:
Forwarding from 127.0.0.1:10054 -> 10054 Forwarding from 127.0.0.1:10055 -> 10055- A porta
Numa nova sessão de terminal, use o comando
curlpara aceder aos endpoints de métricas.# Get kube-dns metrics curl http://127.0.0.1:10055/metrics # Get dnsmasq metrics curl http://127.0.0.1:10054/metricsO 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?
- Leia uma vista geral do DNS do cluster no GKE.
- Leia o artigo DNS para serviços e pods para uma vista geral de como o DNS é usado em clusters do Kubernetes.
- Saiba como configurar a NodeLocal DNSCache.
- Saiba como configurar uma implementação do kube-dns personalizada.