为什么FIN_WAIT2状态下的连接没有被Linux内核closures?

我在一个长期的过程中遇到了一个问题: kube-proxy是Kubernetes的一部分。

问题是有时连接处于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 

随着时间的推移,这些连接会累积起来,从而导致stream程失败。 我已经向Kubernetes bug跟踪器报告了一个问题 ,但是我想知道为什么这样的连接没有被Linux内核closures。

根据它的文档 (searchtcp_fin_timeout),FIN_WAIT2状态下的连接应该在X秒后被内核closures,其中X可以从/ proc中读取。 在我的机器上它被设置为60:

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

所以如果我正确地理解这样的连接应该被closures60秒。 但事实并非如此,他们处于这种状态几个小时。

虽然我也明白,FIN_WAIT2连接是非常不寻常的(这意味着主机正在等待从连接的远程端可能已经消失一些确认)我不明白为什么这些连接不被系统“closures” 。

有什么我可以做的吗?

请注意,重新启动相关的过程是最后的手段。

内核超时只适用于连接是孤立的。 如果连接仍然连接到一个套接字,拥有该套接字的程序负责超时closures连接。 可能它已经叫做shutdown并正在等待连接closures干净。 该应用程序可以等待,只要它喜欢closures完成。

典型的干净closuresstream程如下所示:

  1. 应用程序决定closures连接并closures连接的写入端。

  2. 应用程序等待另一端closures其一半的连接。

  3. 应用程序检测到对方closures连接并closures其套接字。

应用程序可以在步骤2等待,只要它喜欢。

这听起来像应用程序需要超时。 一旦它决定closures连接,它应该放弃等待对方在一段合理的时间后干净closures。