Compartilhar via


Personalizar o CoreDNS com o Serviço de Kubernetes do Azure

O AKS (Serviço Kubernetes do Azure) usa o projeto CoreDNS para a resolução e o gerenciamento de DNS do cluster com todos os clusters 1.12. x e superiores. Para mais informações sobre a personalização do CoreDNS e Kubernetes, consulte a documentação oficial upstream.

O AKS é um serviço gerenciado, portanto, você não pode modificar a configuração principal do CoreDNS (um CoreFile). Em vez disso, você usa um ConfigMap do Kubernetes para substituir as configurações padrão. Para ver os ConfigMaps padrão de CoreDNS do AKS, use o comando kubectl get configmaps --namespace=kube-system coredns -o yaml.

Este artigo mostra como usar o ConfigMaps para as opções básicas de personalização do CoreDNS no AKS. Essa abordagem difere da configuração do CoreDNS em outros contextos, como o CoreFile.

Observação

Anteriormente, kube-dns era usado para gerenciamento e resolução de DNS no cluster, mas agora foi preterido. Em kube-dns, são oferecidas diferentes Opções de personalização por meio de um mapa de configurações do Kubernetes. O CoreDNS não é compatível com versões anteriores do kube-dns. Todas as personalizações que você usou anteriormente precisam ser atualizadas para o CoreDNS.

Antes de começar

  • Este artigo considera que já existe um cluster do AKS. Se você precisar de um cluster do AKS, crie um usando a CLI do Azure, o Azure PowerShell ou o portal do Azure.
  • Verifique a versão do CoreDNS que você está executando. Os valores de configuração podem ser alterados entre as versões.
  • Ao criar configurações como os exemplos abaixo, seus nomes na seção dados devem terminar em .server ou .override. Essa convenção de nomenclatura é definida no ConfigMap do CoreDNS do AKS padrão, que você pode visualizar usando o comando kubectl get configmaps --namespace=kube-system coredns -o yaml.

Suporte ao plug-in

Todos os plug-ins CoreDNS internos são compatíveis. Nenhum complemento/plug-in de terceiros é compatível.

Reescrita de DNS

Você pode personalizar o CoreDNS com o AKS para executar reescritas de nome DNS em tempo real.

  1. Crie um arquivo chamado corednsms.yaml e cole a seguinte configuração de exemplo. Substitua <domain to be rewritten> pelo seu próprio nome de domínio totalmente qualificado.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: |
        <domain to be rewritten>.com:53 {
        log
        errors
        rewrite stop {
          name regex (.*)\.<domain to be rewritten>\.com {1}.default.svc.cluster.local
          answer name (.*)\.default\.svc\.cluster\.local {1}.<domain to be rewritten>.com
        }
        forward . /etc/resolv.conf # you can redirect this to a specific DNS server such as 10.0.0.10, but that server must be able to resolve the rewritten domain name
        }
    

    Importante

    Se você redirecionar para um servidor DNS, como o IP do serviço CoreDNS, esse servidor DNS precisará ser capaz de resolver o nome de domínio reescrito.

  2. Crie o ConfigMap usando o comando kubectl apply configmap e especifique o nome do seu manifesto YAML.

    kubectl apply -f corednsms.yaml
    
  3. Verifique se as personalizações foram aplicadas usando o kubectl get configmaps e especifique o ConfigMap coredns-custom.

    kubectl get configmaps --namespace=kube-system coredns-custom -o yaml
    
  4. Para recarregar o ConfigMap e habilitar o Agendador do Kubernetes para reiniciar o CoreDNS sem tempo de inatividade, execute uma reinicialização gradual usando kubectl rollout restart.

    kubectl -n kube-system rollout restart deployment coredns
    

Servidor de encaminhamento personalizado

Se você precisar especificar um servidor de encaminhamento para o tráfego de rede, poderá criar um ConfigMap para personalizar o DNS.

  1. Crie um arquivo chamado corednsms.yaml e cole a seguinte configuração de exemplo. Substitua o nome forward e o endereço pelos valores do seu próprio ambiente.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: | # you may select any name here, but it must end with the .server file extension
        <domain to be rewritten>.com:53 {
            forward foo.com 1.1.1.1
        }
    
  2. Crie o ConfigMap usando o comando kubectl apply configmap e especifique o nome do seu manifesto YAML.

    kubectl apply -f corednsms.yaml
    
  3. Para recarregar o ConfigMap e habilitar o Agendador do Kubernetes para reiniciar o CoreDNS sem tempo de inatividade, execute uma reinicialização gradual usando kubectl rollout restart.

    kubectl -n kube-system rollout restart deployment coredns
    

