Configurazione di NodeLocal DNSCache


Questa pagina spiega come migliorare la latenza della ricerca DNS in un cluster Google Kubernetes Engine (GKE) utilizzando NodeLocal DNSCache.

Per i cluster GKE Autopilot, NodeLocal DNSCache è abilitato per impostazione predefinita e non può essere sostituito.

Architettura

NodeLocal DNSCache è un componente aggiuntivo di GKE che puoi eseguire oltre a kube-dns.

GKE implementa NodeLocal DNSCache come DaemonSet che esegue una cache DNS su ogni nodo del cluster.

Quando un pod invia una richiesta DNS, la richiesta viene inviata alla cache DNS in esecuzione sullo stesso nodo del pod. Se la cache non riesce a risolvere la richiesta DNS, la inoltra a una delle seguenti posizioni in base alla destinazione della query:

  • kube-dns: tutte le query per il dominio DNS del cluster (cluster.local) vengono inoltrate a kube-dns. I pod node-local-dns utilizzano il servizio kube-dns-upstream per accedere ai pod kube-dns. Nel seguente diagramma, l'indirizzo IP del servizio kube-dns è 10.0.0.10:53.
  • Domini stub personalizzati o server dei nomi upstream: le query vengono inoltrate direttamente dai pod NodeLocal DNSCache.
  • Cloud DNS: tutte le altre query vengono inoltrate al server di metadati locale in esecuzione sullo stesso node del pod da cui ha avuto origine la query. Il server di metadati locale accede a Cloud DNS.

Il percorso di una richiesta DNS, come descritto nel paragrafo precedente.

Quando attivi NodeLocal DNSCache su un cluster esistente, GKE rielabora tutti i nodi del cluster che eseguono GKE versione 1.15 e successive in base alla procedura di upgrade dei nodi.

Dopo aver ricreato i nodi, GKE li aggiunge automaticamente con l'etichetta addon.gke.io/node-local-dns-ds-ready=true. Non devi aggiungere questa etichetta ai nodi del cluster manualmente.

Vantaggi di NodeLocal DNSCache

NodeLocal DNSCache offre i seguenti vantaggi:

  • Tempo medio di ricerca DNS ridotto
  • Le connessioni dai pod alla loro cache locale non creano voci della tabella conntrack. In questo modo si evitano le connessioni interrotte e rifiutate causate dall'esaurimento della tabella conntrack e dalle condizioni di gara.
  • Puoi utilizzare NodeLocal DNSCache con Cloud DNS per GKE.
  • Le query DNS per gli URL esterni (URL che non fanno riferimento alle risorse del cluster) vengono inoltrate direttamente al server dei metadati Cloud DNS locale, bypassando kube-dns.
  • Le cache DNS locali rilevano automaticamente i domini stub e i server dei nomi upstream specificati nel ConfigMap kube-dns.

Requisiti e limitazioni

  • NodeLocal DNSCache consuma risorse di calcolo su ogni nodo del cluster.
  • NodeLocal DNSCache non è supportato con i node pool Windows Server.
  • NodeLocal DNSCache richiede GKE versione 1.15 o successive.
  • NodeLocal DNSCache accede ai pod kube-dns utilizzando TCP.
  • NodeLocal DNSCache accede a upstreamServers e stubDomains utilizzando TCP e UDP su GKE 1.18 o versioni successive. Il server DNS deve essere raggiungibile utilizzando TCP e UDP.
  • I record DNS vengono memorizzati nella cache per i seguenti periodi:
    • Il valore durata (TTL) del record o 30 secondi se il valore TTL è superiore a 30 secondi.
    • 5 secondi se la risposta DNS è NXDOMAIN.
  • I pod NodeLocal DNSCache ascoltano sulle porte 53, 9253, 9353 e 8080 sui nodi. Se esegui un altro pod hostNetwork o configuri un hostPorts con queste porte, NodeLocal DNSCache non funziona e si verificano errori DNS. I pod NodeLocal DNSCache non utilizzano la modalità hostNetwork quando si utilizza GKE Dataplane V2 e Cloud DNS per GKE.
  • La cache DNS locale viene eseguita solo sui node pool che eseguono GKE versioni 1.15 e successive. Se attivi NodeLocal DNSCache in un cluster con nodi che eseguono versioni precedenti, i pod su questi nodi utilizzano kube-dns.

Abilita NodeLocal DNSCache

Per i cluster Autopilot, NodeLocal DNSCache è abilitato per impostazione predefinita e non può essere sostituito.

Per i cluster standard, puoi attivare NodeLocal DNSCache su cluster nuovi o esistenti utilizzando Google Cloud CLI. Puoi attivare NodeLocal DNSCache nei nuovi cluster utilizzando la console Google Cloud.

Abilita NodeLocal DNSCache in un nuovo cluster

gcloud

Per attivare NodeLocal DNSCache in un nuovo cluster, utilizza il flag --addons con l'argomento NodeLocalDNS:

