Questa pagina descrive come Google Kubernetes Engine (GKE) implementa Service Discovery utilizzando kube-dns, il provider DNS predefinito per i cluster GKE.
Per i cluster Autopilot, non puoi modificare la configurazione kube-dns predefinita.
Architettura
Quando crei un cluster, GKE esegue automaticamente il deployment dei pod kube-dns
nello spazio dei nomi kube-system
. I pod accedono al deployment di kube-dns tramite
un servizio
corrispondente che raggruppa i pod kube-dns e assegna loro un unico indirizzo IP (ClusterIP).
Per impostazione predefinita, tutti i pod di un cluster utilizzano questo servizio per risolvere le query DNS. Il
seguente diagramma mostra la relazione tra i pod e il servizio kube-dns.
kube-dns viene scalato per soddisfare le richieste DNS del cluster. Questo scalabilità è
controllata da kube-dns-autoscaler
, un pod di cui viene eseguito il deployment per impostazione predefinita in
tutti i cluster GKE. kube-dns-autoscaler
regola il numero di repliche nel deployment kube-dns in base al numero di nodi e core nel cluster.
kube-dns supporta fino a 1000 endpoint per servizio headless.
Come viene configurato il DNS del pod
Kubelet in esecuzione su ogni nodo configura etc/resolv.conf
del pod per
utilizzare ClusterIP del servizio kube-dns. La seguente configurazione di esempio mostra
che l'indirizzo IP del servizio kube-dns è 10.0.0.10
. Questo indirizzo IP è
diverso negli altri cluster.
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
kube-dns è il server dei nomi autorevole per il dominio del cluster (cluster.local)
e risolve i nomi esterni in modo ricorsivo. I nomi brevi non completamente
qualificati, come myservice
, vengono completati prima con i percorsi di ricerca locali.
Aggiunta di resolver personalizzati per i domini stub
Puoi modificare ConfigMap per kube-dns per impostare i domini stub come parte dell'infrastruttura DNS all'interno dei tuoi cluster.
I domini stub ti consentono di configurare resolver personalizzati per dominio in modo che kube-dns inoltri le richieste DNS a server DNS upstream specifici durante la risoluzione di questi domini.
Il seguente manifest ConfigMap di esempio per kube-dns include una configurazione stubDomains
che imposta resolver personalizzati per il dominio example.com.
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",
"1.1.1.1",
"1.0.0.1"
]
}
Esegui questo comando per aprire un editor di testo:
kubectl edit configmap kube-dns -n kube-system
Sostituisci i contenuti del file con il manifest, poi esci dall'editor di testo per applicare il manifest al cluster.
Nameserver upstream
Se modifichi il
ConfigMap
per kube-dns in modo da includere upstreamNameservers
, kube-dns inoltra tutte le richieste DNS
tranne *.cluster.local
a questi server. Sono inclusi
metadata.internal
e *.google.internal
, che non possono essere risolti dal
server upstream.
Se abiliti la
federazione delle identità per i carichi di lavoro per GKE o qualsiasi
carico di lavoro che si basa sulla risoluzione metadata.internal
, per conservare la risoluzione dei nomi *.internal
, aggiungi un stubDomain
a ConfigMap.
data:
stubDomains: |
{
"internal": [
"169.254.169.254"
]
}
upstreamNameservers: |
["8.8.8.8"]
Risoluzione dei problemi
Per informazioni sulla risoluzione dei problemi di kube-dns, consulta le seguenti pagine:
- Per suggerimenti su kube-dns in GKE, consulta Risolvere i problemi di kube-dns in GKE.
- Per suggerimenti generali sulla diagnosi dei problemi DNS di Kubernetes, consulta Debug della risoluzione DNS.
Limitazioni
Leggi le sezioni seguenti per informazioni sulle limitazioni di kube-dns.
Limite di domini di ricerca
Per /etc/resolv.conf
è previsto un limite di sei domini di ricerca DNS. Se
definisci più di sei domini di ricerca, viene visualizzato il seguente avviso quando esegui
il comando kubectl describe pod
:
Search Line limits were exceeded, some search paths have been omitted, the applied search line is: default.svc.cluster.local svc.cluster.local cluster.local c.<project ID>.internal google.internal
Questo avviso viene registrato in Cloud Logging nella sezione dei log dei container.
Per risolvere il problema, rimuovi i percorsi di ricerca aggiuntivi dalla configurazione.
Considera il limite di upstreamNameservers
Kubernetes impone un limite di massimo tre valori upstreamNameservers
. Se definisci più di tre upstreamNameservers
, in Cloud Logging viene visualizzato il seguente errore nei log di deployment di kube-dns
:
Invalid configuration: upstreamNameserver cannot have more than three entries (value was &TypeMeta{Kind:,APIVersion:,}), ignoring update
In questo caso, kube-dns si comporta come se non avesse configurato alcun upstreamNameservers
. Per risolvere il problema, rimuovi l'upstreamNameservers
aggiuntivo dalla configurazione.
Limitazioni delle prestazioni con kube-dns
Se riscontri una latenza elevata con le ricerche DNS o errori di risoluzione DNS con il provider kube-dns predefinito, il problema potrebbe essere causato da:
- Eseguire ricerche DNS frequenti all'interno del carico di lavoro
- Deployment di una densità di pod per nodo più elevata.
- Superamento del limite di 20 query al secondo (QPS) per ogni pod kube-dns.
- L'esecuzione di kube-dns su VM spot o preemptible, che può comportare eliminazioni impreviste di nodi e successivi problemi di risoluzione DNS.
Per migliorare i tempi di ricerca DNS, puoi scegliere una delle seguenti opzioni:
- Evita di eseguire componenti di sistema critici come kube-dns su VM Spot o preemptible. L'utilizzo di VM spot o prerilasciabili per il DNS può causare errori e interrompere il tuo cluster.
- Come best practice, crea almeno un pool di nodi composto da VM standard (non spot o preemptive) per ospitare componenti di sistema critici come kube-dns. Per assicurarti che i carichi di lavoro critici vengano pianificati solo sul pool di nodi affidabile, impedendo loro di essere eseguiti su VM spot o prerilasciabili, puoi utilizzare taint e tolleranze per le VM spot.
- Abilita NodeLocal DNSCache.
- Fai lo scale up di kube-dns.
- Assicurati che la tua applicazione utilizzi funzioni basate su dns.resolve* anziché funzioni basate su dns.lookup, in quanto dns.lookup è sincrona. Le funzioni dns.resolve* eseguono sempre una query DNS asincrona sulla rete.
Record DNS del servizio
kube-dns crea record DNS solo per i servizi che hanno endpoint.
TTL elevato dai server upstream DNS
Se kube-dns riceve una risposta DNS da un resolver DNS upstream con un TTL grande o "infinito", mantiene questo valore TTL per la voce DNS nella cache. La voce non scade mai e potrebbe creare una discrepanza tra la voce e l'indirizzo IP effettivo risolto per il nome TTL.
GKE risolve questo problema nelle seguenti versioni del control plane impostando un valore TTL massimo di 30 secondi per qualsiasi risposta DNS con un TTL superiore a 30 secondi:
- 1.21.14-gke.9100
- 1.22.15-gke.2100
- 1.23.13-gke.500
- 1.24.7-gke.500
- 1.25.2-gke.500 o versioni successive
Questo comportamento è simile a NodeLocal DNSCache.
Registra le metriche di kube-dns o dnsmasq
Puoi ottenere metriche sulle query DNS nel cluster GKE. Questo è un modo rapido per ottenere le metriche di kube-dns o dnsmasq senza modificare il deployment.
Elenca i pod nel deployment kube-dns.
$ kubectl get pods -n kube-system --selector=k8s-app=kube-dns
L'output sarà 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 47m
Scegli un pod e imposta il suo nome su una variabile.
POD="kube-dns-548976df6c-98fkd"
Configura il port forwarding per il pod kube-dns scelto.
$ kubectl port-forward pod/${POD} -n kube-system 10054:10054 10055:10055
L'output sarà simile al seguente:
Forwarding from 127.0.0.1:10054 -> 10054 Forwarding from 127.0.0.1:10055 -> 10055
Recupera le metriche eseguendo il seguente comando curl sull'endpoint.
$ curl http://127.0.0.1:10054/metrics; curl http://127.0.0.1:10055/metrics
La porta 10054 contiene le metriche dnsmasq e la porta 10055 contiene le metriche kube-dns.
L'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 DNS per servizi e pod per una panoramica generale di come viene utilizzato il DNS nei cluster Kubernetes.