Tại sao các kết nối ở trạng thái FIN_WAIT2 không bị nhân Linux đóng?


11

Tôi có một vấn đề trong một quá trình tồn tại lâu dài được gọi là kube-proxy là một phần của Kubernetes .

Vấn đề là đôi khi một kết nối bị bỏ lại ở trạng thái 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

Các kết nối này chồng lên nhau theo thời gian làm cho quá trình hoạt động sai. Tôi đã báo cáo sự cố với trình theo dõi lỗi Kubernetes nhưng tôi muốn hiểu tại sao các kết nối như vậy không bị nhân Linux đóng.

Theo tài liệu của nó (tìm kiếm tcp_fin_timeout) kết nối ở trạng thái FIN_WAIT2 sẽ được đóng bởi kernel sau X giây, trong đó X có thể được đọc từ / Proc. Trên máy của tôi, nó được đặt thành 60:

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

vì vậy nếu tôi hiểu chính xác thì các kết nối như vậy sẽ bị đóng trong 60 giây. Nhưng đây không phải là trường hợp, họ bị bỏ lại trong tình trạng như vậy trong nhiều giờ.

Mặc dù tôi cũng hiểu rằng các kết nối FIN_WAIT2 khá bất thường (điều đó có nghĩa là máy chủ đang chờ một số ACK từ đầu kết nối từ xa có thể đã biến mất) Tôi không hiểu tại sao các kết nối này không bị "đóng" bởi hệ thống .

Có bất cứ điều gì tôi có thể làm về nó?

Lưu ý rằng khởi động lại quá trình liên quan là biện pháp cuối cùng.


1
Nhân tiện, trong FIN-WAIT2, kết nối không chờ ACK (FIN mà nó đã gửi đã được xác nhận, đó là lý do tại sao chúng tôi không ở FIN-WAIT1). Thay vào đó, đầu kia vẫn có tùy chọn gửi một lượng dữ liệu không giới hạn.
Hagen von Eitzen

Câu trả lời:


14

Thời gian chờ kernel chỉ áp dụng nếu kết nối là mồ côi. Nếu kết nối vẫn được gắn vào ổ cắm, chương trình sở hữu ổ cắm đó có trách nhiệm hết thời gian tắt kết nối. Có khả năng nó đã gọi shutdownvà đang chờ kết nối tắt sạch. Ứng dụng có thể đợi miễn là hoàn thành việc tắt máy.

Luồng tắt sạch điển hình diễn ra như sau:

  1. Ứng dụng quyết định tắt kết nối và tắt phía ghi của kết nối.

  2. Ứng dụng chờ phía bên kia tắt một nửa kết nối.

  3. Ứng dụng phát hiện việc tắt kết nối khác và kết nối ổ cắm của nó.

Ứng dụng có thể đợi ở bước 2 miễn là nó thích.

Có vẻ như ứng dụng cần thời gian chờ. Một khi nó quyết định tắt kết nối, nó sẽ từ bỏ chờ phía bên kia thực hiện tắt máy sau một khoảng thời gian hợp lý.


Tôi sẽ kiểm tra thông tin này với các nhà phát triển Kubernetes để xem liệu thời gian chờ như vậy có được thực hiện không. Tôi sẽ chấp nhận câu trả lời khi tôi xác minh nó. Tuy nhiên, cảm ơn đã phản hồi nhanh chóng.
Adam Romanek

Tôi muốn hiểu câu trả lời của bạn chi tiết hơn. Bạn có thể vui lòng giải thích một kết nối mồ côi là gì?
Adam Romanek

1
@AdamRomanek Một kết nối mồ côi là một kết nối không có ổ cắm liên quan, nghĩa là, một kết nối chỉ có thể được truy cập bởi chính kernel và không có quá trình nào có thể thực hiện thao tác trên.
David Schwartz

Điều này sẽ giúp ..." blog.cloudflare.com/...
John Greene

2

Nếu ổ cắm bị tắt (), nhưng chưa đóng (), ổ cắm sẽ ở trạng thái FIN_WAIT2. Và vì ứng dụng vẫn sở hữu bộ mô tả tệp, kernel sẽ không cần dọn dẹp.


Điều đó đã được đề cập trong câu trả lời được chấp nhận.
RalfFriedl

Tôi đặc biệt thêm rằng close () không được gọi.
L. Yan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.