Se esegui applicazioni nei cluster Standard, kube-dns è il provider DNS predefinito che ti aiuta ad abilitare il Service Discovery e la comunicazione. Questo documento descrive come gestire il DNS con kube-dns, inclusi la sua architettura, la configurazione e le best practice per ottimizzare la risoluzione DNS nel tuo ambiente GKE.
Questo documento è rivolto a sviluppatori, amministratori e architetti responsabili della gestione del DNS in GKE. Per il contesto sui ruoli comuni e le attività in Google Cloud, consulta Ruoli e attività utente comuni di GKE e attività.
Prima di iniziare, assicurati di conoscere i servizi Kubernetes e i concetti DNS generali.
Informazioni sull'architettura di kube-dns
kube-dns opera all'interno del cluster GKE per abilitare la risoluzione DNS tra pod e servizi.
Il seguente diagramma mostra come i pod interagiscono con il servizio kube-dns:
Componenti chiave
kube-dns include i seguenti componenti chiave:
- Pod
kube-dns: questi pod eseguono il software del serverkube-dns. Più repliche di questi pod vengono eseguite nello spazio dei nomikube-systeme forniscono alta affidabilità e ridondanza. - Servizio
kube-dns: la seguente tabella confronta i limiti di scalabilità e configurazione delle versioni legacy e basate su CoreDNS dikube-dns:Funzionalità Legacy (kube-dns 1.35 e versioni precedenti) kube-dns su CoreDNS (1.36 e versioni successive) Rilevamento degli endpoint Rileva fino a 1000 endpoint per servizio. Se un servizio ha più di 1000 pod, kube-dns non rileva gli endpoint aggiuntivi. Rileva tutti gli endpoint. Questa versione utilizza EndpointSlice per garantire la correttezza e migliorare l'efficienza per i servizi di grandi dimensioni. Server dei nomi upstream Limitato a 3 Supporta fino a 15 Connessioni TCP in uscita simultanee Limitato a 200 Supporta fino a 1500 kube-dns-autoscaler: questo pod regola il numero di replichekube-dnsin base alle dimensioni del cluster, incluso il numero di nodi e core della CPU. Questo approccio aiuta a garantire chekube-dnspossa gestire carichi di query DNS variabili.
Risoluzione DNS interna
Quando un pod deve risolvere un nome DNS all'interno del dominio del cluster, ad esempio myservice.my-namespace.svc.cluster.local, si verifica la seguente procedura:
- Configurazione DNS del pod: il
kubeletsu ogni nodo configura il file/etc/resolv.confdel pod. Questo file utilizza ilClusterIPdel serviziokube-dnscome server dei nomi. - Query DNS: il pod invia una query DNS al servizio
kube-dns. Risoluzione dei nomi:
- GKE versione 1.36 o successive: l'implementazione basata su CoreDNS utilizza EndpointSlice in modo che
kube-dnssia a conoscenza di tutti i pod in un servizio. Ciò migliora la correttezza e l'efficienza per i servizi su larga scala. - GKE versione 1.35 o precedenti:
kube-dnsrisolve i nomi in base alla versione precedente dell'API Cloud Endpoints, che è limitata a 1000 endpoint. Se un servizio ha più di 1000 pod di backup,kube-dnsnon rileva gli endpoint aggiuntivi.
- GKE versione 1.36 o successive: l'implementazione basata su CoreDNS utilizza EndpointSlice in modo che
Comunicazione: il pod utilizza l'indirizzo IP risolto per comunicare con il servizio di destinazione.
Risoluzione DNS esterna
Quando un pod deve risolvere un nome DNS esterno o un nome al di fuori del dominio del cluster, kube-dns funge da resolver ricorsivo. Inoltra la query
ai server DNS upstream configurati nel suo
ConfigMap
file. Puoi anche configurare resolver personalizzati per domini specifici, noti anche come domini stub. Questa configurazione indica a kube-dns di inoltrare le richieste per questi domini a server DNS upstream specifici.
Configurare il DNS dei pod
In GKE, l'agente kubelet su ogni nodo configura le impostazioni DNS per i pod in esecuzione su quel nodo.
Configurare il file /etc/resolv.conf
Quando GKE crea un pod, l'agente kubelet modifica il file /etc/resolv.conf del pod. Questo file configura il server DNS per la risoluzione dei nomi e specifica i domini di ricerca. Per impostazione predefinita, kubelet configura il pod in modo che utilizzi il servizio DNS interno del cluster, kube-dns, come server dei nomi. Popola anche i domini di ricerca nel file. Questi domini di ricerca ti consentono di utilizzare nomi non qualificati nelle query DNS. Ad esempio, se un pod esegue una query su myservice,
Kubernetes tenta prima di risolvere myservice.default.svc.cluster.local, poi
myservice.svc.cluster.local e poi altri domini dall'elenco search.
L'esempio seguente mostra una configurazione predefinita di /etc/resolv.conf:
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
Questo file contiene le seguenti voci:
nameserver: definisce ilClusterIPdel serviziokube-dns.search: definisce i domini di ricerca che vengono aggiunti ai nomi non qualificati durante le ricerche DNS.options ndots:5: imposta la soglia per cui GKE considera un nome come completo. Un nome è considerato completo se contiene cinque o più punti.
I pod configurati con hostNetwork: true ereditano la configurazione DNS dall'host e non eseguono query direttamente su kube-dns, a meno che non utilizzino dnsPolicy ClusterFirstWithHostNet.
Personalizzare kube-dns
kube-dns fornisce una risoluzione DNS predefinita robusta. Puoi personalizzarne il comportamento per esigenze specifiche, ad esempio migliorare l'efficienza della risoluzione o utilizzare i resolver DNS preferiti. Sia i domini stub sia i server dei nomi upstream vengono configurati modificando il ConfigMap kube-dns nello spazio dei nomi kube-system.
Modificare il ConfigMap kube-dns
Per modificare il ConfigMap kube-dns:
Apri il ConfigMap per la modifica:
kubectl edit configmap kube-dns -n kube-systemNella sezione
data, aggiungi i campistubDomainseupstreamNameserverscome segue: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 "8.8.4.4" # Google Public DNS Backup ]Salva il ConfigMap.
kube-dnsricarica automaticamente la configurazione.
Domini stub
I domini stub consentono di definire resolver DNS personalizzati per domini specifici. Quando un pod esegue una query per un nome all'interno di quel dominio stub, kube-dns inoltra la query al resolver specificato anziché utilizzare il meccanismo di risoluzione predefinito.
Includi una sezione stubDomains nel ConfigMap kube-dns.
Questa sezione specifica il dominio e i server dei nomi upstream corrispondenti.
kube-dns inoltra quindi le query per i nomi all'interno di quel dominio ai server designati. Ad esempio, puoi indirizzare tutte le query DNS per internal.mycompany.com
a 192.168.0.10, aggiungendo "internal.mycompany.com": ["192.168.0.10"] a
stubDomains.
Quando imposti un resolver personalizzato per un dominio stub, ad esempio example.com,
kube-dns inoltra tutte le richieste di risoluzione dei nomi per quel dominio, inclusi i
sottodomini come *.example.com, ai server specificati.
Server dei nomi upstream
Puoi configurare kube-dns in modo che utilizzi server dei nomi upstream personalizzati per risolvere i nomi di dominio esterni. Questa configurazione indica a kube-dns di inoltrare tutte le richieste DNS, ad eccezione delle richieste per il dominio interno del cluster (*.cluster.local), ai server upstream designati. I domini interni come metadata.internal e *.google.internal potrebbero non essere risolvibili dai server upstream personalizzati. Se abiliti
Workload Identity Federation for GKE o
hai workload che dipendono da questi domini, aggiungi un dominio stub per internal in
the ConfigMap. Utilizza 169.254.169.254, l'indirizzo IP del server di metadati, come resolver per questo dominio stub.
Gestire un deployment kube-dns personalizzato
In un cluster Standard, kube-dns viene eseguito come deployment. Un deployment kube-dns personalizzato significa che tu, in qualità di amministratore del cluster, puoi controllare il deployment e personalizzarlo in base alle tue esigenze, anziché utilizzare il deployment predefinito fornito da GKE.
Motivi per un deployment personalizzato
Prendi in considerazione un deployment kube-dns personalizzato per i seguenti motivi:
- Allocazione delle risorse: ottimizza le risorse di CPU e memoria per i pod
kube-dnsper ottimizzare le prestazioni nei cluster con traffico DNS elevato. - Versione dell'immagine: utilizza una versione specifica dell'immagine
kube-dnso passa a un provider DNS alternativo come CoreDNS. - Configurazione avanzata: personalizza i livelli di logging, le policy di sicurezza e il comportamento di memorizzazione nella cache DNS.
Scalabilità automatica per i deployment personalizzati
kube-dns-autoscaler integrato funziona con il deployment kube-dns predefinito.
Se crei un deployment kube-dns personalizzato, lo strumento di scalabilità automatica integrato non lo gestisce. Pertanto, devi configurare uno strumento di scalabilità automatica separato configurato specificamente per monitorare e regolare il numero di repliche del deployment personalizzato.
Questo approccio prevede la creazione e il deployment della tua configurazione di scalabilità automatica nel cluster.
Quando gestisci un deployment personalizzato, sei responsabile di tutti i suoi componenti, ad esempio di mantenere aggiornata l'immagine dello strumento di scalabilità automatica. L'utilizzo di componenti obsoleti può comportare un peggioramento delle prestazioni o errori DNS.
Per istruzioni dettagliate su come configurare e gestire il tuo kube-dns
deployment, consulta Configurare un deployment kube-dns personalizzato.
Risoluzione dei problemi
Per informazioni sulla risoluzione dei problemi relativi a kube-dns, consulta le seguenti pagine:
- Per suggerimenti su
kube-dnsin GKE, consulta Risolvere i problemi relativi akube-dnsin GKE. - Per suggerimenti generali sulla diagnosi dei problemi DNS di Kubernetes, consulta Eseguire il debugdella risoluzione DNS.
Ottimizzare la risoluzione DNS
Questa sezione descrive i problemi comuni e le best practice per la gestione del DNS in GKE.
Limite dei domini di ricerca dnsConfig di un pod
Kubernetes limita il numero di domini di ricerca DNS a 32. Se tenti di definire più di 32 domini di ricerca in dnsConfig di un pod, kube-apiserver non creerà il pod e verrà visualizzato un errore simile al seguente:
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.
kube-apiserver restituisce questo messaggio di errore in risposta a un tentativo di creazione del pod. Per risolvere il problema, rimuovi i percorsi di ricerca aggiuntivi dalla configurazione.
Limite di nameservers upstream per kube-dns
Le versioni legacy di kube-dns (versione 1.35 e precedenti) limitano il numero di upstreamNameservers a tre. Se ne definisci più di tre, Cloud Logging visualizza un errore simile al seguente:
Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update
In questo scenario, kube-dns ignora la configurazione upstreamNameservers e continua a utilizzare la configurazione valida precedente. Per risolvere il problema, rimuovi gli upstreamNameservers aggiuntivi dal ConfigMap kube-dns.
Fare lo scale up kube-dns
Nei cluster Standard, puoi utilizzare un valore inferiore per nodesPerReplica in modo che vengano creati più pod kube-dns quando i nodi del cluster fanno lo scale up. Ti consigliamo vivamente di impostare un valore esplicito per il campo max per assicurarti che la macchina virtuale (VM) del piano di controllo GKE non venga sovraccaricata a causa del numero elevato di pod kube-dns che monitorano l'API Kubernetes.
Puoi impostare il valore del campo max sul numero di nodi nel cluster.
Se il cluster ha più di 500 nodi, imposta il valore del campo max su 500.
Puoi modificare il numero di kube-dns repliche modificando il
kube-dns-autoscaler ConfigMap.
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 kube-dns viene calcolato utilizzando la seguente formula:
replicas = max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) )
Per fare lo scale up, modifica il valore del campo nodesPerReplica con un valore inferiore e includi un valore per il campo max.
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'
Questa configurazione crea un pod kube-dns per ogni otto nodi nel cluster. Un cluster di 24 nodi ha tre repliche e un cluster di 40 nodi ha cinque repliche. Se il cluster supera i 120 nodi, il numero di repliche kube-dns non supera 15, che è il valore del campo max.
Per garantire un livello di base di disponibilità DNS nel cluster, imposta un numero minimo di repliche per il campo kube-dns.
L'output per il ConfigMap kube-dns-autoscaler con il campo min configurato è simile al seguente:
linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'
Migliorare i tempi di ricerca DNS
Diversi fattori possono causare una latenza elevata con le ricerche DNS o errori di risoluzione DNS con il provider kube-dns predefinito. Le applicazioni potrebbero riscontrare questi problemi come errori getaddrinfo EAI_AGAIN, che indicano un errore temporaneo nella risoluzione dei nomi. Le cause includono:
- Ricerche DNS frequenti all'interno del workload.
- Densità elevata di pod per nodo.
- Esecuzione di
kube-dnssu VM spot o VM preemptible, che può comportare eliminazioni impreviste dei nodi. - Limiti di connessione: le versioni legacy di
kube-dns(GKE versione 1.35 e precedenti) sono limitate a 200 connessioni TCP simultanee.kube-dnssu CoreDNS (GKE versione 1.36 e successive) rimuove questi limiti fissi per le connessioni in entrata e fornisce una capacità significativamente maggiore per le connessioni in uscita.
Per migliorare i tempi di ricerca DNS:
- Evita di eseguire componenti di sistema critici come
kube-dnssu VM spot o VM preemptible. Crea almeno un pool di nodi con VM standard e senza VM spot o VM preemptible. Utilizza taint e tolleranze per assicurarti che i workload critici siano pianificati su questi nodi affidabili. - Abilita NodeLocal
DNSCache. NodeLocal DNSCache memorizza nella cache le risposte DNS direttamente su ogni nodo, il che riduce la latenza e il carico sul servizio
kube-dns. Se abiliti NodeLocal DNSCache e utilizzi policy di rete con regole di negazione predefinite, aggiungi una policy per consentire ai workload di inviare query DNS ai podnode-local-dns. - Fare lo scale up di
kube-dns. - Assicurati che l'applicazione utilizzi funzioni basate su
dns.resolve*anziché funzioni basate sudns.lookup, perchédns.lookupè sincrono. - Utilizza nomi di dominio completi (FQDN), ad esempio
https://google.com./anzichéhttps://google.com/.
Potrebbero verificarsi errori di risoluzione DNS durante gli upgrade del cluster GKE a causa degli upgrade simultanei dei componenti del control plane, incluso kube-dns.
Questi errori in genere interessano una piccola percentuale di nodi. Esegui test approfonditi degli upgrade del cluster in un ambiente non di produzione prima di applicarli ai cluster di produzione.
Garantire la rilevabilità dei servizi
kube-dns crea record DNS solo per i servizi che hanno endpoint. Se un servizio non ha endpoint, kube-dns non crea record DNS per quel servizio.
Gestire le discrepanze del TTL DNS
Se kube-dns riceve una risposta DNS da un resolver DNS upstream con un TTL elevato o infinito, mantiene questo valore TTL. Questo comportamento può creare una discrepanza tra la voce memorizzata nella cache e l'indirizzo IP effettivo.
GKE risolve questo problema in versioni specifiche del piano di controllo, ad esempio 1.21.14-gke.9100 e successive o 1.22.15-gke.2100 e successive. Queste versioni impostano un valore TTL massimo di 30 secondi per qualsiasi risposta DNS con un TTL più elevato. Questo comportamento è simile a NodeLocal DNSCache.
Visualizzare le metriche kube-dns
Puoi recuperare le metriche sulle query DNS direttamente dai pod kube-dns.
La modalità di recupero di queste metriche dipende dalla versione di GKE.
GKE versione 1.36 e successive
Se il cluster esegue GKE versione 1.36 o successive (kube-dns su CoreDNS), puoi monitorare le prestazioni DNS utilizzando dashboard predefinite in Cloud Monitoring o recuperare manualmente le metriche dai pod.
Visualizzare le metriche nella Google Cloud console
- Nella Google Cloud console, vai alla pagina Dashboard.
- Seleziona la dashboard GKE DNS Observability - Cluster View.
In alternativa, puoi eseguire query su queste metriche direttamente nella Google Cloud console andando a Monitoraggio > Esplora metriche e cercando i nomi delle metriche specifici.
Recuperare le metriche manualmente
Per recuperare manualmente le metriche dal pod:
Trova i pod
kube-dns.kubectl get pods -n kube-system --selector=k8s-app=kube-dnsEsegui il port forwarding della porta 9153 a uno dei pod.
kubectl port-forward pod/POD_NAME -n kube-system 9153:9153Sostituisci
POD_NAMEcon il nome di uno dei podkube-dnsdell'output precedente.Accedi alle metriche.
curl http://127.0.0.1:9153/metrics
GKE versione 1.35 e precedenti
Questa versione di kube-dns utilizza pod multi-container. Per recuperare le metriche:
Trova i pod
kube-dnsnello spazio dei nomikube-system.kubectl get pods -n kube-system --selector=k8s-app=kube-dnsEsegui il port forwarding alle porte 10055 (per il container
kube-dns) e 10054 (per il containerdnsmasq):#For the kube-dns container kubectl port-forward pod/POD_NAME -n kube-system 10055:10055 #For the dnsmasq container kubectl port-forward pod/POD_NAME -n kube-system 10054:10054Sostituisci
POD_NAMEcon il nome di uno dei podkube-dnsdell'output precedente. Esegui questi comandi di port forwarding in sessioni di terminale separate.Accedi alle metriche.
#Metrics from the kube-dns container curl http://127.0.0.1:10055/metrics #Metrics from the dnsmasq container curl http://127.0.0.1:10054/metrics
Passaggi successivi
- Leggi una panoramica del DNS del cluster in GKE.
- Leggi DNS per servizi e pod per una panoramica generale di come viene utilizzato il DNS nei cluster Kubernetes.
- Scopri come configurare NodeLocal DNSCache.
- Scopri come configurare un deployment kube-dns personalizzato.