Usar domínios personalizados

Talvez você queira configurar domínios personalizados que só podem ser resolvidos internamente. Por exemplo, talvez você queira resolver o domínio personalizado puglife.local, que não é um domínio primário. Sem um ConfigMap de domínio personalizado, o cluster do AKS não pode resolver o endereço.

  1. Crie um novo arquivo chamado corednsms.yaml e cole a seguinte configuração de exemplo. Certifique-se de atualizar o domínio personalizado e o endereço IP com os valores do seu próprio ambiente.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      puglife.server: | # you may select any name here, but it must end with the .server file extension
        puglife.local:53 {
            errors
            cache 30
            forward . 192.11.0.1  # this is my test/dev DNS server
        }
    
  2. Crie o ConfigMap usando o comando kubectl apply configmap e especifique o nome do seu manifesto YAML.

    kubectl apply -f corednsms.yaml
    
  3. Para recarregar o ConfigMap e habilitar o Agendador do Kubernetes para reiniciar o CoreDNS sem tempo de inatividade, execute uma reinicialização gradual usando kubectl rollout restart.

    kubectl -n kube-system rollout restart deployment coredns 
    

Domínios stub

O CoreDNS também pode ser usado para configurar domínios stub.

  1. Crie um arquivo chamado corednsms.yaml e cole a seguinte configuração de exemplo. Certifique-se de atualizar os domínios personalizados e os endereços IP com os valores do seu próprio ambiente.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: | # you may select any name here, but it must end with the .server file extension
        abc.com:53 {
         errors
         cache 30
         forward . 1.2.3.4
        }
        my.cluster.local:53 {
            errors
            cache 30
            forward . 2.3.4.5
        }
    
    
  2. Crie o ConfigMap usando o comando kubectl apply configmap e especifique o nome do seu manifesto YAML.

    kubectl apply -f corednsms.yaml
    
  3. Para recarregar o ConfigMap e habilitar o Agendador do Kubernetes para reiniciar o CoreDNS sem tempo de inatividade, execute uma reinicialização gradual usando kubectl rollout restart.

    kubectl -n kube-system rollout restart deployment coredns
    

Plug-in de hosts

Todos os plug-ins internos são compatíveis, portanto, os plug-in dos hosts CoreDNS também estão disponíveis para personalizar os /etc/hosts.

  1. Crie um arquivo chamado corednsms.yaml e cole a seguinte configuração de exemplo. Certifique-se de atualizar os domínios personalizados e os endereços de IP com os valores do seu próprio ambiente.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom # this is the name of the configmap you can overwrite with your changes
      namespace: kube-system
    data:
        test.override: | # you may select any name here, but it must end with the .override file extension
              hosts { 
                  10.0.0.1 example1.org
                  10.0.0.2 example2.org
                  10.0.0.3 example3.org
                  fallthrough
              }
    
  2. Crie o ConfigMap usando o comando kubectl apply configmap e especifique o nome do seu manifesto YAML.

    kubectl apply -f corednsms.yaml
    
  3. Para recarregar o ConfigMap e habilitar o Agendador do Kubernetes para reiniciar o CoreDNS sem tempo de inatividade, execute uma reinicialização gradual usando kubectl rollout restart.

    kubectl -n kube-system rollout restart deployment coredns
    

Conclusões inválidas de domínios de pesquisa para internal.cloudapp.net e reddog.microsoft.com

O DNS do Azure configura um domínio de pesquisa padrão igual a <vnetId>.<region>.internal.cloudapp.net nas redes virtuais usando o DNS do Azure e um stub não funcional reddog.microsoft.com nas redes virtuais usando servidores DNS personalizados (consulte a documentação sobre resolução de nomes para recursos para obter mais detalhes). O Kubernetes define as configurações de DNS de pod para ndots: 5 a fim de dar suporte adequado à resolução de nomes de host do serviço de cluster. Essas duas configurações se combinam para resultar em consultas de preenchimento de domínio de pesquisa inválido que nunca conseguem ser enviadas para servidores de nomes upstream enquanto o sistema as processa por meio da lista de pesquisa de domínio. Essas consultas inválidas causam atrasos na resolução de nomes e podem colocar carga extra em servidores DNS upstream.

