เรากำลังเรียกใช้แอปพลิเคชันของเราในคลัสเตอร์ Kubernetes (1.11) ที่ติดตั้งผ่าน KOps (เป็นคลัสเตอร์ DEV/QA ของเราที่สืบทอดมาจากพนักงานที่ไม่ได้อยู่กับบริษัทแล้ว)
ทุกอย่างทำงานได้ดีเป็นส่วนใหญ่ แต่บางครั้งหลังจากการปรับใช้
พ็อดบางตัวให้การเชื่อมต่อปฏิเสธข้อผิดพลาด เรารู้เพราะ Nginx บ่นข้อผิดพลาด 502 จากแบ็กเอนด์
บางครั้งมันจะทำงานโดยอัตโนมัติอีกครั้ง แต่มันจะเริ่มแสดงข้อผิดพลาดอีกครั้ง การรีสตาร์ทพ็อดจะช่วยแก้ปัญหาได้
มันจะทำงานได้ดีจนกว่าจะปรับใช้ครั้งต่อไป จากนั้นปัญหาก็เกิดขึ้นอีก
เราเปรียบเทียบ syslog กับคลัสเตอร์อื่น แต่ทุกอย่างดูคล้ายกัน
บันทึก TCPDUMPS ของ IP ของ POD
11:06:47.387766 IP 100.96.13.22.57778 > 100.96.12.137.http-alt: ค่าสถานะ [S], seq 1515889791, ชนะ 26883, ตัวเลือก [mss 8961,sackOK,TS val 132113284 ecr 0,nop,wscale 9], ความยาว 0
11:06:47.387775 IP 100.96.13.22.57778 > 100.96.12.137.http-alt: ค่าสถานะ [S], seq 1515889791, ชนะ 26883, ตัวเลือก [mss 8961,sackOK,TS val 132113284 ecr 0,nop,wscale 9], ความยาว 0
11:06:47.387777 IP 100.96.13.22.57778 > 100.96.12.137.http-alt: ค่าสถานะ [S], seq 1515889791, ชนะ 26883, ตัวเลือก [mss 8961,sackOK,TS val 132113284 ecr 0,nop,wscale 9], ความยาว 0
11:06:47.387781 IP 100.96.12.137.http-alt > 100.96.13.22.57778: ค่าสถานะ [R.], seq 0, ack 1515889792, ชนะ 0, ความยาว 0
11:06:47.387781 IP 100.96.12.137.http-alt > 100.96.13.22.57778: ค่าสถานะ [R.], seq 0, ack 1, ชนะ 0, ความยาว 0
11:06:47.387785 IP 100.96.12.137.http-alt > 100.96.13.22.57778: ค่าสถานะ [R.], seq 0, ack 1, ชนะ 0, ความยาว 0
ดังที่เห็นในบันทึก Ingress-nginx(100.96.13.22) พ็อดพยายามเชื่อมต่อกับ webapp พ็อด(100.96.12.137) แต่การเชื่อมต่อกับพ็อดจะถูกรีเซ็ตทันที
การสืบสวนของเรา:
หลังจากเรียนรู้เกี่ยวกับวิธีการทำงานของเครือข่าย kubernetes (การเชื่อมต่อเครือข่ายแบบบริดจ์, คู่ VETH)
(https://medium.com/practo-engineering/networking-with-kubernetes-1-3db116ad3c98
https://stackoverflow.com/questions/37860936/find-out- which-network-interface-belongs-to-docker-container
https://www.digitalocean.com/community/tutorials/how-to-inspect-kubernetes-networking#finding-and-entering-pod-network-namespaces
)
ด้วยเหตุนี้ อินเทอร์เฟซของพ็อดจึงเชื่อมต่อผ่านคู่ VETHÂ กับอินเทอร์เฟซโหนดบริดจ์
การจราจรใดๆ จากหรือไปยังพ็อดต้องผ่านสะพานนี้ (ในกรณีของเราคือ cbr0)
การแก้ไขปัญหา:
เราได้รับรหัสคอนเทนเนอร์ของพ็อดที่ได้รับผลกระทบโดยการเรียกใช้
นักเทียบท่า PS
รับ ID กระบวนการของ Pod
นักเทียบท่าตรวจสอบ --format '{{ .State.Pid }}' container-ID
ดูรายละเอียดเครือข่าย Pods
nsenter -t คอนเทนเนอร์ -pid -n ip addr
เอาต์พุต:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN กลุ่มเริ่มต้น qlen 1
ลิงค์ / ย้อนกลับ 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 ขอบเขตโฮสต์ lo
valid_lft ตลอดไป reserved_lft ตลอดไป
inet6 ::1/128 ขอบเขตโฮสต์
valid_lft ตลอดไป reserved_lft ตลอดไป
3: eth0@if380852: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state ค่าเริ่มต้นของกลุ่ม
ลิงค์/อีเธอร์ 0a:58:64:60:0d:27 brd ff:ff:ff:ff:ff:ff ลิงค์-netnsid 0
inet 100.96.13.39/24 ครอบคลุมทั่วโลก eth0
valid_lft ตลอดไป reserved_lft ตลอดไป
ลิงค์ขอบเขต inet6 fe80::e4cd:81ff:fe96:2914/64
valid_lft ตลอดไป reserved_lft ตลอดไป
eth0@if380852Â เป็นอินเทอร์เฟซเครือข่ายพ็อด
380852Â คือหมายเลขลิงค์ VETH
0a:58:64:60:0d:27Â คือที่อยู่ mac ของ pods
ดูรายละเอียดคู่ VETH ของพ็อด
ไอพีแอดเดอร์ | เกรป 380852
เอาต์พุต: 380852: vethd49cda8b@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue master cbr0 สถานะ UP กลุ่มเริ่มต้น
ที่นี่ vethd49cda8bคือพ็อด VETH ID
ตอนนี้ตรวจสอบรายละเอียดสะพานแล้ว
รับตารางบริดจ์ mac:
brctl โชว์แมค cbr0 | grep 0a:58:64:60:0d:27
เอาต์พุต:27 0a:58:64:60:0d:27 ไม่มี 1.44
ที่นี่ 27เป็น PORT ของ VETHÂ Interface
ตรวจสอบรายละเอียด VETHÂ ของท่าเรือ
brctl โชว์สเต็ป cbr0 | เกรป "(27)"
เอาต์พุต:
veth488082e8 (27)
เราจะเห็นว่าพอร์ต 27 เป็นของอินเทอร์เฟซ VETH ที่แตกต่างกัน ผลลัพธ์ที่คาดหวังควรเป็น:
VETH ID ของ POD (PORT ในตารางบริดจ์)
vethd49cda8b (27)
ให้รับ PORT จริงของอินเทอร์เฟซ VETH ของ POD
brctl โชว์สเต็ป cbr0 | grep vethd49cda8b
เอาต์พุต:
vethd49cda8b (52)
เราจะเห็นว่าการรับส่งข้อมูลไปยังพ็อดหายไปเนื่องจากพอร์ตที่ไม่ถูกต้องในตารางบริดจ์ mac
ตาราง MAC ของบริดจ์ควรแสดงพอร์ตเป็น 52 สำหรับที่อยู่ MAC ของคอนเทนเนอร์ แต่แสดงเป็น 27
แต่หลังจากผ่านไประยะหนึ่ง ระบบจะแสดงพอร์ตที่ถูกต้องโดยอัตโนมัติ ซึ่งจะช่วยแก้ปัญหาการเชื่อมต่อของเรา
เป็นไปได้ไหมที่จะรู้ว่าอะไรอัพเดทบริดจ์ตาราง? และจะหลีกเลี่ยงการอัพเดทที่ไม่ถูกต้องได้อย่างไร?
เราจะแก้ไขปัญหาต่อไปได้อย่างไร
มีใครประสบปัญหาที่คล้ายกัน
ขอบคุณล่วงหน้า ขอบคุณจริงๆ ความช่วยเหลือใด ๆ