Perché le connessioni nello stato FIN_WAIT2 non sono chiuse dal kernel Linux?


11

Ho un problema in un lungo processo chiamato kube-proxy che fa parte di Kubernetes .

Il problema è che di tanto in tanto una connessione viene lasciata nello stato FIN_WAIT2.

$ sudo netstat -tpn | grep FIN_WAIT2
tcp6       0      0 10.244.0.1:33132        10.244.0.35:48936       FIN_WAIT2   14125/kube-proxy
tcp6       0      0 10.244.0.1:48340        10.244.0.35:56339       FIN_WAIT2   14125/kube-proxy
tcp6       0      0 10.244.0.1:52619        10.244.0.35:57859       FIN_WAIT2   14125/kube-proxy
tcp6       0      0 10.244.0.1:33132        10.244.0.50:36466       FIN_WAIT2   14125/kube-proxy

Queste connessioni si accumulano nel tempo, comportando il malfunzionamento del processo. Ho già segnalato un problema al tracker di bug di Kubernetes ma vorrei capire perché tali connessioni non sono chiuse dal kernel di Linux.

Secondo la sua documentazione (ricerca di tcp_fin_timeout) la connessione nello stato FIN_WAIT2 dovrebbe essere chiusa dal kernel dopo X secondi, dove X può essere letto da / proc. Sulla mia macchina è impostato su 60:

$ cat /proc/sys/net/ipv4/tcp_fin_timeout
60

quindi se ho capito bene tali connessioni dovrebbero essere chiuse per 60 secondi. Ma non è così, rimangono per ore in questo stato.

Anche se capisco anche che le connessioni FIN_WAIT2 sono piuttosto insolite (significa che l'host è in attesa di un ACK dall'estremità remota della connessione che potrebbe già essere andato) Non capisco perché queste connessioni non siano "chiuse" dal sistema .

C'è qualcosa che potrei fare al riguardo?

Si noti che il riavvio del processo correlato è l'ultima risorsa.


1
A proposito, in FIN-WAIT2, la connessione non è in attesa di un ACK (il FIN che ha inviato è già stato riconosciuto, motivo per cui non siamo in FIN-WAIT1). Invece, l'altra estremità ha ancora la possibilità di inviare una quantità illimitata di dati.
Hagen von Eitzen,

Risposte:


14

Il timeout del kernel si applica solo se la connessione è orfana. Se la connessione è ancora collegata a un socket, il programma proprietario di quel socket è responsabile del timeout dell'arresto della connessione. Probabilmente ha chiamato shutdowne sta aspettando che la connessione si chiuda in modo pulito. L'applicazione può attendere fino a quando desidera il completamento dell'arresto.

Il tipico flusso di arresto pulito va in questo modo:

  1. L'applicazione decide di chiudere la connessione e di chiudere il lato di scrittura della connessione.

  2. L'applicazione attende che l'altro lato chiuda la sua metà della connessione.

  3. L'applicazione rileva l'arresto della connessione dell'altro lato e chiude il suo socket.

L'applicazione può attendere al passaggio 2 per tutto il tempo che desidera.

Sembra che l'applicazione abbia bisogno di un timeout. Una volta che decide di chiudere la connessione, dovrebbe smettere di aspettare che l'altro lato effettui un arresto pulito dopo un periodo di tempo ragionevole.


Verificherò queste informazioni con gli sviluppatori di Kubernetes per vedere se tale timeout è implementato. Accetterò la risposta una volta verificata. Tuttavia, grazie per la risposta rapida.
Adam Romanek,

Mi piacerebbe capire la tua risposta in modo più dettagliato. Potresti spiegare cos'è una connessione orfana?
Adam Romanek,

1
@AdamRomanek Una connessione orfana è una connessione senza socket associati, ovvero a cui è possibile accedere solo dal kernel stesso e su cui nessun processo può eseguire un'operazione.
David Schwartz,

Ciò aiuterebbe ... " blog.cloudflare.com/…
John Greene,

2

Se il socket è shutdown (), ma non ancora close (), il socket rimarrà nello stato FIN_WAIT2. E poiché l'applicazione possiede ancora il descrittore di file, il kernel non si preoccuperebbe di ripulire.


Questo è già menzionato nella risposta accettata.
RalfFriedl,

Ho aggiunto specificamente che close () non viene chiamato.
L. Yan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.