A partir da versão v20241025 do AKS, o AKS configura o CoreDNS para responder com o NXDOMAIN nos dois seguintes casos, a fim de impedir que essas consultas de preenchimento de domínio de pesquisa inválido sejam encaminhadas para o DNS upstream:

  • Qualquer consulta para o domínio raiz ou um subdomínio de reddog.microsoft.com.
  • Qualquer consulta para um subdomínio de internal.cloudapp.net que tenha sete ou mais rótulos no nome de domínio.
    • Essa configuração permite que a resolução de máquina virtual por nome do host ainda seja bem-sucedida. Por exemplo, o CoreDNS envia aks12345.myvnetid.myregion.internal.cloudapp.net (seis rótulos) para o DNS do Azure, mas rejeita mcr.microsoft.com.myvnetid.myregion.internal.cloudapp.net (oito rótulos)

Esse bloco é implementado no bloco de servidor padrão no Corefile para o cluster. Se necessário, essa configuração de rejeição pode ser desabilitada com a criação de blocos de servidor personalizados para o domínio apropriado com um plug-in de encaminhamento habilitado:

  1. Crie um arquivo chamado corednsms.yaml e cole a seguinte configuração de exemplo. Certifique-se de atualizar os domínios personalizados e os endereços de IP com os valores do seu próprio ambiente.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom # this is the name of the configmap you can overwrite with your changes
      namespace: kube-system
    data:
        override-block.server:
           internal.cloudapp.net:53 {
               errors
               cache 30
               forward . /etc/resolv.conf
           }
           reddog.microsoft.com:53 {
               errors
               cache 30
               forward . /etc/resolv.conf
           }
    
  2. Crie o ConfigMap usando o comando kubectl apply configmap e especifique o nome do seu manifesto YAML.

    kubectl apply -f corednsms.yaml
    
  3. Para recarregar o ConfigMap e habilitar o Agendador do Kubernetes para reiniciar o CoreDNS sem tempo de inatividade, execute uma reinicialização gradual usando kubectl rollout restart.

    kubectl -n kube-system rollout restart deployment coredns
    

Solução de problemas

Para ver as etapas gerais da solução de problemas do CoreDNS, como verificar os pontos de extremidade ou a resolução, confira Depurar a resolução de DNS.

Configurar a escala horizontal de pods do CoreDNS

Picos repentinos no tráfego DNS em clusters do AKS são uma ocorrência comum devido à elasticidade que o AKS fornece para cargas de trabalho. Esses picos podem levar a um aumento no consumo de memória por pods CoreDNS. Em alguns casos, esse aumento no consumo de memória pode causar Out of memory problemas. Para antecipar esse problema, os clusters do AKS dimensionam automaticamente pods CoreDNS para reduzir o uso de memória por pod. As configurações padrão para essa lógica de dimensionamento automático são armazenadas no coredns-autoscaler ConfigMap. No entanto, você pode observar que o dimensionamento automático padrão de pods CoreDNS nem sempre é agressivo o suficiente para evitar Out of memory problemas para seus pods CoreDNS. Nesse caso, você pode modificar diretamente o coredns-autoscaler ConfigMap. Observe que simplesmente aumentar o número de pods CoreDNS sem abordar a causa raiz do Out of memory problema pode fornecer apenas uma correção temporária. Se não houver memória suficiente disponível nos nós em que os pods CoreDNS estão em execução, aumentar o número de pods CoreDNS não ajudará. Talvez seja necessário investigar mais e implementar soluções apropriadas, como otimizar o uso de recursos, ajustar solicitações e limites de recursos ou adicionar mais memória aos nós.

O CoreDNS usa o dimensionador automático proporcional de cluster horizontal para dimensionamento automático de pod. O coredns-autoscaler ConfigMap pode ser editado para configurar a lógica de dimensionamento para o número de pods CoreDNS. O coredns-autoscaler ConfigMap atualmente dá suporte a dois valores de chave ConfigMap diferentes: linear e ladder que correspondem a dois modos de controle com suporte. O linear controlador produz um número de réplicas no intervalo [min,max] equivalente a max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) ). O ladder controlador calcula o número de réplicas consultando duas funções de etapa diferentes, uma para dimensionamento de núcleo e outra para dimensionamento de nó, gerando o máximo dos dois valores de réplica. Para obter mais informações sobre os modos de controle e o formato ConfigMap, consulte a documentação do upstream.

Importante

