วันนี้ฉันมีเรื่องลึกลับสำหรับคุณ เราเรียกใช้คลัสเตอร์ Elasticsearch ขนาดเล็กสามโหนดที่ใช้ CoreOS (2023.5.0 / Linux 4.19.25-coreos) บน Azure Elasticsearch ทำงานภายในคอนเทนเนอร์นักเทียบท่าในโหมดโฮสต์เครือข่าย หลังจากใช้งานการบำรุงรักษาเกือบทั้งหมดฟรีเป็นเวลานานกว่าหนึ่งปีเราได้เห็นเครื่องเข้าสู่สถานะที่น่าสนใจมาก
ปรับปรุง
ปัญหานี้ถูกแก้ไขได้โดยการแก้ไขที่จะขับรถในลินุกซ์เคอร์เนล ดูคำตอบด้านล่าง
อาการ
โดยพื้นฐานแล้วการเชื่อมต่อระหว่างเครื่องที่ได้รับผลกระทบและอีกสองโหนดจะตาย ทั้งหมดอยู่ในเครือข่ายเสมือนเดียวกันและเครือข่ายย่อยเดียวกันและสามารถสื่อสารกับ eath อื่น ๆ ได้ โหนดที่ได้รับผลกระทบยังสามารถเข้าถึงได้จากเครือข่ายย่อยอื่น ๆ (ฉันสามารถ ssh เข้าไปได้) และจากเครือข่ายเสมือนที่แตกต่างกัน เครื่องยังมีการเชื่อมต่อกับอินเทอร์เน็ต (ขาด ๆ หาย ๆ ) แต่การร้องขอส่วนใหญ่จะหมดเวลา
เราสังเกตว่าบนโหนดที่ได้รับผลกระทบจำนวน "ซ็อกเก็ตที่ใช้" ที่รายงานโดย/proc/net/sockstat
มีค่าสูงมาก (~ 4.5k แทน ~ 300 บนโหนดที่มีสุขภาพดี) การตรวจสอบแสดงให้เห็นว่าจำนวนนี้เพิ่มขึ้นอย่างรวดเร็วจากช่วงเวลาที่โหนดจะไม่พร้อมใช้งาน
สิ่งที่สนุกคือเราไม่สามารถระบุแหล่งที่มาของซ็อกเก็ตที่ใช้แล้ว:
# cat /proc/net/sockstat
sockets: used 4566
TCP: inuse 2 orphan 0 tw 2 alloc 98 mem 4
UDP: inuse 1 mem 0
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0
# cat /proc/net/sockstat6
TCP6: inuse 98
UDP6: inuse 1
UDPLITE6: inuse 0
RAW6: inuse 1
FRAG6: inuse 0 memory 0
นอกเหนือจากนั้นเครื่องก็ดูดี ไม่มีกระบวนการที่น่าสงสัยในการทำงานการใช้งาน CPU มีน้อยและมีหน่วยความจำเหลือเฟือ
กระตุกเป็น "ไม่สามารถเข้าถึง" VM ในผลเครือข่ายย่อยเดียวกันในไม่กี่EAGAIN
การตอบสนองต่อrecvmsg
แล้วข้ามไปรับกลับมาจากENOBUFS
sting ping เอาต์พุตที่นี่sendmsg
ฉันได้รวบรวมเอาท์พุทเพิ่มเติม (ก่อนที่จะทำการแก้ไขใด ๆ กับระบบ) และโพสต์ไว้ในกระทู้นี้: https://gist.github.com/privatwolke/e7e2e7eb0272787765f5d3726f37107c
การวิเคราะห์
เราได้ลองปิดทุกสิ่งที่เราสามารถนึกได้บนเซิร์ฟเวอร์โดยใช้ elasticsearch เป็นผู้ต้องสงสัยคนแรก แต่การปิดที่เก็บยางยืดไม่ได้ทำให้ซ็อกเก็ตที่ใช้หมดแล้ว สิ่งเดียวกันสำหรับกระบวนการที่เกี่ยวข้องกับ CoreOS ทั้งหมด (อัปเดตเอ็นจิ้น, locksmithd, ... ) หรือแม้กระทั่งรันไทม์ Docker ทั้งหมดหรือเนื้อหาเฉพาะ Azure ดูเหมือนจะไม่มีอะไรช่วย
แต่ตอนนี้มันเป็นเรื่องที่แปลกกว่า: เราพยายามวิ่งtcpdump
บนเครื่องเพื่อดูว่าเกิดอะไรขึ้น และดูเถิด: ปัญหาได้รับการแก้ไขแล้วการเชื่อมต่อได้รับการกู้คืน ทฤษฏีของเราคือ tcpdump ทำ syscall บางอย่างที่สามารถแก้ไขได้ เรารัน tcpdump ด้วย gdb และตั้งจุดพักบน syscalls ทั้งหมด หลังจากก้าวผ่านจุดพักมากมายในที่สุดเราก็พบว่าการกระทำของการตั้งค่าโหมดที่หลากหลายบนซ็อกเก็ตการจับภาพ (โดยเฉพาะบรรทัดนี้ใน libpcap ) เป็นสิ่งที่รีเซ็ตซ็อกเก็ตที่ใช้เคาน์เตอร์และกลับสู่สถานะปกติ
ข้อค้นพบเพิ่มเติม
- เราได้ตรวจสอบแล้วว่าการรัน
tcpdump
ด้วย-p/--no-promiscuous-mode
แฟล็กไม่ได้ล้างซ็อกเก็ตที่ใช้ตัวนับและส่งคืนเครื่องให้อยู่ในสถานะใช้งานได้ - การเรียกใช้
ifconfig eth0 txqueuelen 1001
รีเซ็ตซ็อกเก็ตที่ใช้นับ แต่การเชื่อมต่อไม่ได้คืนค่า - การตั้งค่าโหมด promisc ด้วยตนเองด้วย
ip link set eth0 promisc on
จะไม่คืนค่าการเชื่อมต่อnet.ipv4.xfrm4_gc_thresh
มีการตั้งค่าเป็น 32768 และการเพิ่มขึ้นเล็กน้อยไม่สามารถแก้ไขปัญหาได้
เราได้ติดต่อกับ Azure ผู้ซึ่งรู้สึกงุนงงกับสิ่งนี้ตามที่เราเป็น ฉันเข้าใจว่านี่ไม่ใช่ปัญหา แต่เป็นเพียงอาการเท่านั้น แต่มันเป็นสิ่งเดียวที่จับต้องได้ที่ฉันพบ ความหวังของฉันคือโดยการทำความเข้าใจกับอาการฉันสามารถเข้าใกล้สาเหตุที่แท้จริง อินเทอร์เฟซเครือข่ายบน Azure ทำงานด้วยไดรเวอร์เครือข่ายนี้
CoreOS / Kernel อาจจะตำหนิหรือไม่
จากมุมมองระยะเวลาปัญหาเริ่มต้นที่ 2019-03-11 ซึ่งเป็นวันที่ CoreOS อัปเดตอัตโนมัติเป็นเวอร์ชันล่าสุด ตามบันทึกประจำรุ่นปรับปรุงนี้ประกอบด้วยการปรับปรุงเคอร์เนลจาก4.15.23 4.19.25 ฉันยังคงผ่านการเปลี่ยนแปลงเพื่อดูว่ามีอะไรที่อาจเป็นปัญหาหรือไม่ จนถึงตอนนี้ฉันเพิ่งค้นพบว่าไดรเวอร์เครือข่าย hyperv ได้รับการอัปเดตไม่กี่เดือนที่ผ่านมาซึ่งไม่ทั้งหมดดูเหมือนจะเป็นส่วนหนึ่งของ 4.19.25 ชุดแพทช์ที่ CoreOS ใช้กับ 4.19.25 นั้นไม่น่าประทับใจแต่ชุดข้อมูลที่แนะนำโมดูล nf_conntrack_ipv4 ปลอมเป็นของใหม่
ปรับปรุง: เป็นไปได้ที่เกี่ยวข้องกับเคอร์เนลแพทช์ขาเข้า?
ช่วยด้วย!
จนถึงตอนนี้คำถามที่เรามีดังต่อไปนี้:
อะไรจะทำให้เมตริก "ซ็อกเก็ตที่ใช้" นี้พุ่งสูงขึ้น ฉันได้อ่านแหล่งที่มาของเคอร์เนลสำหรับการวัดนี้และดูเหมือนว่าจะเป็นเพียงตัวนับโดยไม่มีการอ้างอิงถึงซ็อกเก็ตประเภทใดที่เป็นจริงหรือสิ่งที่สร้างขึ้นมา
ทำไมจำนวนแฟลตไลน์ถึงประมาณ 4.5k ข้อ จำกัด ใดที่ทำให้เกิดสิ่งนี้
สิ่งที่เปลี่ยนแปลงอย่างมีนัยสำคัญระหว่างเคอร์เนล 4.14.96 และ 4.19.25 หรือไม่?
ทำไมการ
setsockopt()
โทรใน libpcap รีเซ็ตสถานะ
ข้อผิดพลาด CoreOS ที่เกี่ยวข้อง: https://github.com/coreos/bugs/issues/2572