เหตุใดการเชื่อมต่อในสถานะ FIN_WAIT2 จึงไม่ถูกปิดโดยเคอร์เนล Linux


11

ฉันมีปัญหาในกระบวนการระยะยาวที่เรียกว่า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 บางตัวจากระยะไกลของการเชื่อมต่อซึ่งอาจหายไปแล้ว) ฉันไม่เข้าใจว่าทำไมการเชื่อมต่อเหล่านี้จึงไม่ "ปิด" โดยระบบ .

มีอะไรที่ฉันทำได้บ้างไหม?

โปรดทราบว่าการรีสตาร์ทกระบวนการที่เกี่ยวข้องเป็นวิธีสุดท้าย


1
โดยวิธีการใน FIN-WAIT2 การเชื่อมต่อไม่รอ ACK (FIN ที่ได้ส่งได้รับการยอมรับแล้วซึ่งเป็นสาเหตุที่เราไม่ได้อยู่ใน FIN-WAIT1) ปลายอีกด้านยังคงมีตัวเลือกให้ส่งข้อมูลได้ไม่ จำกัด จำนวน
Hagen von Eitzen

คำตอบ:


14

เคอร์เนลไทม์เอาต์ใช้เฉพาะในกรณีที่การเชื่อมต่อมีการ Orphaned หากการเชื่อมต่อยังคงเชื่อมต่อกับซ็อกเก็ตโปรแกรมที่เป็นเจ้าของซ็อกเก็ตนั้นจะรับผิดชอบในการหมดเวลาการปิดการเชื่อมต่อ มีแนวโน้มว่าจะมีการเรียกใช้shutdownและกำลังรอการเชื่อมต่อเพื่อปิดการทำงานอย่างสมบูรณ์ แอปพลิเคชันสามารถรอได้ตราบเท่าที่มันต้องการให้การปิดระบบเสร็จสมบูรณ์

กระแสการปิดเครื่องที่สะอาดปกติจะเป็นเช่นนี้:

  1. แอปพลิเคชั่นตัดสินใจที่จะปิดการเชื่อมต่อและปิดด้านการเขียนของการเชื่อมต่อ

  2. แอปพลิเคชันรอให้อีกฝั่งหนึ่งปิดการเชื่อมต่อครึ่งหนึ่ง

  3. แอปพลิเคชันตรวจพบการปิดการเชื่อมต่อของอีกด้านหนึ่งและปิดซ็อกเก็ต

แอปพลิเคชันสามารถรอในขั้นตอนที่ 2 ได้นานเท่าที่ต้องการ

ดูเหมือนว่าแอปพลิเคชันจะต้องหมดเวลา เมื่อตัดสินใจที่จะปิดการเชื่อมต่อมันควรจะยอมแพ้รออีกด้านหนึ่งเพื่อทำการปิดเครื่องใหม่หลังจากใช้เวลาพอสมควร


ฉันจะตรวจสอบข้อมูลนี้กับนักพัฒนาของ Kubernetes เพื่อดูว่าหมดเวลาหรือไม่ ฉันจะยอมรับคำตอบเมื่อฉันยืนยัน อย่างไรก็ตามขอขอบคุณสำหรับการตอบสนองที่รวดเร็ว
Adam Romanek

ฉันต้องการที่จะเข้าใจคำตอบของคุณในรายละเอียดมากขึ้น คุณช่วยอธิบายการเชื่อมต่อแบบเด็กกำพร้าได้อย่างไร
Adam Romanek

1
@AdamRomanek การเชื่อมต่อแบบ orphaned นั้นไม่มีซ็อกเก็ตที่เกี่ยวข้องนั่นคือสามารถเข้าถึงได้โดยเคอร์เนลเท่านั้นและไม่มีกระบวนการใดที่สามารถทำการดำเนินการได้
David Schwartz

สิ่งนี้จะช่วย ... " blog.cloudflare.com/
John Greene

2

หากซ็อกเก็ตถูกปิด () แต่ยังไม่ปิด () ยังซ็อกเก็ตจะอยู่ในสถานะ FIN_WAIT2 และเนื่องจากแอปพลิเคชันยังคงเป็นเจ้าของตัวอธิบายไฟล์เคอร์เนลจะไม่รบกวนการทำความสะอาด


ที่กล่าวถึงแล้วในคำตอบที่ยอมรับ
RalfFriedl

ฉันเพิ่มเฉพาะที่ไม่ได้เรียกว่าปิด ()
L. Yan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.