gcloud container clusters create CLUSTER_NAME \
    --location=COMPUTE_LOCATION \
    --addons=NodeLocalDNS

Sostituisci quanto segue:

Console

Per attivare NodeLocal DNSCache in un nuovo cluster, segui questi passaggi:

  1. Vai alla pagina Google Kubernetes Engine nella console Google Cloud.

    Vai a Google Kubernetes Engine

  2. Accanto a Standard, fai clic su Configura.

  3. Configura il cluster come preferisci.

  4. Nel riquadro di navigazione, fai clic su Networking.

  5. Nella sezione Opzioni di rete avanzate, seleziona la casella di controllo Abilita NodeLocal DNSCache.

  6. Fai clic su Crea.

Abilita NodeLocal DNSCache in un cluster esistente

Per abilitare NodeLocal DNSCache in un cluster esistente, utilizza il --update-addons flag con l'argomento NodeLocalDNS=ENABLED:

gcloud container clusters update CLUSTER_NAME \
    --update-addons=NodeLocalDNS=ENABLED

Sostituisci quanto segue:

  • CLUSTER_NAME: il nome del tuo cluster.

Questa modifica richiede la ricreazione dei nodi, il che può causare interruzioni dei carichi di lavoro in esecuzione. Per informazioni dettagliate su questa modifica specifica, individua la riga corrispondente nella tabella Modifiche manuali che ricreano i nodi utilizzando una strategia di upgrade dei nodi e rispettando le norme di manutenzione. Per scoprire di più sugli aggiornamenti dei nodi, consulta Pianificare le interruzioni per gli aggiornamenti dei nodi.

Verificare che NodeLocal DNSCache sia abilitato

Puoi verificare che NodeLocal DNSCache sia in esecuzione elencando i node-local-dns pod:

kubectl get pods -n kube-system -o wide | grep node-local-dns

L'output è simile al seguente:

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>

L'output mostra un pod node-local-dns per ogni nodo su cui è in esecuzione GKE 1.15 o versioni successive.

Disabilita NodeLocal DNSCache

Puoi disattivare NodeLocal DNSCache utilizzando il seguente comando:

gcloud container clusters update CLUSTER_NAME \
    --update-addons=NodeLocalDNS=DISABLED

Sostituisci quanto segue:

  • CLUSTER_NAME: il nome del cluster da disattivare.

Questa modifica richiede la ricreazione dei nodi, il che può causare interruzioni dei carichi di lavoro in esecuzione. Per informazioni dettagliate su questa modifica specifica, individua la riga corrispondente nella tabella Modifiche manuali che ricreano i nodi utilizzando una strategia di upgrade dei nodi e rispettando le norme di manutenzione. Per scoprire di più sugli aggiornamenti dei nodi, consulta Pianificare le interruzioni per gli aggiornamenti dei nodi.

Risolvere i problemi relativi a NodeLocal DNSCache

Per informazioni generali sulla diagnosi dei problemi di DNS di Kubernetes, consulta Debug della risoluzione DNS.

NodeLocal DNSCache non viene attivato immediatamente

Quando attivi NodeLocal DNSCache su un cluster esistente, GKE potrebbe non aggiornare immediatamente i nodi se il cluster ha una esclusione o una finestra di manutenzione configurata. Per ulteriori informazioni, consulta limitazioni per la ricostituzione dei nodi e le finestre di manutenzione.

Se preferisci non aspettare, puoi applicare manualmente le modifiche ai nodi chiamando il comando gcloud container clusters upgrade e passando il flag --cluster-version con la stessa versione GKE in esecuzione nel pool di nodi. Per questa soluzione alternativa, devi utilizzare Google Cloud CLI.

NodeLocal DNSCache con Cloud DNS

Se utilizzi NodeLocal DNSCache con Cloud DNS, il cluster utilizza l'indirizzo IP del server dei nomi 169.254.20.10, come mostrato nel seguente diagramma:

NodeLocal DNSCache con l&#39;architettura Cloud DNS.

Di conseguenza, l'indirizzo IP del servizio kube-dns potrebbe essere diverso dall'indirizzo IP del server dei nomi utilizzato dai pod. Questa differenza di indirizzi IP è prevista, perché l'indirizzo IP del server dei nomi 169.254.20.10 è necessario per il corretto funzionamento di Cloud DNS.

Per controllare gli indirizzi IP, esegui i seguenti comandi:

  1. Visualizza l'indirizzo IP del servizio kube-dns:

    kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
    

    L'output è l'indirizzo IP di kube-dns, ad esempio 10.0.0.10:53

  2. Apri una sessione di shell nel pod:

    kubectl exec -it POD_NAME -- /bin/bash
    
  3. Nella sessione di shell del pod, leggi i contenuti del file /etc/resolv.conf:

    cat /etc/resolv.conf
    

    L'output è 169.254.20.10

