CoreOS: tcpdump แก้ไขปัญหาเครือข่ายอย่างลึกลับ (ใช้ซ็อกเก็ตจำนวนมากเกินไป)


14

วันนี้ฉันมีเรื่องลึกลับสำหรับคุณ เราเรียกใช้คลัสเตอร์ 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


ซ็อกเก็ตเปิดเป็นปัญหาที่เกิดขึ้นไม่ใช่ปัญหารูท IMHO ฉันมีพฤติกรรมนี้ในระบบ linux ที่มีอุปกรณ์ macvlan (พร้อมที่อยู่ mac ของตัวเอง) บนอุปกรณ์บริดจ์ การตั้งค่าบริดจ์ให้เป็น promisc ทำให้อุปกรณ์ macvlan ทำงาน ฉันไม่รู้ coreos หรือ Azure ปัญหาคือเลเยอร์พื้นฐานไม่ทราบเกี่ยวกับที่อยู่ mac ในระดับบน
AndreasM

ขอบคุณสำหรับความคิดเห็นของคุณ! ฉันรู้ว่าซ็อกเก็ตที่ใช้จำนวนมากไม่ใช่สาเหตุที่แท้จริงฉันแค่ยึดมั่นในสิ่งที่จับต้องได้อย่างหนึ่งที่ฉันสามารถระบุได้ว่าผิดปกติในเครื่อง
Stephan Klein

สวัสดีสเตฟาน ข่าวใด ๆ? โปรดรายงาน 1) WOL เปิดใช้งานหรือไม่ 2) sysctl -w net.ipv4.route.flush = 1 แก้ไขหรือไม่ 3) แคช arp ที่ไม่มีสถานะการทำงานคืออะไร? ที่สถานะการทำงาน?
Massimo

คำตอบ:


4

ก่อนอื่นขอขอบคุณสำหรับคำถามที่เขียนดีมาก!

เนื่องจากระดับของรายละเอียดที่คุณอธิบายนั้นสูงมากและคุณอยู่ในระดับ gdb แล้วฉันคิดว่าคำตอบของฉันจะไม่ใช้งานให้คุณมากนัก อย่างไรก็ตามนี่คือการลอง:

  • สมมุติว่าคุณลองอะไรที่ชอบss -aeแล้วlsof -n?
  • ไม่dmesgกลับมาอะไรที่น่าสนใจเมื่อเกิดเหตุการณ์นี้หรือไม่?
  • คุณใช้ iptables บนเซิร์ฟเวอร์หรือไม่
  • หากคุณตั้งค่าโหมด promiscuous โดยใช้วิธีอื่นนอกเหนือจาก tcpdump (เช่น, ip link set [interface] promisc on) สิ่งนี้จะแก้ไขปัญหาด้วยหรือไม่
  • คุณได้ตรวจสอบกระบวนการที่น่าสงสัยไฟล์หรือกิจกรรมแปลก ๆ หรือไม่? แค่คิดว่าอาจมีกระบวนการที่น่ารังเกียจบางอย่างที่ซ่อนเร้นอยู่ในเงามืดซ่อนตัวและเงียบไปเมื่อมีการตั้งค่าโหมดที่หลากหลาย
  • หากคุณปล่อยให้พื้นหลังที่รัน tcpdump ปัญหานี้จะกลับมาหรือไม่

ฉันหวังว่านี่จะช่วยได้.


1
ขอบคุณสำหรับการตอบกลับของคุณ! ฉันได้รวบรวมเอาท์พุทของคำสั่งบางอย่างที่คุณอ้างอิงมาแล้ว ตอนนี้พวกเขายังเชื่อมโยงในคำถาม ( gist.github.com/privatwolke/e7e2e7eb0272787765f5d3726f37107c ) สิ่งที่แปลกคือวิธีการที่ได้รับน้อยซ็อกเก็ตได้รับรายงานจากss, lsofและnetstatกว่าจาก "ซ็อกเก็ตที่ใช้" /proc/net/sockstatใน เฉพาะจำนวนรวม (ซึ่งดูเหมือนว่าจะเพิ่งอ่านจากไฟล์นั้น) จะเท่ากัน iptablesวิ่ง แต่ไม่มีกฎพิเศษ (ดูส่วนสำคัญ) ฉันไม่ได้ลองตั้งโหมด promiscous ด้วยตัวเองหรือรัน tcpdump อย่างต่อเนื่อง จะทำเช่นนั้นในครั้งต่อไป
เตฟานไคลน์

ฉันได้เพิ่มเอาท์พุทของss -aepiลงในคอลเลคชั่นเอาท์พุทของฉัน: gist.github.com/privatwolke/ … - น่าเศร้าที่ dmesg ไม่ได้ผลอะไรเลยเมื่อเกิดเหตุการณ์นี้ขึ้น ในความเป็นจริงรายการล่าสุดก่อนเกิดเหตุการณ์คือ 5 วัน
เตฟานไคลน์

เพิ่มdmesg / journalctl -kเอาท์พุท
เตฟานไคลน์

ฉันได้ตรวจสอบแล้วว่าip link set eth0 promisc onเพียงอย่างเดียวไม่ได้ทำให้เครื่องกลับสู่สถานะใช้งานได้
เตฟานไคลน์

สวัสดีคุณเคยดูคำถามอื่น ๆ ในเว็บไซต์นี้หรือไม่? serverfault.com/questions/614453/ ...... ดูเหมือนว่าคุณอาจกำลังแคชแคช xfrm4 ปลายทาง คุณสามารถเพิ่มได้ด้วยการตั้งค่าเคอร์เนล: xfrm4_gc_thresh - INTEGER The threshold at which we will start garbage collecting for IPv4 destination cache entries. At twice this value the system will refuse new allocations. เท่าที่ฉันสามารถบอกได้ว่ามันเกี่ยวข้องกับ IPsec ซึ่งคุณดูเหมือนจะไม่ได้ทำงานที่นี่เช่นกัน
เปโดรเปเรซ

0

ปัญหานี้เกิดจากข้อผิดพลาดในไดรเวอร์ hv_netsvc ในเคอร์เนล Linux เราสามารถแก้ไขปัญหานี้ได้ด้วยนักพัฒนาของ Microsoft และจัดการเพื่อแก้ไขปัญหาที่ใช้กับอัปสตรีม

ฉันจะพูดข้อความกระทำที่นี่เพราะมันสรุปปัญหาค่อนข้างดี:

เมื่อบัฟเฟอร์วงแหวนเกือบเต็มเนื่องจากข้อความเสร็จสมบูรณ์ของ RX แพ็กเก็ต TX อาจถึง "ลายน้ำต่ำ" และทำให้คิวหยุดทำงาน หากความสำเร็จของ TX มาถึงเร็วกว่าการหยุดรอคิวการปลุกอาจไม่ได้รับ

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

สำหรับการอ้างอิงในอนาคตกระทำที่แก้ไขนี้เป็นhttps://github.com/torvalds/linux/commit/6d9cfab853ca60b2f77b5e4c40443216988cba1f

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