I problemi di connettività di rete del cluster Google Kubernetes Engine (GKE) possono causare timeout di connessione, connessioni rifiutate, pod non raggiungibili, interruzioni del servizio o errori di comunicazione tra i pod.
Utilizza questo documento per risolvere i problemi di connettività del cluster acquisendo pacchetti di rete (utilizzando toolbox e tcpdump) e diagnosticando i problemi di rete dei pod.
Queste informazioni sono importanti per gli amministratori e gli operatori della piattaforma e per gli sviluppatori di applicazioni che diagnosticano e risolvono i problemi di rete che interessano i carichi di lavoro GKE. Per ulteriori informazioni sui ruoli comuni e sulle attività di esempio a cui facciamo riferimento nei Google Cloud contenuti, consulta Ruoli e attività comuni degli utenti GKE .
Problemi di connettività relativi all'acquisizione di pacchetti di rete in GKE
Questa sezione descrive come risolvere i problemi di connettività relativi all'acquisizione di pacchetti di rete, inclusi sintomi come timeout di connessione, errori di connessione rifiutata o comportamenti imprevisti dell'applicazione. Questi problemi di connettività possono verificarsi a livello di nodo o di pod.
I problemi di connettività nella rete del cluster rientrano spesso nelle seguenti categorie:
- Pod non raggiungibili: un pod potrebbe non essere accessibile dall'interno o dall'esterno del cluster a causa di configurazioni errate della rete.
- Interruzioni del servizio: un servizio potrebbe subire interruzioni o ritardi.
- Problemi di comunicazione tra i pod: i pod potrebbero non essere in grado di comunicare tra loro in modo efficace.
I problemi di connettività nel cluster GKE possono avere varie cause, tra cui:
- Configurazioni errate della rete: policy di rete, regole firewall, o tabelle di routing errate.
- Bug dell'applicazione: errori nel codice dell'applicazione che influiscono sulle interazioni di rete.
- Problemi di infrastruttura: congestione della rete, guasti hardware o limitazioni delle risorse.
La sezione seguente mostra come risolvere il problema sui nodi o sui pod problematici.
Identifica il nodo su cui è in esecuzione il pod problematico utilizzando il seguente comando:
kubectl get pods POD_NAME -o=wide -n NAMESPACESostituisci quanto segue:
POD_NAMEcon il nome del pod.NAMESPACEcon lo spazio dei nomi Kubernetes.
Connettiti al nodo:
gcloud compute ssh NODE_NAME \ --zone=ZONESostituisci quanto segue:
NODE_NAME: nome del nodo.ZONE: nome della zona in cui è in esecuzione il nodo.
Per eseguire il debug di un pod specifico, identifica l'interfaccia
vethassociata al pod:ip route | grep POD_IPSostituisci
POD_IPcon l'indirizzo IP del pod.Esegui i comandi della toolbox.
Comandi toolbox
toolbox è un'utilità che fornisce un ambiente containerizzato all'interno dei nodi GKE per il debug e la risoluzione dei problemi. Questa sezione descrive come installare l'utilità toolbox e utilizzarla per risolvere i problemi del nodo.
Mentre sei connesso al nodo, avvia lo strumento
toolbox:toolboxVengono scaricati i file che facilitano l'utilità
toolbox.Al prompt principale di
toolbox, installatcpdump:Per i cluster con indirizzi IP esterni o Cloud NAT:
apt update -y && apt install -y tcpdumpPer i cluster privati senza Cloud NAT:
Se hai un cluster privato senza Cloud NAT, non puoi installare
tcpdumputilizzandoapt. Scarica invece i file di releaselibpcapetcpdumpdal repository ufficiale e copiali nella VM utilizzandogcloud compute scpogcloud storage cp. Quindi, installa le librerie manualmente seguendo questi passaggi:# Copy the downloaded packages to a staging area cp /media/root/home/USER_NAME/tcpdump-VERSION.tar.gz /usr/sbin/ cp /media/root/home/USER_NAME/libpcap-VERSION.tar.gz /usr/sbin/ cd /usr/sbin/ # Extract the archives tar -xvzf tcpdump-VERSION.tar.gz tar -xvzf libpcap-VERSION.tar.gz # Build and install libpcap (a dependency for tcpdump) cd libpcap-VERSION ./configure ; make ; make install # Build and install tcpdump cd ../tcpdump-VERSION ./configure ; make ; make install # Verify tcpdump installation tcpdump --versionSostituisci quanto segue:
USER_NAME: il tuo nome utente sul sistema in cui si trovano i file.VERSION: il numero di versione specifico dei pacchettitcpdumpelibpcap.
Avvia l'acquisizione dei pacchetti:
tcpdump -i eth0 -s 100 "port PORT" \ -w /media/root/mnt/stateful_partition/CAPTURE_FILE_NAMESostituisci quanto segue:
PORT: nome del numero di porta.CAPTURE_FILE_NAME: nome del file di acquisizione.
Interrompi l'acquisizione dei pacchetti e interrompi
tcpdump.Esci dalla toolbox digitando
exit.Elenca il file di acquisizione dei pacchetti e controllane le dimensioni:
ls -ltr /mnt/stateful_partition/CAPTURE_FILE_NAMECopia l'acquisizione dei pacchetti dal nodo alla directory di lavoro corrente sul computer:
gcloud compute scp NODE_NAME:/mnt/stateful_partition/CAPTURE_FILE_NAME \ --zone=ZONESostituisci quanto segue:
NODE_NAME: nome del nodo.CAPTURE_FILE_NAME: nome del file di acquisizione.ZONE: nome della zona.
Comandi alternativi
Puoi anche utilizzare i seguenti metodi per risolvere i problemi di connettività sui pod problematici:
Carico di lavoro di debug temporaneo collegato al container del pod.
Esegui una shell direttamente sul pod di destinazione utilizzando
kubectl exec, quindi installa e avvia il comandotcpdump.
Problemi di connettività di rete dei pod
Come indicato nella discussione Panoramica della rete, per risolvere i problemi in modo efficace è importante capire come i pod sono collegati dagli spazi dei nomi di rete allo spazio dei nomi root sul nodo. Per la seguente discussione, se non diversamente specificato, si presuppone che il cluster utilizzi il CNI nativo di GKE anziché quello di Calico. Ciò significa che non è stata applicata alcuna policy di rete.
I pod su alcuni nodi non sono disponibili
Se i pod su alcuni nodi non hanno connettività di rete, assicurati che il bridge Linux sia attivo:
ip address show cbr0
Se il bridge Linux è inattivo, attivalo:
sudo ip link set cbr0 up
Assicurati che il nodo stia apprendendo gli indirizzi MAC dei pod collegati a cbr0:
arp -an
I pod su alcuni nodi hanno una connettività minima
Se i pod su alcuni nodi hanno una connettività minima, devi prima verificare se sono presenti pacchetti persi eseguendo tcpdump nel container della toolbox:
sudo toolbox bash
Installa tcpdump nella toolbox se non l'hai già fatto:
apt install -y tcpdump
Esegui tcpdump su cbr0:
tcpdump -ni cbr0 host HOSTNAME and port PORT_NUMBER and [TCP|UDP|ICMP]
Se sembra che i pacchetti di grandi dimensioni vengano eliminati a valle del bridge (ad esempio, l'handshake TCP viene completato, ma non vengono ricevuti hello SSL ), assicurati che la MTU per ogni interfaccia pod Linux sia impostata correttamente sulla MTU della rete VPC del cluster.
ip address show cbr0
Quando vengono utilizzati overlay (ad esempio, Weave o Flannel), questa MTU deve essere ulteriormente ridotta per tenere conto dell'overhead di incapsulamento sull'overlay.
MTU GKE
La MTU selezionata per un'interfaccia pod dipende dall'interfaccia di rete container (CNI) utilizzata dai nodi del cluster e dall'impostazione MTU VPC sottostante. Per ulteriori informazioni, consulta Pod.
Il valore MTU dell'interfaccia pod è 1460 o ereditato dall'interfaccia principale del nodo.
| CNI | MTU | GKE Standard |
|---|---|---|
| kubenet | 1460 | Predefinito |
|
kubenet (versione GKE 1.26.1 e successive) |
Ereditato | Predefinito |
| Calico | 1460 |
Abilitato utilizzando Per maggiori dettagli, consulta Controllare la comunicazione tra pod e servizi utilizzando le policy di rete. |
| netd | Ereditato | Abilitato utilizzando uno dei seguenti metodi: |
| GKE Dataplane V2 | Ereditato |
Abilitato utilizzando Per maggiori dettagli, consulta Utilizzare GKE Dataplane V2. |
Connessioni non riuscite intermittenti
Le connessioni da e verso i pod vengono inoltrate da iptables. I flussi vengono monitorati come voci nella tabella conntrack e, quando sono presenti molti carichi di lavoro per nodo, l'esaurimento della tabella conntrack può manifestarsi come un errore. Questi possono essere registrati nella console seriale del nodo, ad esempio:
nf_conntrack: table full, dropping packet
Se riesci a determinare che i problemi intermittenti sono causati dall'esaurimento di conntrack, puoi aumentare le dimensioni del cluster (riducendo così il numero di carichi di lavoro e flussi per nodo) o aumentare nf_conntrack_max:
new_ct_max=$(awk '$1 == "MemTotal:" { printf "%d\n", $2/32; exit; }' /proc/meminfo)
sysctl -w net.netfilter.nf_conntrack_max="${new_ct_max:?}" \
&& echo "net.netfilter.nf_conntrack_max=${new_ct_max:?}" >> /etc/sysctl.conf
Puoi anche utilizzare NodeLocal DNSCache per ridurre le voci di monitoraggio delle connessioni.
"bind: Address already in use " segnalato per un container
Un container in un pod non può essere avviato perché, in base ai log dei container, la porta a cui l'applicazione sta tentando di eseguire il binding è già riservata. Il container è in un loop di arresto anomalo. Ad esempio, in Cloud Logging:
resource.type="container"
textPayload:"bind: Address already in use"
resource.labels.container_name="redis"
2018-10-16 07:06:47.000 CEST 16 Oct 05:06:47.533 # Creating Server TCP listening socket *:60250: bind: Address already in use
2018-10-16 07:07:35.000 CEST 16 Oct 05:07:35.753 # Creating Server TCP listening socket *:60250: bind: Address already in use
Quando Docker si arresta in modo anomalo, a volte un container in esecuzione viene lasciato indietro e diventa obsoleto. Il processo è ancora in esecuzione nello spazio dei nomi di rete allocato per il pod ed è in ascolto sulla sua porta. Poiché Docker e kubelet non conoscono il container obsoleto, tentano di avviare un nuovo container con un nuovo processo, che non è in grado di eseguire il binding sulla porta perché viene aggiunto allo spazio dei nomi di rete già associato al pod.
Per diagnosticare questo problema:
Devi avere l'UUID del pod nel campo
.metadata.uuid:kubectl get pod -o custom-columns="name:.metadata.name,UUID:.metadata.uid" ubuntu-6948dd5657-4gsgg name UUID ubuntu-6948dd5657-4gsgg db9ed086-edba-11e8-bdd6-42010a800164Recupera l'output dei seguenti comandi dal nodo:
docker ps -a ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep [Pod UUID]Controlla i processi in esecuzione da questo pod. Poiché gli UUID degli spazi dei nomi cgroup contengono l'UUID del pod, puoi cercare l'UUID del pod nell'output di
ps. Cerca anche la riga precedente, in modo da avere anche i processidocker-containerd-shimcon l'ID container nell'argomento. Taglia il resto della colonna cgroup per ottenere un output più semplice:# ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep -B 1 db9ed086-edba-11e8-bdd6-42010a800164 | sed s/'blkio:.*'/''/ 1283089 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim 276e173b0846e24b704d4 12: 1283107 1283089 Ss sys_pause 4026532393 pause /pause 12: 1283150 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim ab4c7762f5abf40951770 12: 1283169 1283150 Ss do_wait 4026532393 sh /bin/sh -c echo hello && sleep 6000000 12: 1283185 1283169 S hrtimer_nanosleep 4026532393 sleep sleep 6000000 12: 1283244 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim 44e76e50e5ef4156fd5d3 12: 1283263 1283244 Ss sigsuspend 4026532393 nginx nginx: master process nginx -g daemon off; 12: 1283282 1283263 S ep_poll 4026532393 nginx nginx: worker processDa questo elenco puoi visualizzare gli ID container, che dovrebbero essere visibili anche in
docker ps.In questo caso:
docker-containerd-shim 276e173b0846e24b704d4per la pausadocker-containerd-shim ab4c7762f5abf40951770per sh con sleep (sleep-ctr)docker-containerd-shim 44e76e50e5ef4156fd5d3per nginx (echoserver-ctr)
Controlla quelli nell'output di
docker ps:# docker ps --no-trunc | egrep '276e173b0846e24b704d4|ab4c7762f5abf40951770|44e76e50e5ef4156fd5d3' 44e76e50e5ef4156fd5d383744fa6a5f14460582d0b16855177cbed89a3cbd1f registry.k8s.io/echoserver@sha256:3e7b182372b398d97b747bbe6cb7595e5ffaaae9a62506c725656966d36643cc "nginx -g 'daemon off;'" 14 hours ago Up 14 hours k8s_echoserver-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0 ab4c7762f5abf40951770d3e247fa2559a2d1f8c8834e5412bdcec7df37f8475 ubuntu@sha256:acd85db6e4b18aafa7fcde5480872909bd8e6d5fbd4e5e790ecc09acc06a8b78 "/bin/sh -c 'echo hello && sleep 6000000'" 14 hours ago Up 14 hours k8s_sleep-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0 276e173b0846e24b704d41cf4fbb950bfa5d0f59c304827349f4cf5091be3327 registry.k8s.io/pause-amd64:3.1In condizioni normali, tutti gli ID container di
psvengono visualizzati indocker ps. Se non ne vedi uno, si tratta di un container obsoleto e probabilmente vedrai un processo figlio deldocker-containerd-shim processin ascolto sulla porta TCP che viene segnalata come già in uso.Per verificarlo, esegui
netstatnello spazio dei nomi di rete del container. Recupera il PID di qualsiasi processo container (quindi NONdocker-containerd-shim) per il pod.Dall'esempio precedente:
- 1283107 - pausa
- 1283169 - sh
- 1283185 - sleep
- 1283263 - nginx master
- 1283282 - nginx worker
# nsenter -t 1283107 --net netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast gke-zonal-110-default-pool-fe00befa-n2hx ~ # nsenter -t 1283169 --net netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mastPuoi anche eseguire
netstatutilizzandoip netns, ma devi collegare manualmente lo spazio dei nomi di rete del processo, poiché Docker non esegue il collegamento:# ln -s /proc/1283169/ns/net /var/run/netns/1283169 gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns list 1283169 (id: 2) gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns exec 1283169 netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast gke-zonal-110-default-pool-fe00befa-n2hx ~ # rm /var/run/netns/1283169
Mitigazione:
La mitigazione a breve termine consiste nell'identificare i processi obsoleti con il metodo descritto in precedenza e terminare i processi utilizzando il comando kill [PID].
La mitigazione a lungo termine prevede l'identificazione del motivo per cui Docker si arresta in modo anomalo e la risoluzione del problema. Le possibili cause includono:
- Processi zombie che si accumulano, quindi esaurimento degli spazi dei nomi PID
- Bug in Docker
- Pressione delle risorse / OOM
Passaggi successivi
Per informazioni generali sulla diagnosi dei problemi DNS di Kubernetes, consulta Debug della risoluzione DNS.
Se non riesci a trovare una soluzione al tuo problema nella documentazione, consulta Richiedere assistenza per ulteriore aiuto, inclusi consigli sui seguenti argomenti:
- Aprire una richiesta di assistenza contattando l'assistenza clienti Google Cloud.
- Richiedere assistenza alla community ponendo
domande su Stack Overflow
e utilizzando il tag
google-kubernetes-engineper cercare problemi simili. Puoi anche unirti al#kubernetes-enginecanale Slack per ulteriore assistenza dalla community. - Aprire problemi o richieste di funzionalità utilizzando lo strumento di monitoraggio dei problemi pubblico.