Criterio di rete con NodeLocal DNSCache

Se utilizzi i criteri di rete con NodeLocal DNSCache e non utilizzi Cloud DNS o GKE Dataplane V2, devi configurare regole per consentire ai tuoi carichi di lavoro e ai pod node-local-dns di inviare query DNS.

Utilizza una regola ipBlock nel manifest per consentire la comunicazione tra i tuoi pod e kube-dns.

Il seguente manifest descrive un criterio di rete che utilizza una regola ipBlock:

spec:
  egress:
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP
    to:
    - ipBlock:
        cidr: KUBE_DNS_SVC_CLUSTER_IP/32
  podSelector: {}
  policyTypes:
    - Egress

Sostituisci KUBE_DNS_SVC_CLUSTER_IP con l'indirizzo IP del servizio kube-dns. Puoi ottenere l'indirizzo IP del servizio kube-dns utilizzando il seguente comando:

kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"

Problemi noti

Tempo di attesa DNS in dnsPolicy ClusterFirstWithHostNet quando si utilizza NodeLocal DNSCache e GKE Dataplane V2

Nei cluster che utilizzano GKE Dataplane V2 e NodeLocal DNSCache, i pod con hostNetwork impostato su true e dnsPolicy impostato su ClusterFirstWithHostNet non possono raggiungere i backend DNS del cluster. I log DNS potrebbero contenere voci simili alle seguenti:

nslookup: write to 'a.b.c.d': Operation not permitted

;; connection timed out; no servers could be reached

L'output indica che le richieste DNS non possono raggiungere i server di backend.

Una soluzione alternativa è impostare dnsPolicy e dnsConfig per i pod 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"

Sostituisci quanto segue:

  • NAMESPACE: lo spazio dei nomi del pod hostNetwork.
  • PROJECT_ID: l'ID del tuo progetto Google Cloud.
  • KUBE_DNS_UPSTREAM: l'indirizzo ClusterIP del servizio kube-dns upstream. Puoi ottenere questo valore utilizzando il seguente comando:

    kubectl get svc -n kube-system kube-dns-upstream -o jsonpath="{.spec.clusterIP}"
    

Le richieste DNS dal pod ora possono raggiungere kube-dns e bypassare NodeLocal DNSCache.

Errori di timeout di NodeLocal DNSCache

Nei cluster in cui è abilitato NodeLocal DNSCache, i log potrebbero contenere voci simili alle seguenti:

[ERROR] plugin/errors: 2 <hostname> A: read tcp <node IP: port>-><kubedns IP>:53: i/o timeout

L'output include l'indirizzo IP del servizio kube-dns-upstream Cluster IP. In questo esempio, la risposta a una richiesta DNS non è stata ricevuta da kube-dns in 2 secondi. Ciò potrebbe essere dovuto a uno dei seguenti motivi:

  • Un problema di connettività di rete sottostante.
  • Aumento significativo delle query DNS dal carico di lavoro o a causa dell'upscaling del pool di nodi.

Di conseguenza, i pod kube-dns esistenti non sono in grado di gestire tutte le richieste in tempo. La soluzione alternativa consiste nell'aumentare il numero di repliche di kube-dns regolando i parametri di scalabilità automatica.

Eseguire il ridimensionamento di kube-dns

Puoi utilizzare un valore più basso per nodesPerReplica per assicurarti che vengano creati più pod kube-dns man mano che i nodi del cluster vengono scalati. Ti consigliamo vivamente di impostare un valore max esplicito per assicurarti che la VM (macchina virtuale) del piano di controllo GKE non venga sovraccaricata a causa del numero elevato di pod kube-dns che monitorano l'API Kubernetes.

Puoi impostare max sul numero di nodi del cluster. Se il cluster ha più di 500 nodi, imposta max su 500.

Per i cluster standard, puoi modificare il numero di repliche di kube-dns modificando il ConfigMap kube-dns-autoscaler. Questa configurazione non è supportata nei cluster Autopilot.

kubectl edit configmap kube-dns-autoscaler --namespace=kube-system

L'output è simile al seguente:

linear: '{"coresPerReplica":256, "nodesPerReplica":16,"preventSinglePointFailure":true}'

Il numero di repliche di kube-dns viene calcolato utilizzando la seguente formula:

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

Per aumentare le dimensioni, modifica nodesPerReplica in un valore inferiore e includi un valore max.

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

La configurazione crea un pod kube-dns per ogni 8 nodi del cluster. Un cluster di 24 nodi avrà 3 repliche e un cluster di 40 nodi avrà 5 repliche. Se il cluster supera i 120 nodi, il numero di repliche di kube-dns non supera i 15, il valore max.

Per garantire un livello di disponibilità DNS di riferimento nel cluster, imposta un numero minimo di repliche per kube-dns.

L'output del ConfigMap kube-dns-autoscaler con il campo min sarà simile al seguente:

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

Passaggi successivi