ขณะนี้ฉันใช้ Kubernetes กับ Calico v3.20.2 เป็น CNI ฉันมีกรณีพิเศษมากที่ฉันต้องส่งทราฟฟิก UDP จาก DaemonSet Pod เฉพาะไปยังเซิร์ฟเวอร์ภายนอก ซึ่งจะอ่านชุดค่าผสม sourceIP:sourcePort ของ IP และส่งการตอบสนองโดยตั้งค่าทั้งสองเป็นฟิลด์ destIP:destPort เนื่องจากเซสชัน UDP ที่แตกต่างกันจะสุ่มเลือกพอร์ตต้นทางแบบสุ่มที่แตกต่างกัน (ช่วง 1024-65535) และการตอบสนองจะต้องโหลดอย่างสมดุลผ่าน MetalLB ฉันจึงต้องตั้งค่าตัวฟัง UDP ในทุกพ็อดของ DaemonSet เพื่อฟังทุกคำขอที่ส่งออก พอร์ตต้นทาง รวมทั้งกำหนดค่า LB ใหม่เพื่อให้รับฟังพอร์ตนั้นและกระจายทราฟฟิกเห็นได้ชัดว่าสิ่งนี้ไม่สามารถปรับขนาดได้และยังไม่มีประสิทธิภาพเนื่องจากเวลาแฝงของการกำหนดค่าดังกล่าวใช้เวลานานกว่าการตอบสนองที่ต้องส่งคืน รวมถึงความไม่ตรงกันที่อาจเกิดขึ้นของการกำหนดค่า LB แบบขนาน
ดังนั้น ฉันควรจะเปิดฟังเดียวต่อ Pod บนพอร์ตเฉพาะ (เช่น 20,000) และ SNAT การรับส่งข้อมูลขาออกทั้งหมดจากทุก Pod เพื่อให้พอร์ตต้นทางทุกครั้งที่ดาตาแกรม UDP ออกจากโหนดคือ 20,000 เซิร์ฟเวอร์ภายนอกจะส่ง การตอบกลับไปยังพอร์ตปลายทางนี้ และในที่สุด การตอบสนองจะไปถึงหนึ่งในผู้ฟัง UDP บน DaemonSet Pods อันใดอันหนึ่ง ฉันลองสิ่งนี้โดยใช้
sudo iptables -t nat -I POSTROUTING 1 -d <EXT-SERVER-IP>/32 -p udp --dport <EXT-SERVER-PORT> -j SNAT --to-source <WORKER-NODE-IP>:20000
เมื่อฉันพยายามใช้สิ่งนี้ใน IPtables Calico จะเขียนการเปลี่ยนแปลงที่ฉันทำใหม่เสมอและบังคับใช้การกำหนดค่าของตัวเอง ซึ่งนำไปสู่พอร์ตต้นทางแบบสุ่มที่ออกจากโหนดอีกครั้ง ในทางกลับกัน เมื่อฉันตั้งค่าแฟล็ก natOutgoing เป็นเท็จและพยายามตั้งค่ากฎของตัวเอง มีเพียงดาตาแกรม UDP เดียวเท่านั้นที่ออกจากโหนดที่มีการเปลี่ยนแปลง SNAT ที่ถูกต้อง ก่อนที่ดาตาแกรมอื่นๆ ทั้งหมดจะถูกบล็อก และไม่เคยปล่อยให้โหนดผู้ปฏิบัติงานอยู่ที่ ทั้งหมด (ตามหลักฐานจากเซิร์ฟเวอร์ภายนอกและ tcpdump บนโหนดผู้ปฏิบัติงาน)
การแก้ไขกรณีใดกรณีหนึ่งเหล่านี้จะช่วยแก้ปัญหาโดยรวมได้ และข้อเสนอแนะใด ๆ จะได้รับการชื่นชม!