É recomendável um mínimo de 2 réplicas de pod do CoreDNS por cluster. Configurar um mínimo de 1 réplica de pod do CoreDNS pode causar falhas durante operações que exigem esvaziamento de nós, como operações de atualização de cluster.

Para recuperar o ConfigMap coredns-autoscaler, você pode executar o comando kubectl get configmap coredns-autoscaler -n kube-system -o yaml que retornará o seguinte:

apiVersion: v1
data:
  ladder: '{"coresToReplicas":[[1,2],[512,3],[1024,4],[2048,5]],"nodesToReplicas":[[1,2],[8,3],[16,4],[32,5]]}'
kind: ConfigMap
metadata:
  name: coredns-autoscaler
  namespace: kube-system
  resourceVersion: "..."
  creationTimestamp: "..."

Comportamento de dimensionamento automático vertical de pods do CoreDNS

O CoreDNS é um complemento essencial gerenciado pelo AKS e habilitado por padrão. Para manter a disponibilidade do serviço CoreDNS, o CoreDNS mantém o uso das solicitações/limites de recursos fornecidos originais ao habilitar o recurso de dimensionamento automático do complemento para impedir que o processo de reinicialização do pod CoreDNS cause indisponibilidade do serviço.

Para o complemento CoreDNS gerenciado pelo AKS, as solicitações/limites de CPU padrão são definidos em 100m /3 núcleos e solicitações/limites de memória em 70Mi/500Mi. Com base nesses padrões, a taxa de solicitação para limite da CPU é aproximadamente 1:30 e, para memória, é em torno de 1/7. Se as solicitações recomendadas de CPU forem 500m, o VPA ajusta os limites de CPU para 15 para manter essa proporção. Da mesma forma, se as solicitações de memória recomendadas forem 700Mi, a VPA ajustará o limite de memória para 5000Mi.

O VPA define os limites de CPU e memória do CoreDNS para valores grandes com base na solicitação de CPU/Mem recomendada pelo VPA e na taxa de solicitação a limite definida pelo AKS. Esses ajustes são benéficos para lidar com várias solicitações durante os horários de pico do serviço. A desvantagem é que o CoreDNS pode consumir todos os recursos disponíveis de CPU e memória no nó durante o período de pico do serviço.

É difícil definir um único valor ideal de CPU e solicitações/limites de memória para atender aos requisitos do cluster grande e do cluster pequeno ao mesmo tempo. Ao habilitar o dimensionamento do complemento otimizado, você tem a flexibilidade de personalizar a CPU do CoreDNS e solicitações/limites de memória ou usar o VPA para dimensionar automaticamente o CoreDNS para atender aos requisitos específicos do cluster. Veja a seguir alguns cenários a serem considerados:

  • Você está considerando se a VPA é adequada para seu serviço CoreDNS e deseja exibir apenas as recomendações de VPA. Você pode desabilitar a VPA para CoreDNS definindo o modo de atualização da VPA para Desativado se você não quiser que a VPA atualize automaticamente os pods. Personalize a configuração de recursos na Implantação para definir as solicitações/limites de CPU/memória para o valor que você prefere.
  • Você está considerando usar a VPA, mas deseja restringir a taxa de solicitação para limite para que a VPA não reduza o limite de CPU e memória para valores grandes ao mesmo tempo. Você pode personalizar recursos na Implantação e atualizar o valor de solicitações/limites de CPU e memória para manter a taxa de solicitação para limite para 1/2 ou 1/3.
  • Se uma política de contêiner de VPA definir a CPU e a memória máximas, as solicitações de recurso recomendadas não excederão esses limites. Personalizar a configuração de recursos permite que você aumente ou diminua os valores maxAllowed e controle as recomendações da VPA.

Para mais informações, consulte Habilitar o dimensionamento automático de complementos no cluster AKS (versão prévia).

Habilitar o registro em log de consulta DNS

  1. Adicione a seguinte configuração ao ConfigMap coredns-custom:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      log.override: | # you may select any name here, but it must end with the .override file extension
            log
    
  2. Aplique as alterações de configuração e force o CoreDNS a recarregar o ConfigMap usando os seguintes comandos:

    # Apply configuration changes
    kubectl apply -f corednsms.yaml
    
    # Force CoreDNS to reload the ConfigMap
    kubectl -n kube-system rollout restart deployment coredns
    
  3. Exiba o log de depuração do CoreDNS usando o comando kubectl logs.

    kubectl logs --namespace kube-system -l k8s-app=kube-dns
    

