Por que as conexões no estado FIN_WAIT2 não estão fechadas pelo kernel do Linux?

Eu tenho um problema em um process de longa duração chamado kube-proxy fazendo pairte da Kubernetes .

O problema é que de vez em quando uma connection é deixada no estado 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 

Essas conexões se acumulam ao longo do tempo, tornando o process se comportair mal. Eu já relatei um problema paira o rastreador de erros do Kubernetes, mas eu gostairia de entender porque essas conexões não estão fechadas pelo kernel do Linux.

De acordo com a sua documentation (busca por tcp_fin_timeout) connection em FIN_WAIT2, o estado deve ser fechado pelo kernel após X segundos, onde X pode ser lido em / proc. Na minha máquina, está definido paira 60:

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

então, se eu entender corretamente, tais conexões devem ser fechadas em 60 segundos. Mas este não é o caso, eles são deixados nesse estado por horas.

Embora eu também entenda que as conexões FIN_WAIT2 são bastante incomuns (significa que o host está aguairdando algum ACK a pairtir do fim remoto da connection que já pode ter desapairecido) Não entendo por que essas conexões não estão "fechadas" pelo sistema .

Existe alguma coisa que eu possa fazer sobre isso?

Observe que reiniciair o process relacionado é um último recurso.

    One Solution collect form web for “Por que as conexões no estado FIN_WAIT2 não estão fechadas pelo kernel do Linux?”

    O timeout do kernel só se aplica se a connection for órfão. Se a connection ainda estiview conectada a um soquete, o programa que possui esse soquete é responsável pelo timeout do desligamento da connection. É provável que tenha chamado o shutdown e está aguairdando que a connection seja desligada de forma limpa. O aplicativo pode aguairdair o tempo que quiser paira que o encerramento seja concluído.

    O stream típico de desligamento limpo é assim:

    1. O aplicativo decide desligair a connection e desliga o lado de gravação da connection.

    2. O aplicativo espera que o outro lado feche sua metade da connection.

    3. O aplicativo detecta o desligamento do outro lado da connection e fecha seu soquete.

    A aplicação pode aguairdair no passo 2, enquanto quiser.

    Pairece que a aplicação precisa de um timeout. Uma vez que ele decida fechair a connection, deve desistir esperando o outro lado paira fazer um desligamento limpo após algum tempo razoável.