Kubernetes Gateway API
(romaglushko.com)- ในเดือนพฤศจิกายน 2025 Kubernetes ได้ประกาศ deprecation ของ NGINX Ingress Controller ในเดือนมีนาคม 2026 ซึ่งถูกใช้งานอยู่ในมากกว่า 40% ของทั้งคลัสเตอร์ และการตัดสินใจครั้งนี้กลายเป็นจุดเปลี่ยนที่ทำให้ Gateway API ถูกวางตำแหน่งเป็นตัวสืบทอดของ Ingress API
- Gateway API ครอบคลุมความสามารถที่กว้างขวางสำหรับการจัดการทราฟฟิกขาเข้า มีความสามารถในการแสดงผลสูงกว่า Ingress API และแยกขอบเขตความรับผิดชอบระหว่างทีมได้ชัดเจนยิ่งขึ้น
- ข้อจำกัดของ Ingress API ได้แก่ ขอบเขต API ที่แคบ ความสามารถในการขยายที่แข็งทื่อ, การขาดการบังคับใช้นโยบาย, เส้นแบ่งความเป็นเจ้าของที่คลุมเครือ และไม่รองรับ cross-namespace อย่างปลอดภัย
- Gateway API มีโมเดลทรัพยากรที่แยกออกจากกัน เช่น GatewayClass, Gateway, Listener และ Route รวมถึงมีกลไกด้านความปลอดภัยและการขยายอย่าง ReferenceGrant และ Policy attachment
- CVE ที่เกิดซ้ำใน NGINX Ingress Controller มีต้นตอมาจากข้อบกพร่องเชิงโครงสร้าง และในระยะยาว การย้ายไปยัง Gateway API คือทางแก้เชิงรากฐานเพียงทางเดียว
วิวัฒนาการของ Ingress
- ใน Kubernetes ยุคแรกปี 2014 ทรัพยากร Service เป็นวิธีหลักในการเปิดเผยแอปพลิเคชัน
- ClusterIP ให้เพียงชื่อ DNS ภายในคลัสเตอร์ และไม่สามารถเข้าถึงจากภายนอกได้
- NodePort เปิดพอร์ตเฉพาะบนทุกโหนดเพื่อรับทราฟฟิกจากภายนอก และหาก IP ของโหนดถูกเปิดเผยก็สามารถถูกเข้าถึงจากภายนอกได้
- LoadBalancer จะ provision external load balancer ที่มี public IP เพื่อส่งต่อทราฟฟิก
- ExternalName ให้ alias ภายในคลัสเตอร์สำหรับบริการภายนอกด้วยเรคคอร์ด CNAME
- ในสี่แบบนี้ มีเพียง NodePort และ LoadBalancer เท่านั้นที่สามารถเปิดเผยสู่ภายนอกได้โดยตรง
- NodePort เป็น primitive พื้นฐาน แต่มีระดับต่ำเกินไป ต้องจัดการ external load balancing ระหว่างโหนดและทำ path-based routing เอง
- LoadBalancer เพิ่ม L4 load balancer (TCP/UDP) บน NodePort พร้อมการ provision อัตโนมัติ โดย Cloud Controller Manager เป็นผู้รับผิดชอบ
- อย่างไรก็ตาม ต้องจัดการ public IP และ load balancer จำนวนมาก ทำให้ต้นทุนสูงขึ้น และไม่มีจุดศูนย์กลางสำหรับบริหารทราฟฟิก
- แทนที่จะมี load balancer แยกสำหรับแต่ละ Service จึงเกิดแนวทางที่ LoadBalancer Service เดียวรับทราฟฟิกทั้งหมด แล้วส่งต่อไปยัง Deployment ของ reverse proxy อย่าง NGINX เพื่อทำ routing ตาม path และ hostname ซึ่งเป็นจุดเริ่มต้นของ Ingress API และ Ingress Controller
Ingress Controller
-
ในปี 2015 ทีม Kubernetes ได้นำ Ingress API มาใช้เป็นวิธีกำหนดกฎสำหรับ routing ทราฟฟิก HTTP(S) จากภายนอกไปยัง Service ภายใน
-
Ingress API ประกอบด้วยสองทรัพยากรคือ IngressClass และ Ingress โดยกำหนดเพียงอินเทอร์เฟซร่วม และต้องติดตั้ง Ingress Controller เพื่อให้ทำงานจริง
-
IngressClass
- เป็นทรัพยากรระดับ cluster-wide ที่ระบุว่าคอนโทรลเลอร์ตัวใดจะจัดการชุดของ Ingress resource ที่กำหนด
- ทำให้สามารถ ใช้งาน Ingress Controller หลายตัวควบคู่กัน ในคลัสเตอร์เดียวกันได้ โดยแต่ละคอนโทรลเลอร์จะเฝ้าดูเฉพาะ resource ที่ถูกเลือกด้วย IngressClass ของตน
- คอนโทรลเลอร์ต้องมีสิทธิ์ ClusterRole เพื่ออ่านและใช้งาน IngressClass
-
Ingress resource
- Ingress เป็นทรัพยากรหลักของ Ingress API ที่รวมองค์ประกอบหลายอย่างเข้าด้วยกัน
- กำหนดการ routing ไปยัง Service ภายในด้วยกฎการจับคู่แบบ path-based (exact/prefix) และ host-based
- กำหนดการตั้งค่า TLSของทราฟฟิกขาเข้า
- เมื่อสร้าง resource แล้ว Ingress Controller จะตรวจจับและอัปเดตการตั้งค่าภายในของตนเพื่อใช้กฎการ routing
- Ingress เป็นทรัพยากรหลักของ Ingress API ที่รวมองค์ประกอบหลายอย่างเข้าด้วยกัน
-
ปัญหาของ Ingress API
- ในสภาพแวดล้อมการใช้งานจริง พบปัญหาดังต่อไปนี้: ขอบเขต API ที่จำกัดมาก ความสามารถในการขยายที่แข็งทื่อ การขาดการบังคับใช้นโยบาย เส้นแบ่งความเป็นเจ้าของที่คลุมเครือ และไม่รองรับ cross-namespace อย่างปลอดภัย
-
ขอบเขต API ที่จำกัดมาก
- Ingress API ไม่ได้เรียบง่ายในความหมายที่ดี แต่เป็นแบบ เรียบจนขาดความสามารถ (simplistic) เพราะรองรับเพียงสิ่งขั้นต่ำที่จำเป็นสำหรับการตั้งค่าทราฟฟิกขาเข้า
- ไม่รองรับความสามารถต่อไปนี้ที่มักต้องการใน NGINX โดยตรง
- request timeout, CORS, การจำกัด max body size, sticky cookie session, การแบ่งทราฟฟิกแบบ canary, rate limiting, routing ตาม header·query·cookie และการแก้ไข header
- ด้วยเหตุนี้ custom annotation จึงกลายเป็นวิธีมาตรฐานในการส่งการตั้งค่าเพิ่มเติม และคอนโทรลเลอร์บางตัว เช่น Traefik ก็ใช้ CRD ของตนเอง
- เมื่อใช้ Ingress Controller หลายตัวพร้อมกัน จะไม่มีวิธีตั้งค่าแบบรวมศูนย์ ทำให้ annotation ของแต่ละคอนโทรลเลอร์แตกต่างกันและลดความสามารถในการพกพา
- Ingress รองรับเฉพาะ HTTP(S) routing ส่วน gRPC (L7), TCP และ UDP (L4) จะถูกจัดการผ่าน custom annotation ตามแต่ละ implementation
-
ความสามารถในการขยายที่แข็งทื่อ
- custom annotation เป็นเพียงคู่ key-value แบบสตริง จึงต้อง serialize การตั้งค่าที่ซับซ้อนเป็นสตริง ทำให้ขาดพลังในการแสดงความหมาย
-
การขาดการบังคับใช้นโยบาย
- ทีมแอปพลิเคชันสามารถเพิ่ม annotation ใด ๆ ลงใน Ingress resource ได้ เช่น อาจปิดการทำ rate limiting ที่ทีมแพลตฟอร์มคาดหวังให้มีในทุก route
- ตัว Ingress API เองไม่มีกลไกบังคับใช้พฤติกรรมแบบ global จึงต้องพึ่งพา external policy engine อย่าง Kyverno หรือ OPA Gatekeeper
-
เส้นแบ่งความเป็นเจ้าของที่คลุมเครือ
- Ingress resource ปะปนการตั้งค่าหลายประเภทไว้ด้วยกัน
- กฎการ routing โดยปกติมักเป็นของทีมแอปพลิเคชัน
- การตั้งค่า hostname และ port เป็นของทีมแพลตฟอร์มที่ดูแล DNS, load balancer และเครือข่าย
- การตั้งค่า TLS เป็นของทีมแพลตฟอร์มที่รับผิดชอบการ provision certificate
- custom annotation อาจเป็นของทีมใดทีมหนึ่งก็ได้
- ในระบบซับซ้อนที่ deploy ด้วย umbrella Helm chart นั้น Ingress มักอยู่ใน subchart ของแอปพลิเคชัน แต่ทีมแพลตฟอร์มก็ยังต้องอัปเดตหรือบังคับใช้บางส่วน
- ในมุมมองของหลักการความรับผิดชอบเดียว Ingress มีเหตุผลในการเปลี่ยนแปลงมากกว่าหนึ่งอย่าง จึงควรถูกแยกเป็น resource ที่มีหน้าที่เฉพาะเจาะจงกว่านี้
- Ingress resource ปะปนการตั้งค่าหลายประเภทไว้ด้วยกัน
-
ไม่รองรับ cross-namespace อย่างปลอดภัย
- Ingress resource ไม่สามารถอ้างอิง Service หรือ TLS secret นอก namespace ของตนเองได้ และใน
rules[].backend.serviceก็ไม่มีฟิลด์ระบุ namespace ด้วยซ้ำ - วิธีเลี่ยงคือสร้าง Service แบบ ExternalName ใน namespace เดียวกัน เพื่อชี้ไปยังชื่อ DNS ภายในคลัสเตอร์ของ Service เป้าหมาย
- อย่างไรก็ตาม วิธีนี้มีปัญหาที่เข้าข่าย confused deputy attack โดยตรง
- Ingress resource ไม่สามารถอ้างอิง Service หรือ TLS secret นอก namespace ของตนเองได้ และใน
Gateway API
- Gateway API เป็นเวอร์ชันถัดไปของ Ingress API ที่แก้ข้อจำกัดเหล่านี้ด้วยวิธีต่อไปนี้
- ครอบคลุมความสามารถที่กว้างกว่ามากสำหรับการจัดการทราฟฟิกขาเข้า และเพิ่มความสามารถในการแสดงผล
- สะท้อนรูปแบบความเป็นเจ้าของ resource ที่พบได้ทั่วไป จึงแยกขอบเขตความรับผิดชอบระหว่างทีมได้ชัดเจน
- มีทั้งกลไกการขยายที่นิยามไว้อย่างเป็นทางการในรูปแบบ policies และการอ้างอิงอ็อบเจ็กต์ข้าม namespace ที่ยืดหยุ่น
GatewayClass
- คล้ายกับ IngressClass โดยกำหนดชุดของ Gatewayที่ deployment ของ Gateway controller ตัวหนึ่งเป็นเจ้าของ ซึ่งมีความหมายและโครงสร้างแทบจะเหมือนกับ IngressClass
- สามารถอ้างอิง custom resource ที่เก็บการตั้งค่า Gateway เพิ่มเติมเฉพาะ implementation ได้
- รวมถึงวิธีเปิดเผย Gateway proxy, ค่าเริ่มต้นสำหรับ bootstrap และ runtime, วิธี rollout และ scale ของ deployment และตัวเลือกอื่น ๆ เฉพาะคอนโทรลเลอร์
Gateway
-
Gateway resource แสดงถึง edge gateway ที่ถูก provision แบบไดนามิก เป็นนามธรรมของโครงสร้างพื้นฐานที่รับทราฟฟิกขาเข้าและ route ไปยัง backend service ที่เหมาะสม
- ในสถาปัตยกรรม Ingress เดิม Ingress Controller ทำหน้าที่นี้อยู่แล้ว จึงอาจมองได้ว่าเป็นอินสแตนซ์ Gateway ที่ provision แบบคงที่
-
Gateway แต่ละตัวจะอ้างอิง GatewayClass เพื่อระบุว่าคอนโทรลเลอร์ใดจะเป็นผู้ provision และจัดการ โดยองค์ประกอบที่สำคัญที่สุดคือ รายการ listener
-
Listeners
- กำหนดวิธีที่ Gateway รับทราฟฟิกขาเข้า โดยแต่ละ listener คือจุดรับเข้าแยกกันที่อธิบายด้วยชุดพอร์ต·โปรโตคอล·โฮสต์เนม
- สามารถตั้งค่า TLS termination ได้ ซึ่งในโลกของ Ingress ข้อมูลนี้จะอยู่ภายในทรัพยากร Ingress
- เป็นหน่วยย่อยที่สุดที่ Route สามารถ attach เข้ากับ Gateway ได้
-
ListenerSet
- listener เหมาะกับการรวมศูนย์การตั้งค่าจุดรับเข้า แต่ไม่เหมาะเมื่อจำเป็นต้องมีหลายร้อยรายการ
- กรณีหลักคือ HTTPS listener ที่มีการตั้งค่าโฮสต์เนม·TLS แยกตามบริการแทนการใช้ wildcard TLS certificate เดียว ทำให้จำนวน listener อาจเพิ่มตามจำนวนไมโครเซอร์วิส
- เมื่อโมเดลด้วย Gateway เดียว จะเกิดปัญหาสองอย่าง
- Gateway รองรับได้สูงสุดเพียง 64 listeners
- หากหลายทีมต้องจัดการ listener·TLS Gateway จะกลายเป็น คอขวด ด้านการประสานงาน
- เพื่อกระจายการจัดการและรองรับมัลติเทนเนนต์ จึงใช้ทรัพยากร ListenerSet
-
Listener และ Route ที่ได้รับอนุญาต
- หลังแยกแนวคิดของ Gateway กับ Route ออกจากกัน ก็เกิดปัญหาใหม่ว่าควรควบคุมอย่างไรว่าเทนเนนต์ใดจะ attach Route เข้ากับ listener ใดได้บ้าง
- listener เป็นโครงสร้างพื้นฐานที่ใช้ร่วมกันและมีวัตถุประสงค์ต่างกัน ตัวอย่างเช่น ไม่เหมาะที่จะผูก HTTPRoute เข้ากับ listener
tls-passthrough-dbซึ่งเป็นช่องทาง passthrough ไปยังฐานข้อมูล และก็ไม่เหมาะให้ namespace อื่นนอกเหนือจากdbผูก Route เข้ามา - เนื่องจาก Route ถูกเพิ่มเข้ามาได้แบบจัดการตนเอง จึงใช้กลไก allowedRoutes เพื่อป้องกันการตั้งค่าผิดพลาด
- allowedRoutes สร้าง ความสัมพันธ์ความเชื่อถือ ระหว่าง Gateway·ListenerSet กับ Route ของ namespace และชนิด route ที่ระบุ
Routes
-
listener รับทราฟฟิก แต่ไม่รู้ว่าจะต้องจัดการต่ออย่างไร หน้าที่นี้เป็นของ ทรัพยากร Route ซึ่งเป็นแกนสำคัญของความยืดหยุ่นใน Gateway API
-
มีทรัพยากร Route อยู่ห้าชนิดสำหรับจัดการหลายโปรโตคอล
- HTTPRoute: การกำหนดเส้นทางทราฟฟิก HTTP ที่เสริมความสามารถและขยายได้มากขึ้น
- GRPCRoute: การกำหนดเส้นทางที่รับรู้ gRPC
- TLSRoute: การกำหนดเส้นทางตาม TLS SNI
- TCPRoute·UDPRoute: ส่งต่อทราฟฟิก TCP/UDP ที่เข้ามายังพอร์ต listener ไปยังแบ็กเอนด์โดยตรง
-
ทรัพยากร Route ทั้งหมด (เรียกรวมว่า xRoutes) มีโครงสร้าง envelope ที่คล้ายกัน
parentRefsคือ typed object reference ไปยังทรัพยากรแม่ที่รับ Route นี้ไว้ เช่น Gateway, ListenerSet, Service ของ service mesh เป็นต้น และสามารถใช้ตัวเลือกsectionName·portเพื่อระบุ listener เฉพาะได้rulesมีชุดกฎการกำหนดเส้นทาง·ฟิลเตอร์·การตั้งค่าตามโปรโตคอล โดยแต่ละ rule ประกอบด้วยmatches,filtersแบบเลือกใส่, และbackendRefsแบบเลือกใส่ หากฟิลเตอร์จัดการคำขอเสร็จสมบูรณ์แล้วก็สามารถไม่ระบุ backendRefs ได้- หากโปรโตคอลรองรับ ก็สามารถใช้ฟิลด์
hostnamesเพื่อทำ host-based routing ในระดับ Route ได้
-
HTTPRoute
-
กำหนดกฎการกำหนดเส้นทางทราฟฟิก HTTP(S) ในระดับ L7
-
Traffic Matching
- รองรับการกำหนดเส้นทางตาม path·host แบบคล้าย Ingress รวมถึงกฎการจับคู่ตาม header·query·method
- ตัวอย่างเช่น สามารถใช้การจับคู่ตาม header เพื่อส่ง canary release สำหรับไคลเอนต์ภายในเท่านั้นไปยัง test deployment ได้
- data plane จะใช้กฎที่เฉพาะเจาะจงที่สุด ดังนั้นลำดับการประกาศกฎจึงไม่สำคัญ
-
URL Rewrites
- สามารถใช้ filter เพื่อ rewrite บางส่วนของ URL คำขอก่อนที่จะไปถึงแบ็กเอนด์ได้
-
Header Modifications
- มีฟิลเตอร์ HeaderModifier สำหรับเพิ่ม·ลบ·แก้ไข header ของ request·response
- มีฟิลเตอร์ CORS แบบเฉพาะสำหรับการตั้งค่า Cross-Origin Resource Sharing ซึ่งในเชิงแนวคิดเป็นกรณีพิเศษของการแก้ไข response header แต่เปิดให้ใช้เป็นชนิดฟิลเตอร์แยกต่างหาก
-
Redirects
- สามารถตอบกลับไคลเอนต์ด้วย redirect แทนการส่งต่อไปยังแบ็กเอนด์ได้ รองรับ redirect ตาม path แบบ 3xx และ redirect จาก HTTP → HTTPS
-
Traffic Control
- สามารถแบ่งทราฟฟิกระหว่างบริการแบ็กเอนด์ด้วย weight ซึ่งมีประโยชน์กับการ deploy แบบ blue-green และการทดสอบ A/B
- traffic mirroring จะส่งสำเนาทราฟฟิกโปรดักชันไปยังแบ็กเอนด์เพิ่มเติม โดยตั้งค่าผ่านฟิลเตอร์
RequestMirrorขณะที่คำขอต้นฉบับยังคงไปยังแบ็กเอนด์หลักตามปกติ - mirroring เป็นองค์ประกอบสำคัญของ tap-and-compare testing สำหรับเปรียบเทียบผลลัพธ์ของเวอร์ชันเก่าและใหม่ระหว่างการรีแฟกเตอร์หรือการย้ายระบบ
-
Sticky Sessions
- รองรับ session persistence โดยกำหนด cookie หรือ header เป็นตัวบ่งชี้เซสชัน เพื่อให้คำขอจากไคลเอนต์เดียวกันถูกกำหนดเส้นทางไปยังอินสแตนซ์แบ็กเอนด์เดิมอย่างสม่ำเสมอ
-
External Authentication
- รองรับ experimental external authentication filter ที่ทำงานผ่าน gRPC หรือ HTTP โดย Gateway จะส่ง header ของคำขอไปยังบริการยืนยันตัวตนภายนอกก่อนส่งต่อไปยังแบ็กเอนด์ และจะส่ง request body ด้วยก็ต่อเมื่อเปิดใช้งานอย่างชัดเจน
- สำหรับ gRPC บริการยืนยันตัวตนภายนอกต้อง implement Envoy
ext_authzprotobuf API - สำหรับ HTTP หากการยืนยันตัวตนสำเร็จจะต้องคืนค่า
200ส่วนสถานะอื่นจะถือว่าเป็นการยืนยันตัวตนล้มเหลว
-
Retries & Timeouts
- สามารถตั้งค่า retry ให้กับ route เฉพาะได้ และ BackendTrafficPolicy มี global retry budget เพื่อป้องกัน retry storm
-
-
GRPCRoute
- แม้ gRPC จะทำงานบน HTTP/2 และจัดการด้วย HTTPRoute ได้ แต่ก็มีเหตุผลที่ต้องโมเดลเป็นทรัพยากรแยก
- เพื่อแยกตัวเลือกที่ไม่มีความหมายกับ gRPC เช่น URL rewrite และเปิดให้แต่ละทรัพยากรพัฒนาอย่างอิสระตามโปรโตคอลของตน
- การตอบกลับของ gRPC อาจคืน HTTP
200แต่แสดงข้อผิดพลาดระดับแอปพลิเคชันผ่าน headergrpc-status·grpc-messageซึ่งสำคัญต่อ retry และ metrics ที่ถูกต้อง - การนิยามกฎด้วยคำศัพท์ระดับสูงของ gRPC ช่วยให้ประสบการณ์ใช้งานดีขึ้น
- path matcher ของ HTTPRoute ถูกแทนที่ด้วย method matcher ซึ่งภายในยังคงจับคู่จาก path แต่เปิดเผยให้ผู้ใช้เห็นในรูปแบบ service·method
- สามารถจัดการ request·response header ได้ แต่ไม่ถอดรหัส payload ของ gRPC จึงไม่สามารถกำหนดเส้นทางตาม protobuf field เฉพาะได้
- รองรับบางส่วนของฟิลเตอร์ HTTPRoute เช่น traffic mirroring·weighted load balancing และการแก้ไข header
- แม้ gRPC จะทำงานบน HTTP/2 และจัดการด้วย HTTPRoute ได้ แต่ก็มีเหตุผลที่ต้องโมเดลเป็นทรัพยากรแยก
-
TCPRoute และ UDPRoute
- ส่งต่อทราฟฟิกที่มาถึงพอร์ต listener ไปยังบริการแบ็กเอนด์แบบตรงไปตรงมา ปัจจุบันยังไม่รองรับ matcher·filter
- ทั้งสองชนิดรองรับ weighted load balancing ระหว่างหลายแบ็กเอนด์
-
TLSRoute
- กำหนดเส้นทางทราฟฟิก TLS ที่เข้ารหัสไปยังแบ็กเอนด์โดยอิงจาก SNI ที่ส่งมาในระหว่าง TLS handshake
- ใช้หลัก ๆ กับ TLS passthrough โดย Gateway จะตรวจสอบ SNI เพื่อเลือกแบ็กเอนด์ แล้วส่งต่อการเชื่อมต่อที่เข้ารหัสต่อไปโดยไม่ทำ TLS termination ซึ่งให้แบ็กเอนด์เป็นผู้ทำ TLS termination เอง
- implementation บางตัว เช่น Envoy Gateway หรือ kgateway รองรับ TLS termination ที่ edge ด้วย แต่ถือเป็นความสามารถแบบขยาย
- ต้องระบุ hostname ใน Route ซึ่งต้องตรงกับค่า SNI และต้องมีส่วนตัดกันกับ hostname ของ listener บน Gateway โดยไม่รองรับ matcher·filter แต่รองรับ weighted load balancing
-
Route Filter Extensions
- HTTPRoute และ GRPCRoute มีกลไกขยายสำหรับ custom filter และการประมวลผล request/response ผ่านฟิลเตอร์
extensionRefซึ่งชี้ไปยังทรัพยากรอื่นด้วย typed object reference - ตัวอย่างเช่น Envoy Gateway มี CRD ชนิด HTTPRouteFilter ที่สามารถคืน response ได้โดยตรงโดยไม่ต้องมีบริการแบ็กเอนด์
- HTTPRoute และ GRPCRoute มีกลไกขยายสำหรับ custom filter และการประมวลผล request/response ผ่านฟิลเตอร์
-
เป้าหมายแบ็กเอนด์
- โดยพื้นฐานรองรับ Service มาตรฐาน (ใช้ทั่วไปที่สุด) และ ServiceImport สำหรับมัลติคลัสเตอร์เป็นเป้าหมายแบ็กเอนด์
- เนื่องจากระบุด้วย typed object reference จึงสามารถขยายด้วย custom resource ของแต่ละ implementation ได้
- ตัวอย่าง: Envoy Gateway รองรับ custom resource Backend ที่ชี้ไปยัง external upstream เช่น FQDN, IP, UNIX socket เป็นต้น
-
ReferenceGrant
- Gateway API จัดการการอ้างอิงข้าม namespace เป็นแนวคิดชั้นหนึ่งในดีไซน์มาตรฐาน แต่มีความเสี่ยงด้านความปลอดภัย
- ตัวอย่างของ confused deputy attack: หากผู้โจมตียึด namespace หนึ่งได้ ก็อาจใช้สิทธิ์สร้าง Ingress, Service และ EndpointSlice เพื่อรั่วไหลการเข้าถึงบริการที่ได้รับการปกป้อง
- Ingress ใหม่ชี้ไปยัง Service ใหม่ใน namespace ที่ถูกเจาะ
- Service นั้นเป็นแบบ selectorless จึงไม่แมตช์กับ deployment ใด และสามารถจัดหา EndpointSlice เองแบบแมนนวลได้
- ผู้โจมตีปลอม EndpointSlice ให้มี pod IP ของแบ็กเอนด์ที่ได้รับการปกป้องจาก namespace อื่น และสร้างช่องทางเข้าเส้นที่สองสู่ API ที่ปกป้องไว้ด้วยการจัดพอร์ตให้ตรงกัน
- สามารถไปถึงผลลัพธ์เดียวกันได้ด้วย ExternalName Service
- เพื่อบรรเทาปัญหานี้ จึงมีการนำ resource ReferenceGrant มาใช้ เป็นกลไกความเชื่อใจแบบสองทางที่ให้ namespace หนึ่งกำหนดได้ว่าจะอนุญาตให้ namespace ใดอ้างอิง resource ของตน
- Gateway Controller จะพิจารณา ReferenceGrant เมื่อมีการอ้างอิงข้าม namespace ไปยังเป้าหมายแบ็กเอนด์หรือ TLS secret ทำให้ confused deputy attack ทำได้ยากขึ้น
- อย่างไรก็ดี ReferenceGrant รับประกันเพียงความชอบธรรมของการอ้างอิง และไม่เกี่ยวข้องกับพฤติกรรมหลังจากมีการส่งต่อทราฟฟิกแล้ว โดยสามารถเสริมด้วย NetworkPolicies เพื่อบล็อกการเข้าถึงพอร์ต API ที่ปกป้องไว้
Policies
- Policy attachment เป็นแพตเทิร์นการขยายที่ทรงพลัง ซึ่งใช้บังคับพฤติกรรมและผลกระทบแบบ ลำดับชั้น กับคอมโพเนนต์ Gateway API หนึ่งรายการหรือมากกว่า โดยไม่ต้องแก้ไข resource ต้นทาง
- การยืนยันตัวตนเป็นตัวอย่างที่เด่นชัด
- หากบังคับใช้การยืนยันตัวตนกับทั้ง Gateway (หรือ ListenerSet) ก็จะมีผลแบบลำดับชั้นต่อ Route ที่ถูก attach อยู่ทั้งหมดทั้งปัจจุบันและอนาคต และในขณะเดียวกันก็สามารถมีข้อยกเว้นระดับ Route เช่น public route ได้
- การยืนยันตัวตนสามารถถูกควบคุมโดยทีมที่ไม่เกี่ยวข้องกับ Gateway หรือ Route โดยตรง จึงออกแบบมาเพื่อไม่ให้ต้องแก้ไข resource เหล่านั้นโดยตรง
- แม้จะมีมาตรฐานอย่าง OAuth 2 และ OIDC แต่การตั้งค่าการยืนยันตัวตนยังขึ้นกับ implementation สูง จึงยากที่จะสร้าง abstraction ที่ใช้ได้กับทุก implementation
- ตัวอย่าง: ใช้ resource SecurityPolicy ของ Envoy Gateway เพื่อตั้งค่าการตรวจสอบ JWT token โดย Policy เป็นวิธีที่ทันสมัยและสื่อความหมายได้ดีกว่าสำหรับแทนที่การตั้งค่าแบบ annotation ในยุค Ingress
- Policy ที่มีมาให้โดยตรงมีเพียงสองตัว
- BackendTLSPolicy: สั่งให้ Gateway เชื่อมต่อไปยัง upstream backend ด้วย TLS
- BackendTrafficPolicy: กำหนด retry budget สำหรับแบ็กเอนด์หนึ่งตัว หากเกินปริมาณ retry ที่อนุญาตโดยรวมจะคืนค่า
503ทำงานคล้าย circuit breaker เพื่อป้องกัน retry storm
Ownership
- resource ของ Gateway API ภายในคลัสเตอร์มักเป็นของสองทีม
- Platform team กำหนด GatewayClass, Gateway, ListenerSet และการตั้งค่า LoadBalancer กับ TLS และอาจดูแล Policy ส่วนกลางที่ใช้กับบางส่วนหรือทั้งหมดของ Gateway
- Application/Service team มักโฟกัสที่ resource Route ของตนเองเป็นหลัก และใช้ Policy ระดับ Route เมื่อจำเป็น
- ด้วยความยืดหยุ่นที่สูง จึงสามารถจัดโมเดลความเป็นเจ้าของได้หลากหลาย เช่น ให้ทีมแพลตฟอร์มรวบรวม Route ไปเป็นเจ้าของใน namespace เดียว
Typical Architecture
- Gateway API ไม่ได้ตั้งสมมติฐานกับสถาปัตยกรรมของ implementation มากนัก แต่แนวทางที่พบบ่อยคือ แยก control plane กับ data plane
- Gateway Controller ทำหน้าที่เป็น Kubernetes operator ฝั่ง control plane โดยเฝ้าดู resource และ CRD ของ Gateway API เพื่อสังเคราะห์การตั้งค่า data plane ที่ต้องการ และต้องมีสิทธิ์แบบขยายเพื่ออ่านและแก้ไข resource
- Gateway data plane คือ proxy ที่จัดการทราฟฟิกตามการตั้งค่า โดยมักใช้ Envoy Proxy, NGINX, Traefik เป็นต้น และแต่ละ implementation อาจ provision proxy แยกต่อ Gateway หรือใช้ร่วมกัน
- การแยก control/data plane เป็นทางเลือกด้านการออกแบบที่เอื้อต่อการหลีกเลี่ยงช่องโหว่ด้านความปลอดภัยเชิงโครงสร้างที่พบใน NGINX Ingress Controller
การย้ายจาก Ingress
-
ตัวเลือกสำหรับรับมือการเลิกใช้งาน NGINX Ingress Controller มีสี่แบบ โดยพิจารณาตามลำดับจากความกระทบกระเทือนต่ำไปสูง
-
ไม่ทำอะไรเลย
-
แม้จะไม่ใช่ทางเลือกที่ดีที่สุด แต่ในบางกรณีก็เป็นไปได้ และใน homelab อาจมีแรงจูงใจน้อย
-
ในองค์กร มักยอมรับได้ยากเพราะกรอบงานด้านกฎระเบียบ ความปลอดภัย และคอมพลายแอนซ์คาดหวังให้ใช้งานซอฟต์แวร์ที่ยังได้รับการดูแลและแพตช์
- ISO 27001: คาดหวังการจัดการช่องโหว่ การแพตช์ และการติดตาม EOL
- SOC 2 Type II: คาดหวังการสแกนช่องโหว่ การจัดการแพตช์ และ SLA สำหรับการแก้ไข
- HIPAA Security Rule: ต้องรวมซอฟต์แวร์เก่าและไม่แพตช์ไว้ในการวิเคราะห์ความเสี่ยง
- PCI DSS v4.0.1: กำหนดให้ระบุคอมโพเนนต์ที่ไม่รองรับและมีแผนแก้ไข พร้อมกำหนดระยะเวลาจัดการช่องโหว่ร้ายแรง
- FedRAMP: คาดหวังให้เปลี่ยนซอฟต์แวร์ที่ไม่รองรับเป็นทางเลือกที่ยังได้รับการดูแล และมีกรอบเวลาแก้ไขตามระดับความรุนแรง
-
ในกรอบงานส่วนใหญ่ ซอฟต์แวร์ EOL จะกลายเป็นปัญหาที่เป็นรูปธรรมเมื่อมีการเปิดเผยช่องโหว่ใหม่
-
การวิเคราะห์ CVE
- สถานะ CVE ของ NGINX Ingress Controller ในช่วง 5 ปีที่ผ่านมา
- ช่องโหว่ทั้งหมด 20 รายการ
- ปี 2021 มี High 4 รายการที่เกี่ยวข้องกับการรั่วไหลของ secret
- ปี 2022 มี High 1 รายการที่เกี่ยวข้องกับการรั่วไหลของ credential ของคอนโทรลเลอร์
- ปี 2023~2024 มี High 3 รายการ
- ปี 2025 มี 6 รายการ รวมถึง Critical 1 รายการ (IngressNightmare) และ High 4 รายการที่เกี่ยวข้องกับการฉีดการตั้งค่า NGINX
- ปี 2026 มี 6 รายการ รวมถึง High 3 รายการที่เกี่ยวข้องกับการฉีดการตั้งค่า NGINX
- CVE ในปี 2021~2022 ส่วนใหญ่เกิดจากการตั้งค่า NGINX ที่ผู้ใช้ป้อนผ่าน annotation โดยไม่ถูกทำความสะอาดอย่างเหมาะสม ก่อให้เกิดการฉีดการตั้งค่า การเปิดเผยข้อมูล และการรั่วไหลของ secret ทำให้ Kubernetes ต้องเพิ่ม validation
- CVE ในปี 2023~2024 ส่วนใหญ่เป็นการบายพาส validation ของ annotation ดังกล่าว
- IngressNightmare(CVE-2025-1974) ทำให้สถานการณ์เลวร้ายลง ก่อนหน้านี้จำเป็นต้องมีสิทธิ์สร้างหรือแก้ไข resource Ingress แต่หากเข้าถึงเครือข่ายของ admission controller ได้ ก็สามารถทำ remote code execution ในบริบทของ ingress-nginx controller ผ่านบั๊กคล้ายการฉีดการตั้งค่าได้ และหลังจากนั้นอาจรั่วไหล Secret ที่คอนโทรลเลอร์เข้าถึงได้
- ชุดช่องโหว่ในปี 2026 ก็ยังคงเป็นแพตเทิร์นการฉีดการตั้งค่าผ่าน annotation, path และ comment
- ช่องโหว่เหล่านี้โจมตีจุดอ่อนแบบเดียวกันของดีไซน์ซ้ำแล้วซ้ำเล่า
- คอนโทรลเลอร์มีความยืดหยุ่นสูงและเปิดเผยความสามารถของ NGINX อย่างกว้างขวาง ทำให้ทำ validation ได้สมบูรณ์ยาก จึงเกิดการฉีดการตั้งค่าซ้ำๆ
- คอนโทรลเลอร์รันทั้ง control plane และ data plane ใน pod เดียวกัน และแชร์ filesystem ร่วมกัน ทำให้ขอบเขตผลกระทบขยายกว้างเมื่อเกิดเหตุ
- คอนโทรลเลอร์มักเข้าถึง Secret ได้ทั้งคลัสเตอร์ ดังนั้นเมื่อการฉีดการตั้งค่าสำเร็จ ก็อาจนำไปสู่การรั่วไหลของ secret ทั้งคลัสเตอร์
- ด้วยปัญหาเชิงโครงสร้าง จึงคาดว่าจะมี CVE เพิ่มเติมในอนาคต และการอยู่กับคอนโทรลเลอร์ต้นฉบับต่อไปโดยไม่มีแผนย้ายถือเป็นทางเลือกที่เสี่ยง
- สถานะ CVE ของ NGINX Ingress Controller ในช่วง 5 ปีที่ผ่านมา
-
-
ใช้ NGINX Controller fork
- เส้นทางที่ง่ายที่สุดคือเปลี่ยนไปใช้ fork ที่ยังได้รับการดูแล
- fork ของ Chainguard ดูเหมือนจะไม่ได้ให้ image ที่ build แล้ว และนั่นน่าจะเป็นส่วนหนึ่งของสิ่งที่ขาย
- ช่วยลดความเสี่ยงจากการเปิดรับ CVE ใหม่และคงระบบเดิมไว้ได้โดยแทบไม่ต้องเปลี่ยนแปลงมาก แต่เป็นทางออกระยะสั้น
- Chainguard ไม่ได้มุ่งพัฒนาคอนโทรลเลอร์ต่อไปเป็นโครงการระยะยาว แต่ให้การแก้ไข CVE แบบ best-effort เพื่อซื้อเวลาให้ผู้ใช้ย้ายระบบ
- เส้นทางที่ง่ายที่สุดคือเปลี่ยนไปใช้ fork ที่ยังได้รับการดูแล
-
การใช้ Ingress Controller อื่น
- เนื่องจากตัวรีซอร์ส Ingress เองยังไม่ deprecated การเปลี่ยนไปใช้ Ingress Controller อื่นที่ยังคงได้รับการดูแลก็ยังเป็นทางเลือกที่ใช้ได้ โดยตัวอย่างที่เด่นคือ HAProxy·Istio·Traefik
- จำเป็นต้องทำ annotation migration ทั่วทั้งระบบ และระดับความยากจะแตกต่างกันไปตามระดับการพึ่งพาฟีเจอร์เฉพาะของ NGINX
- ในอนาคตจะมีอีกหลายโปรเจกต์ย้ายไปใช้ Gateway API ทำให้สัดส่วนการใช้ Ingress ลดลง แต่ในช่วงหนึ่งข้างหน้า Ingress ก็ยังใช้งานต่อได้อย่างไม่มีปัญหา
-
การย้ายไปยัง Gateway API
- ทางเลือกระยะยาวเพียงทางเดียวคือการย้ายจาก Ingress API ไปยัง Gateway API
- ติดตั้ง Gateway API CRD และตัว implementation
- ตั้งค่า GatewayClass·Gateway·และรีซอร์ส Policy หากจำเป็น
- ย้ายรีซอร์ส Ingress เดิมไปเป็น Route
- CLI ingress2gateway ที่ทีม Kubernetes สร้างขึ้นรองรับการแปลงอัตโนมัติแบบ best-effort แต่ custom annotation ยังต้องกลับมาตรวจสอบเองภายหลัง
- ต้องย้ายค่าอย่าง timeout, ขีดจำกัดการอัปโหลดไฟล์, ขีดจำกัด body size ฯลฯ ให้ถูกต้อง เพราะหากตกหล่นหรือแมปผิด อาจทำให้สมมติฐานของแอปพลิเคชันพังอย่างเงียบ ๆ ได้
- ควรวางแผนการสลับทราฟฟิกจาก LoadBalancer ของ Ingress Controller ไปยัง LoadBalancer ของ Gateway proxy ใหม่อย่างรอบคอบ และไม่จำเป็นต้องทำแบบ big-bang
- สามารถคง Ingress Controller ไว้เป็นจุดรับทราฟฟิกสาธารณะชั่วคราว แล้วส่งเพียงบางส่วนของทราฟฟิกไปยัง Gateway API data plane เพื่อทดสอบกับทราฟฟิกจริง ก่อนค่อย ๆ ทยอยย้ายได้
- ทางเลือกระยะยาวเพียงทางเดียวคือการย้ายจาก Ingress API ไปยัง Gateway API
ควรเลือก Gateway แบบใด
-
หลังตัดสินใจย้ายแล้ว คำถามใหญ่ข้อแรกคือจะใช้ implementation ของ Gateway API ตัวใด
-
นิยามกรณีใช้งาน generic API Gateway ในบทความนี้: เกตเวย์ที่ขยายได้สำหรับทราฟฟิก public แบบ North-South ซึ่งนำไป deploy ในสภาพแวดล้อมที่ควบคุมได้ทั้งหมด พร้อมรองรับแพตเทิร์นการยืนยันตัวตนทั่วไปและ rate limiting ที่ยืดหยุ่นเป็นค่าเริ่มต้น
-
นอกจาก API Gateway แล้ว ยังมี LLM Gateway และ Agent Gateway ด้วย แต่หัวข้อนี้จะโฟกัสที่ API Gateway แบบดั้งเดิม
-
Gateway API Conformance
- ทีม Kubernetes ได้จัดทำ ชุดทดสอบ conformance มาตรฐาน เพื่อยืนยันความถูกต้องของการจัดการโปรโตคอลหลักของ implementation โดยเน้นที่พฤติกรรมเชิงฟังก์ชันเป็นหลัก และไม่ได้ครอบคลุมประเด็นที่ไม่ใช่เชิงฟังก์ชันอย่างความน่าเชื่อถือ ประสิทธิภาพ ความสามารถในการขยายตัว หรือความซับซ้อนในการปฏิบัติการ
- ควรให้ความสำคัญกับ implementation ที่ conformant และหากไม่มีผลลัพธ์บนเว็บไซต์ทางการ ก็ควรขอรายงาน conformance จากผู้ดูแลโปรเจกต์โดยตรง
-
Public Benchmarks
- นอกเหนือจากการทดสอบทางการ ยังมี benchmark สาธารณะที่ครอบคลุมเรื่องความน่าเชื่อถือและประสิทธิภาพ โดย John Howard ซึ่งเป็นทั้งผู้มีส่วนร่วมใน Istio และพนักงานของ Solo.io ได้จัดทำ benchmark ของ implementation หลัก ๆ ขึ้นมา และ Solo.io เป็นบริษัทแม่ของ kgateway
- มีเคสทดสอบที่เป็นประโยชน์ เช่น Route attachment·การเผยแพร่·การสเกล·และประสิทธิภาพการประมวลผลทราฟฟิกทั่วไป แม้จะอิงจากประสบการณ์ของผู้จัดทำจนมีโอกาสเอนเอียงไปยังบางกรณี แต่ก็ยังใช้เป็นอีกมุมหนึ่งในการประเมินได้
-
OSS vs Proprietary
- ปัจจุบันมี Gateway API implementation แบบ OSS ระดับ production ที่แข็งแกร่งอยู่มาก จึงควรพิจารณาอย่างจริงจังเมื่อประเมินตัวเลือก และสำหรับหลายองค์กร OSS ก็เป็นจุดเริ่มต้นโดยปริยาย
- ฟีเจอร์อย่าง OAuth2·OIDC ที่ในอดีตเคยใช้เป็นเหตุผลในการซื้อซอฟต์แวร์เชิงพาณิชย์ ได้กลายเป็น commodity ไปแล้ว และคอนโทรลเลอร์แบบ OSS ก็มีให้เป็นพื้นฐาน
- ข้อดีของ OSS คือสามารถประเมินคุณภาพได้ด้วยตนเองก่อนตัดสินใจ commit ขณะที่ซอฟต์แวร์เชิงพาณิชย์ต้องเชื่อใจผู้ขายตั้งแต่เนิ่น ๆ
-
Recommendations
-
การจัดกลุ่มตาม data plane
- บน Envoy Proxy: Envoy Gateway, Istio, Cilium, kgateway เป็นต้น
- บน NGINX: NGINX Gateway Fabric, Kong
- proxy อื่น ๆ: HAProxy Ingress, Traefik
-
Envoy Gateway
- คอนโทรลเลอร์ Gateway API แบบโอเพนซอร์สที่พัฒนาโดยทีม Envoy Proxy และทำงานบน Envoy Proxy โดยแมปความสามารถของ Envoy เข้ากับ Gateway API ให้ตรงที่สุด จึงมี abstraction เฉพาะผลิตภัณฑ์น้อยกว่า Istio และทำความเข้าใจได้ง่ายกว่า
- ไม่รองรับ Ingress API และสามารถขยายความสามารถไปยัง LLM, MCP gateway และ Inference Pools ได้ผ่าน Envoy AI Gateway
- มีน้ำหนักเบา ติดตั้งและปฏิบัติการได้ง่าย เน้นที่ API Gateway (North-South) และรองรับฟีเจอร์ดังนี้
- แพตเทิร์นด้านความปลอดภัย เช่น external authentication·การตรวจสอบ JWT·authorization ตาม JWT claim·OIDC·IP allowlisting·การยืนยันตัวตนด้วย static API key·credential injection
- global rate limit policy ที่ยืดหยุ่น พร้อมการตั้งค่าระดับ global และ route, shadow mode และการกำหนด request cost
- ข้อจำกัดด้าน connection·bandwidth·file size, การทำ routing แบบรับรู้ availability zone, มัลติคลัสเตอร์พื้นฐานผ่าน ServiceImport, การบีบอัด response แบบ Brotli·gzip·zstd, direct response และ response override
- ยังขยายต่อได้มาก: สามารถเขียน gRPC service เพื่อแก้ไขคำขอ·คำตอบ·และการตั้งค่า xDS หรือเขียนปลั๊กอินด้วย Lua หรือภาษาที่คอมไพล์เป็น WASM ได้ (Go·Rust)
- มีรีซอร์ส Backend แบบ custom ที่รองรับรีซอร์สภายนอกแบบ FQDN·IP และ UNIX socket สำหรับ sidecar
- ปัจจุบันถูกระบุเป็น partially conformant เนื่องจากมีบางการทดสอบที่ถูกข้าม แต่ในเชิงฟังก์ชันรองรับแทบทุกหัวข้อ และยังผสานกับโปรเจกต์ CNCF อย่าง KEDA·KNative ได้
- หากต้องการเพียง API Gateway ที่มีฟีเจอร์ครบถ้วน ก็เป็นตัวเลือกที่ดี
-
Istio
- service mesh ที่ทำงานบน Envoy Proxy และเป็นโปรเจกต์ CNCF ระดับ Graduated โดยถูกระบุว่า conformant ในการทดสอบ Gateway API
- เป็นแพ็กเกจที่รวม Ingress Controller·Gateway API controller·และ service mesh เข้าไว้ด้วยกัน และสามารถเพิ่มความสามารถด้าน LLM·MCP·A2A gateway ได้ผ่านการเชื่อมต่อกับ agentgateway
- รองรับมัลติคลัสเตอร์ขั้นสูงผ่าน Admiral เป็นต้น มีโปรไฟล์การ deploy ที่หลากหลาย ชุมชนขนาดใหญ่ และเอกสารมากมายรวมถึงหนังสือจาก O'Reilly อีกทั้งการเข้ารหัส pod-to-pod ด้วย mTLS ยังเป็นประโยชน์ในสภาพแวดล้อมภาครัฐหรือ FedRAMP
- ข้อเสียคือในโหมด sidecar ใช้ทรัพยากรมาก และมีแนวคิดเฉพาะของตนเองจำนวนมาก ทำให้ เส้นโค้งการเรียนรู้ ชัน
- มี ambient mode สำหรับ setup ที่เบากว่า แต่ในกรณีใช้งาน L7 ขั้นสูงอาจไม่ครบเท่า sidecar และหากต้องการ policy ที่เข้มขึ้นหรือการควบคุม L7 ที่มากกว่า ก็อาจพิจารณาใช้ Envoy Gateway ร่วมเป็น ingress gateway และ waypoint proxy
- เหมาะที่สุดเมื่อ service mesh เป็นสิ่งหลักและ Gateway API เป็นเรื่องรอง แต่หากต้องการเพียง API gateway อาจรู้สึกว่ายังไม่ตอบโจทย์เต็มที่
-
kgateway
- เกตเวย์โอเพนซอร์ส CNCF Sandbox ที่ต่อยอดจากโปรเจกต์ Gloo รองรับ Envoy Proxy และ agentgateway (ความสามารถแบบ AI gateway) เป็น data plane และยังสามารถใช้ data plane instance ของตนเองที่ถูกจัดการจากภายนอกได้
- มี Gateway API conformance สมบูรณ์แบบ จนแทบเป็นตัวเดียวที่ผ่านครบทุกหัวข้อ
- บน Envoy data plane รองรับการตรวจสอบ JWT·OAuth2/OIDC·external authentication·การควบคุมการเข้าถึงตาม IP, Envoy global rate limiting และการเปิดให้ใช้งานการประมวลผลคำขอ·คำตอบผ่าน ext_proc แต่ดูเหมือนจะไม่เปิดให้ใช้ปลั๊กอิน Lua·WASM หรือแก้ไข raw xDS โดยตรง
- มีเอนจิน transformation ที่ทรงพลังบนพื้นฐานเทมเพลต MiniJinja ทำให้สามารถนิยามการแปลง header·response body·status แบบประกาศได้ในรีซอร์ส TrafficPolicy
- สามารถผสานกับ Istio ในฐานะ edge proxy ได้ แต่ไม่ได้ทำหน้าที่เป็น service mesh เอง รองรับ Route แบบลำดับชั้น ที่ให้ Route หนึ่งมอบหมายการจัดการทราฟฟิกไปยังอีก Route หนึ่ง และมี custom CRD ชื่อ AwsLambda สำหรับเรียก AWS Lambda โดยตรง
- แม้ผู้ขายจะอ้างว่ามีการใช้งานอย่างกว้างขวาง แต่ยังมีฟีดแบ็กอิสระไม่มากนัก ทำให้ในมุมมองของชุมชนสาธารณะยังดูเป็นโปรเจกต์ที่อยู่ระหว่างการเติบโต
-
-
Traefik
-
reverse proxy โอเพนซอร์สยอดนิยมที่เขียนด้วย Go รองรับทั้ง Ingress API และ Gateway API ได้รับความนิยมเป็นพิเศษในชุมชน homelab ด้วยเอกสารที่ยอดเยี่ยม โค้ดเบสที่เป็นระเบียบ การตั้งค่าที่เรียบง่าย และการปรับใช้ที่ทำได้ง่าย
-
รองรับความสามารถหลักของ Gateway API และความสามารถเสริมบางส่วน แต่ยังไม่รองรับ ListenerSet และ traffic mirroring ผ่าน Gateway API (แม้จะทำ mirroring ได้ด้วย custom TraefikService backend)
-
โมเดลการขยายใช้ middleware เป็นฐาน โดยเชื่อม Route เข้ากับ Middleware CRD ผ่านฟิลเตอร์ ExtensionRef และมี middleware ในตัวอย่าง ForwardAuth (มอบหมายการยืนยันตัวตนไปยังภายนอก คล้าย Envoy ext_authz), IP allowlisting และ CORS, การจำกัดการเชื่อมต่อ retry และ circuit breaker, การบีบอัด และ custom error page เป็นต้น
-
สามารถเชื่อมต่อปลั๊กอิน custom YAEGI และ WASM ผ่าน middleware แบบ Plugin ได้ (ส่วนใหญ่ใช้แก้ไข request/response) ส่วนการตรวจสอบ JWT, OIDC และ OAuth2 Client Credentials มีให้เฉพาะในปลั๊กอินแบบเสียเงินเท่านั้น
-
รองรับ distributed rate limiting พื้นฐานผ่าน Middleware CRD (บัคเก็ตตาม IP, host, header) แต่การตั้งค่าไม่ยืดหยุ่นมากนัก และเนื่องจากแนบผ่าน ExtensionRef ไม่ใช่ policy attachment จึงทำให้การจัดลำดับชั้นแบบใช้ทั่วทั้งระบบแล้ว override ในระดับ route ทำได้ยาก
-
ไม่มีการแยก control plane/data plane ที่ชัดเจน ทำให้สถาปัตยกรรมคล้าย NGINX Ingress มากกว่า โดย pod เดียวกันทำทั้งการเฝ้าดู resource และจัดการทราฟฟิก ไม่ได้ provision proxy แยกแบบไดนามิกตามแต่ละ Gateway แต่ใช้ deployment เดียวจัดการ Gateway ทั้งหมดใน namespace ที่เฝ้าดู จึงอาจเกิดปัญหาด้านความทนทานในระบบขนาดใหญ่จาก single point of failure และการแยกส่วนที่ลดลง
-
หากจะเลือกใช้ แนะนำให้ทำ load test ด้วยทราฟฟิกที่คาดว่าจะเจอ โดยเฉพาะเมื่อมีเสียงบ่นเรื่องประสิทธิภาพของ Traefik จึงควรระวังเป็นพิเศษ
-
NGINX Gateway Fabric
- อิมพลีเมนเทชัน Gateway API อย่างเป็นทางการของ F5 บนพื้นฐาน NGINX (NGF) มี conformance ที่แข็งแกร่ง และในเวอร์ชันล่าสุดได้เพิ่มการรองรับ Gateway API 1.5 รวมถึง CORS และการแก้ไข request/response header ผ่านฟิลเตอร์มาตรฐานของ HTTPRoute
- ความสามารถบางอย่าง เช่น การยืนยันตัวตนด้วย JWT และ OIDC, session persistence แบบอิง cookie, และการอัปเดต upstream โดยไม่ต้อง reload NGINX ยังคงผูกกับ NGINX Plus ซึ่งเป็นความต้องการที่พบได้บ่อยของ API Gateway
- สามารถ inject การตั้งค่า NGINX แบบ custom เข้าไปในหลายระดับของ config ที่ถูกสร้างขึ้นได้ผ่าน SnippetsPolicy และ SnippetsFilter แบบ custom ช่วยให้ย้ายระบบได้ง่ายโดยไม่ต้องเขียนการตั้งค่า custom จำนวนมากจาก NGINX Ingress เดิมใหม่ทั้งหมด
- รองรับ rate limiting ผ่าน RateLimitPolicy แบบ custom แต่เป็น local rate limiting ทำให้ state อยู่ใน NGINX data plane เมื่อรันหลาย NGF replica ค่าขีดจำกัดที่มีผลจริงจะเปลี่ยนตามจำนวนอินสแตนซ์ จึงยากต่อการจำกัดแบบเข้มงวดรายผู้ใช้
- มี escape hatch สำหรับการขยายความสามารถของ NGINX เอง เช่น การเขียนสคริปต์ JavaScript และ Lua แบบน้ำหนักเบา,
auth_requestสำหรับมอบหมายการยืนยันตัวตนไปยังภายนอก (คล้าย Envoy ext_authz และ Traefik ForwardAuth), และ custom C module แต่ยังไม่รองรับการแก้ไข request/response ผ่านบริการภายนอกแบบ ext_proc - ใน NGF 2.0 มีการปรับสถาปัตยกรรมใหม่โดยแยก control plane/data plane และรองรับ resource Gateway หลายตัว ซึ่งก่อนหน้านี้สถาปัตยกรรมถือเป็นข้อกังวลใหญ่
-
Cilium Service Mesh
- หลายคลัสเตอร์ใช้ Cilium เป็น CNI อยู่แล้ว และ service mesh แบบ sidecar-less ที่อิง eBPF นี้ก็มีอิมพลีเมนเทชัน Gateway API ที่ใช้ Envoy Proxy รวมอยู่ด้วย จึงช่วยลดจำนวนองค์ประกอบและทำให้เทคโนโลยีสแตกกระชับขึ้นได้
- อย่างไรก็ตาม โฟกัสหลักอยู่ที่ conformance ของ Gateway API ทำให้ความสามารถ Envoy ที่มีประโยชน์นอกเหนือจาก Gateway API ไม่ได้ถูกเปิดให้ตั้งค่าเป็น first-class เช่น การขยายความสามารถและปลั๊กอินของ Envoy, IP allowlisting, การตรวจสอบ JWT, claim-based authorization และการรองรับ OIDC แบบ first-class
- เว้นแต่จะมั่นใจว่าความสามารถ Gateway API ปัจจุบันของ Cilium เพียงพอแล้ว ก็ไม่แนะนำให้ใช้เป็น API Gateway ทั่วไปเมื่อเทียบกับตัวเลือกที่ครบกว่าอย่าง Envoy Gateway, kgateway หรือ Istio
-
Kong
- API Gateway ยอดนิยมที่ใช้ NGINX เป็นฐาน โดย Kong Operator รองรับทั้ง Ingress และ Gateway API
- ข้อกังวลหลักคือ กลยุทธ์ OSS โดยดูเหมือนว่าจะหยุดเผยแพร่ prebuilt Docker image สำหรับ Gateway เวอร์ชันโอเพนซอร์สตัวใหม่ และอิมเมจ OSS อาจหยุดอยู่แถวสายรีลีส 3.10 ทำให้ผู้ใช้ต้อง build, patch, harden และดูแลรักษาเอง
- มีการคาดเดาในที่สาธารณะว่ามาตรการนี้เกี่ยวข้องกับการลดการไหลออกของลูกค้า enterprise แต่ยังไม่อาจถือเป็นข้อเท็จจริงยืนยันได้ อย่างไรก็ดีทิศทางของ OSS จึงดูคาดเดาได้ยากขึ้น
- ดังนั้น หากไม่ได้ซื้อไลเซนส์ enterprise หรือพร้อมรับภาระการแพ็กเกจและดูแล OSS เอง ก็ไม่แนะนำให้เลือกใช้
-
Summary
- ติดตามวิวัฒนาการของแพตเทิร์น Kubernetes ingress ตั้งแต่ระยะแรกจนถึงยุคของ Gateway API พร้อมเจาะลึกตัวโปรโตคอล Gateway API เอง
- GAMMA (การขยายแนวคิดของ Gateway API ไปสู่ service mesh) และ Inference Extension (การนิยามและปรับแต่งเวิร์กโหลด inference บน Kubernetes) ถูกตัดออกจากขอบเขตโดยตั้งใจ เพราะเป็นหัวข้อที่ควรมีการเจาะลึกแยกต่างหาก
- ทบทวนอิมพลีเมนเทชัน Gateway API ที่มีให้ใช้งานและเกณฑ์ในการเลือกใช้ร่วมกัน
2 ความคิดเห็น
ปีที่แล้วเคยคิดจะลองใช้ NGF แต่จำได้ว่าตอนนั้นไม่มีวิธีทำการยืนยันตัวตนโดยอิงจาก
Authorizationheader เลยไปใช้ envoy แทนผมชอบ nginx มากกว่า envoy เลยคิดว่าถ้ารองรับ Gateway API ได้ครบทั้งหมด ครั้งหน้าก็น่าจะลองใช้ NGF ดู
อย่างนี้ Envoy ก็น่าจะดังขึ้นอีกสินะ