Solucionar problemas de desequilíbrio de tráfego do pod CoreDNS

Você pode observar que um ou dois pods CoreDNS mostram um uso de CPU significativamente maior e lidam com mais consultas DNS do que outras, mesmo que vários pods CoreDNS estejam em execução no cluster do AKS. Esse é um problema conhecido no Kubernetes e pode levar a que um dos pods CoreDNS esteja sobrecarregado e falhando.

Essa distribuição desigual de consultas DNS é causada principalmente por limitações de balanceamento de carga UDP no Kubernetes. A plataforma usa um hash de cinco tuplas (IP de origem, porta de origem, IP de destino, porta de destino, protocolo) para distribuir o tráfego UDP, portanto, se um aplicativo reutilizar a mesma porta de origem para consultas DNS, todas as consultas desse cliente serão roteadas para o mesmo pod CoreDNS, resultando em um único pod manipulando uma quantidade desproporcional de tráfego.

Além disso, alguns aplicativos usam o pool de conexões e reutilizam conexões DNS. Esse comportamento pode concentrar ainda mais as consultas DNS em um único pod CoreDNS, agravando o desequilíbrio e aumentando o risco de sobrecarga e possíveis falhas.

Verificando a distribuição de tráfego do pod CoreDNS

Antes de começar, siga as etapas na seção Habilitar registro em log de consultas DNS acima para capturar os logs de consulta DNS necessários dos pods do CoreDNS. Depois que isso estiver habilitado, execute os seguintes comandos:

  1. Execute o seguinte comando para obter os nomes de todos os pods CoreDNS em seu cluster:

    kubectl get pods --namespace kube-system -l k8s-app=kube-dns
    
  2. Examine os logs de cada pod CoreDNS para analisar padrões de consulta DNS:

    kubectl logs --namespace kube-system <coredns-pod1>
    kubectl logs --namespace kube-system <coredns-pod2>
    # Repeat on all CoreDNS pods
    
  3. Procure por endereços IP de cliente repetidos e portas que aparecem apenas nos logs de um único pod CoreDNS. Isso indica que as consultas DNS de determinados clientes não estão sendo distribuídas uniformemente.

    Entrada de log de exemplo:

    [INFO] 10.244.0.247:5556 - 42621 "A IN myservice.default.svc.cluster.local. udp 28" NOERROR qr,aa,rd 106 0.000141s
    
    • 10.244.0.247: endereço IP do cliente que está fazendo a consulta DNS
    • 5556: porta de origem do cliente
    • 42621: ID da consulta

    Se você observar o mesmo IP e porta de cliente repetidamente nos logs de apenas um pod, isso confirma um desequilíbrio de tráfego.

Se você observar esse desequilíbrio, seu aplicativo poderá estar reutilizando portas de origem UDP ou agrupando suas conexões. Com base na causa raiz, você pode executar as seguintes ações de mitigação:

  • Causado pela reutilização da porta de origem UDP:

    A reutilização da porta de origem UDP ocorre quando um aplicativo cliente envia várias consultas DNS da mesma porta de origem UDP. Se esse for o problema, atualize seus aplicativos ou clientes DNS para randomizar as portas de origem para cada consulta DNS, o que ajuda a distribuir as solicitações mais uniformemente entre pods.

  • Causado pelo pool de conexões:
    Pools de conexão são mecanismos usados por aplicativos para reutilizar conexões de rede existentes em vez de criar uma nova conexão para cada solicitação. Embora isso melhore a eficiência, pode resultar em todas as consultas DNS de um aplicativo serem enviadas pela mesma conexão e, portanto, roteadas para o mesmo pod CoreDNS. Para mitigar isso, ajuste o tratamento de conexão DNS do seu aplicativo, reduzindo os TTLs de conexão (Tempo de Vida) ou randomizando a criação de conexões, garantindo que as consultas não fiquem concentradas em um único pod CoreDNS.

Essas alterações podem ajudar a obter uma distribuição de consulta DNS mais equilibrada e reduzir o risco de sobrecarga de pods individuais.

Próximas etapas

Este artigo mostrou alguns cenários de exemplo para a personalização do CoreDNS. Para obter informações sobre o projeto CoreDNS, confira a página de projeto upstream do CoreDNS.

Para saber mais sobre os principais conceitos de rede, confira Conceitos de rede para aplicativos no AKS.