FIN_WAIT2 상태의 연결이 Linux 커널에 의해 닫히지 않는 이유는 무엇입니까? . 문제는 때때로 연결이 FIN_WAIT2 상태로

나는라는 수명이 긴 과정에 문제가있는 KUBE-프록시 의 존재의 일부 는 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를 기다리고 있음을 의미합니다) 이러한 연결이 시스템에 의해 “닫히지 않은”이유를 알 수 없습니다 .

내가 할 수있는 일이 있습니까?

관련 프로세스를 다시 시작하는 것이 최후의 수단입니다.



답변

커널 시간 초과는 연결이 끊어진 경우에만 적용됩니다. 연결이 여전히 소켓에 연결되어 있으면 해당 소켓을 소유 한 프로그램이 연결 종료 시간 초과를 담당합니다. 아마도 호출 shutdown되어 연결이 완전히 종료되기를 기다리고 있습니다. 종료가 완료되기를 원하는 한 응용 프로그램이 대기 할 수 있습니다.

일반적인 클린 종료 흐름은 다음과 같습니다.

  1. 응용 프로그램은 연결을 종료하기로 결정하고 연결의 쓰기 쪽을 종료합니다.

  2. 응용 프로그램은 다른 쪽이 연결의 절반을 종료 할 때까지 기다립니다.

  3. 응용 프로그램은 상대방의 연결 종료를 감지하고 해당 소켓을 닫습니다.

응용 프로그램은 원하는만큼 2 단계에서 기다릴 수 있습니다.

응용 프로그램에 시간 초과가 필요한 것 같습니다. 연결을 종료하기로 결정한 후에는 일정 시간이 지나면 상대방이 완전히 종료 될 때까지 기다리지 않아야합니다.


답변

소켓이 shutdown ()이지만 아직 close ()가 아닌 경우 소켓은 FIN_WAIT2 상태를 유지합니다. 그리고 응용 프로그램은 여전히 ​​파일 디스크립터를 소유하고 있기 때문에 커널은 정리하지 않아도됩니다.