Se esegui applicazioni in cluster Standard, kube-dns è il
provider DNS predefinito che ti aiuta ad attivare il Service Discovery e la
comunicazione. Questo documento descrive come gestire il DNS con kube-dns,
inclusi architettura, configurazione e best practice per ottimizzare la risoluzione DNS
all'interno dell'ambiente GKE.
Questo documento è rivolto a sviluppatori, amministratori e architetti responsabili della gestione del DNS in GKE. Per informazioni sui ruoli e sulle attività comuni in Google Cloud, consulta Ruoli utente e attività comuni di GKE Enterprise.
Prima di iniziare, assicurati di conoscere i servizi Kubernetes e i concetti generali di DNS.
Informazioni sull'architettura 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:
kube-dnsPod: questi pod eseguono il software del serverkube-dns. Nello spazio dei nomikube-systemvengono eseguite più repliche di questi pod, che forniscono alta disponibilità e ridondanza.- Servizio
kube-dns: questo servizio Kubernetes di tipoClusterIPraggruppa i podkube-dnse li espone come un unico endpoint stabile.ClusterIPfunge da server DNS per il cluster, che i pod utilizzano per inviare query DNS.kube-dnssupporta fino a 1000 endpoint per servizio headless. kube-dns-autoscaler: questo pod regola il numero di repliche dikube-dnsin base alle dimensioni del cluster, che includono il numero di nodi e core della CPU. Questo approccio contribuisce 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:
kubeletsu ogni nodo configura il file/etc/resolv.confdel pod. Questo file utilizzaClusterIPdel serviziokube-dnscome server dei nomi. - Query DNS:il pod invia una query DNS al servizio
kube-dns. - Risoluzione dei nomi:
kube-dnsriceve la query. Cerca l'indirizzo IP corrispondente nei suoi record DNS interni e risponde al pod. - 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 file
ConfigMap. 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.
Configura 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. Inoltre, compila 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 dell'elenco search.
L'esempio seguente mostra una configurazione /etc/resolv.conf predefinita:
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 in base alla quale GKE considera un nome come completo. Un nome è considerato completo se contiene cinque o più punti.
I pod configurati con l'impostazione hostNetwork: true ereditano la configurazione DNS dall'host e non eseguono query direttamente su kube-dns.
Personalizza kube-dns
kube-dns fornisce una risoluzione DNS predefinita solida. Puoi personalizzarne il comportamento
per esigenze specifiche, ad esempio migliorando l'efficienza della risoluzione o utilizzando 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.
Modifica il ConfigMap kube-dns
Per modificare ConfigMap kube-dns:
Apri ConfigMap per la modifica:
kubectl edit configmap kube-dns -n kube-systemNella sezione
data, aggiungi i campistubDomainseupstreamNameserversa: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 ]Salva ConfigMap.
kube-dnsricarica automaticamente la configurazione.
Domini stub
I domini stub ti consentono di definire resolver DNS personalizzati per domini specifici. Quando un pod esegue una query per un nome all'interno di questo dominio stub, kube-dns inoltra la query al resolver specificato anziché utilizzare il meccanismo di risoluzione predefinito.
Includi una sezione stubDomains nel kube-dns ConfigMap.
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, aggiungere "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 per utilizzare server dei nomi upstream personalizzati per risolvere
nomi di dominio esterni. Questa configurazione indica a kube-dns di inoltrare tutte
le richieste DNS, ad eccezione di quelle 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 tuoi
server upstream personalizzati. Se abiliti
Workload Identity Federation for GKE o
hai carichi di lavoro che dipendono da questi domini, aggiungi un dominio stub per internal in
ConfigMap. Utilizza 169.254.169.254, l'indirizzo IP del server di metadati, come resolver per questo dominio stub.
Gestire un deployment personalizzato di kube-dns
In GKE 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
fornito da GKE predefinito.
Motivi per una distribuzione personalizzata
Valuta la possibilità di 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, i criteri di sicurezza e il comportamento di memorizzazione nella cache DNS.
Scalabilità automatica per i deployment personalizzati
kube-dns-autoscaler integrato funziona con l'deployment kube-dns predefinita.
Se crei un deployment kube-dns personalizzato, il gestore della scalabilità automatica integrato non
lo gestisce. Pertanto, devi configurare uno scalatore automatico separato specificamente
configurato per monitorare e regolare il conteggio delle repliche del tuo deployment personalizzato.
Questo approccio prevede la creazione e il deployment della tua configurazione del gestore della scalabilità automatica
nel cluster.
Quando gestisci un deployment personalizzato, sei responsabile di tutti i suoi componenti, ad esempio mantenere aggiornata l'immagine dello scalatore automatico. L'utilizzo di componenti obsoleti può comportare un degrado delle prestazioni o errori DNS.
Per istruzioni dettagliate su come configurare e gestire il tuo deployment kube-dns, vedi Configurazione di 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 la pagina Debug della 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 nel 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 di un pod. Per risolvere il problema, rimuovi i percorsi di ricerca aggiuntivi dalla
configurazione.
Limite di nameservers a monte per kube-dns
kube-dns limita il numero di valori di upstreamNameservers a tre. Se
ne definisci più di tre, Cloud Logging mostra 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
il upstreamNameservers aggiuntivo da kube-dns ConfigMap.
Fai lo scale up di 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 vengono scalati. Ti consigliamo vivamente di impostare un valore esplicito per il campo max per contribuire a garantire che la macchina virtuale (VM) del control plane GKE non sia sovraccarica 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 repliche di kube-dns modificando
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 di kube-dns viene calcolato utilizzando la seguente formula:
replicas = max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) )
Per aumentare la scalabilità, modifica il valore del campo nodesPerReplica impostandolo su 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 del cluster. Un cluster di 24 nodi ha tre repliche e un cluster di 40 nodi ne ha cinque. Se il cluster supera i 120 nodi, il numero di repliche di kube-dns non supera 15, ovvero il valore del campo max.
Per garantire un livello di base di disponibilità DNS nel cluster, imposta un conteggio minimo di repliche per il campo kube-dns.
L'output per kube-dns-autoscaler ConfigMap 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 carico di lavoro.
- Densità elevata di pod per nodo.
- Esecuzione di
kube-dnssu VM spot o VM preemptible, che può comportare eliminazioni impreviste dei nodi. - Volume elevato di query che supera la capacità dell'istanza
dnsmasqall'interno del podkube-dns. Una singola istanzakube-dnsha un limite di 200 connessioni TCP simultanee in GKE versione 1.31 e successive e un limite di 20 connessioni TCP simultanee in GKE versione 1.30 e precedenti.
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 carichi di lavoro critici vengano 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 criteri di rete con regole di negazione predefinite, aggiungi un criterio per consentire ai carichi di lavoro di inviare query DNS ai podnode-local-dns. - Fai lo scale up di
kube-dns. - Assicurati che la tua applicazione utilizzi funzioni basate su
dns.resolve*anziché funzioni basate sudns.lookupperchédns.lookupè sincrono. - Utilizza nomi di dominio completi (FQDN), ad esempio
https://google.com./anzichéhttps://google.com/.
Durante gli upgrade del cluster GKE potrebbero verificarsi errori di risoluzione DNS a causa di upgrade simultanei dei componenti del control plane, incluso kube-dns.
In genere, questi errori interessano una piccola percentuale di nodi. Testa a fondo gli upgrade dei cluster in un ambiente non di produzione prima di applicarli ai cluster di produzione.
Garantire l'individuabilità del servizio
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 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 control plane, 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 superiore. Questo comportamento è simile a NodeLocal DNSCache.
Visualizza le metriche di kube-dns
Puoi recuperare le metriche sulle query DNS nel cluster direttamente dai
pod kube-dns.
Trova i pod
kube-dnsnello spazio dei nomikube-system:kubectl get pods -n kube-system --selector=k8s-app=kube-dnsL'output è simile al seguente:
NAME READY STATUS RESTARTS AGE kube-dns-548976df6c-98fkd 4/4 Running 0 48m kube-dns-548976df6c-x4xsh 4/4 Running 0 47mScegli uno dei pod e configura il port forwarding per accedere alle metriche da quel pod:
- La porta
10055espone le metrichekube-dns. - La porta
10054espone le metrichednsmasq.
Sostituisci
POD_NAMEcon il nome del pod che hai scelto.POD_NAME="kube-dns-548976df6c-98fkd" # Replace with your pod name kubectl port-forward pod/${POD_NAME} -n kube-system 10055:10055 10054:10054L'output è simile al seguente:
Forwarding from 127.0.0.1:10054 -> 10054 Forwarding from 127.0.0.1:10055 -> 10055- La porta
In una nuova sessione del terminale, utilizza il comando
curlper accedere agli endpoint delle metriche.# Get kube-dns metrics curl http://127.0.0.1:10055/metrics # Get dnsmasq metrics curl http://127.0.0.1:10054/metricsL'output sarà simile al seguente:
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
Passaggi successivi
- Leggi una panoramica del DNS del cluster in GKE.
- Leggi la sezione 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.