Почему соединения в состоянии FIN_WAIT2 не закрываются ядром Linux?

У меня проблема с долгоживущим процессом под названием 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

Эти соединения со временем накапливаются, что приводит к неправильной работе процесса. Я уже сообщал о проблеме в баг-трекер Kubernetes, но я Я хочу понять, почему такие соединения не закрываются ядром Linux.

Согласно его документации (поиск tcp_fin_timeout) соединение в состоянии FIN_WAIT2 должно быть закрыто ядром через X секунд, где X может читать из / proc. На моей машине установлено значение 60:

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

, поэтому, если я правильно понимаю, такие соединения должны быть закрыты на 60 секунд. Но это не так, они остаются в таком состоянии в течение нескольких часов.

Хотя я также понимаю, что соединения FIN_WAIT2 довольно необычны (это означает, что хост ожидает некоторого ACK от удаленного конца соединения, которое может уже уйти) Я не понимаю, почему эти соединения не «закрываются» системой.

Могу ли я что-нибудь с этим сделать?

Обратите внимание, что перезапуск связанного процесса - это последнее средство.

11
задан 23 November 2015 в 13:57
2 ответа

Тайм-аут ядра применяется только в том случае, если соединение потеряно. Если соединение все еще подключено к сокету, программа, владеющая этим сокетом, отвечает за тайм-аут отключения соединения. Вероятно, он вызвал выключение и ожидает полного завершения соединения. Приложение может ждать завершения завершения работы сколь угодно долго.

Типичный поток чистого завершения работы выглядит следующим образом:

  1. Приложение решает закрыть соединение и закрывает сторону записи соединения.

  2. ] Приложение ожидает, пока другая сторона завершит свою половину соединения.

  3. Приложение обнаруживает отключение соединения другой стороной и закрывает свой сокет.

Приложение может ждать на шаге 2 столько, сколько оно нравится.

Похоже, приложению требуется тайм-аут. Как только он решает закрыть соединение, он должен перестать ждать, пока другая сторона выполнит полное завершение работы через некоторое разумное время.

14
ответ дан 2 December 2019 в 21:50

Если сокет отключен (), но еще не закрыт (), сокет останется в состоянии FIN_WAIT2. А поскольку приложение по-прежнему владеет файловым дескриптором, ядро ​​не утруждает себя очисткой.

1
ответ дан 2 December 2019 в 21:50

Теги

Похожие вопросы