Table of Contents
- บทนำ (Introduction)
- สิ่งที่ต้องเตรียม/ควรรู้ (Prerequisites)
- Kubernetes Gateway API คืออะไร?
- Concept ของ Kubernetes Gateway API
- ข้อดีของ Gateway API และสิ่งที่ต่างจาก(เหนือกว่า) Ingress
- Gateway API มาแทน Ingress จริงมั้ย?
- บทสรุป (Conclusion)
บทนำ (Introduction)
เมื่อพูดถึงการ expose service หรือ application ที่อยู่บน Kubernetes ให้สามารถเข้าถึงได้จากภายนอก หลายคนคงนึกถึง Ingress เป็นอย่างแรก ซึ่ง Ingress แม้จะใช้งานกันมานานแล้วแต่ก็มีข้อจำกัดหลายอย่าง เช่น ไม่รองรับ non-HTTP protocols หรือฟีเจอร์บางอย่างต้องพึ่งพา annotations เฉพาะของแต่ละ controller ซึ่งไม่เป็นมาตรฐานเดียวกัน
เมื่อ 31 ตุลาคม 2023 ที่ผ่านมา Kubernetes ได้ประกาศ GA (generally available) สำหรับ Gateway API ไปเรียบร้อยหลังจากพัฒนามาประมาณ 4 ปีนับตั้งแต่ครั้งแรกที่มีการเสนอไอเดียนี้ในงาน KubeCon San Diego
โดย Gateway API จะเข้ามาแก้ปัญหาบางอย่างของ Ingress และเพิ่มความสามารถใหม่ ๆ เข้ามา รวมถึงเป็นมาตรฐานสำหรับการจัดการ service networking บน Kubernetes หลังจากนี้ไป
สิ่งที่ต้องเตรียม/ควรรู้ (Prerequisites)
บทความนี้จะใช้ความรู้พื้นฐานเกี่ยวกับ Kubernetes และ Ingress หากยังไม่คุ้นเคยสามารถศึกษาได้จาก link ด้านล่างครับ
- พื้นฐาน Kubernetes จาก official documents
- บทความ Kubernetes Services และ Kubernetes Ingress ต่างกันยังไง?
Kubernetes Gateway API คืออะไร?
Gateway API คือ concept ใหม่ที่ถูกเพิ่มเข้ามาใน Kubernetes โดยเป็น resources ซึ่งทำหน้าที่จัดการเรื่องการเข้าถึงจากภายนอกมาสู่ Kubernetes Services ผ่านการทำ routing ในรูปแบบต่าง ๆ โดยที่มันสามารถทำทุกอย่างที่ Ingress ทำได้ เพียงแต่มีความสามารถอื่น ๆ เพิ่มเติมขึ้นมา (เดี๋ยวจะอธิบายเพิ่มหลังจากนี้)
Concept ของ Kubernetes Gateway API
Gateway API ถูกออกแบบมาโดยมีแนวคิดในการแยกหน้าที่ของผู้ที่เกี่ยวข้อง (role-oriented) เป็น 3 กลุ่ม ทำให้เราแยกส่วนบริหารจัดการตามความรับผิดชอบได้ดีขึ้น โดยแต่ละกลุ่มเกี่ยวข้องกับ resources ที่ต่างกันดังนี้
1. GatewayClass
Resource
GatewayClass คือ implementation template สำหรับ gateway ที่กำหนดโดย provider หรือผู้ให้บริการ infrastructure ซึ่งมี gateway controller ของตัวเอง เช่น cloud provider อย่าง AWS, Azure หรือรวมไปถึง Istio, NGINX, Kong, HAProxy และอื่น ๆ โดย GatewayClass ใช้ในการสร้าง gateway ขึ้นมา และ user อาจไม่จำเป็นต้องเข้าใจว่า GatewayClass นั้นมีการ implement ยังไง แค่รู้ว่าจะต้องเลือกใช้ GatewayClass ตัวไหนก็พอ
ยกตัวอย่าง GatewayClass ของ AWS (Amazon EKS) เค้าใช้ AWS Gateway API controller จับคู่กับ VPC Lattice ซึ่งถ้าหากเรามีการสร้าง Gateway API resource ขึ้นมาบน Kubernetes เจ้า controller ก็จะไปสร้าง service network resources บน VPC Lattice เพื่อจัดการเรื่อง network ให้กับเราโดยที่เราไม่จำเป็นต้องรู้จัก VPC Lattice เลยด้วยซ้ำ
ตรงนี้ก็ขึ้นอยู่กับแต่เจ้าว่าจะใช้เทคนิคอะไรใน controller ของตัวเอง
ตัวอย่าง GatewayClass Manifest ของ Istio
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio
spec:
controllerName: istio.io/gateway-controller
2. Gateway
Resource
Gateway
คือ resource ที่ทำหน้าที่เสมือนเป็นประตูทางเข้าสำหรับรับ traffic จากข้างนอก cluster โดยมันถูกสร้างมาจาก GatewayClass (กำหนดที่ gatewayClassname
) ซึ่งตาม concept แล้ว cluster operator จะเป็นผู้สร้างมันขึ้นมา โดยจะกำหนดรายละเอียดในส่วนของ listener เช่น IP, hostname, port, protocol, TLS certificate เป็นต้น
โดย gateway ที่ถูกสร้างขึ้นจริงจะเป็นแบบไหนก็ขึ้นอยู่กับ GatewayClass
ว่ากำหนดไว้ยังไง อาจสร้างเป็น load balancer ใน cloud ก็ได้ หรือเป็น proxy ใน Kubernetes cluster ก็ได้เช่นกัน (เค้าพยายาม abstract ให้มันง่ายสำหรับมุมของ user บน Kubernetes)
ตัวอย่าง Gateway Manifest
สร้าง gateway เพื่อรับ HTTP request ที่ถูกส่งเข้ามาที่ *.nopnithi.com
จากทุก namespace โดยใช้ solution ของ Istio
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: nopnithi-gateway
namespace: infra
spec:
gatewayClassName: istio
listeners:
- name: default
hostname: "*.nopnithi.com"
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
3. HTTPRoute
Resource
HTTPRoute
คือ resource ที่ใช้กำหนด rule เพื่อ route traffic ไปยัง Kubernetes Services ต่าง ๆ โดยต้องกำหนดด้วยว่าจะใช้ gateway ไหนการรับ traffic เข้ามา และตาม concept แล้ว developer จะเป็นคนจัดการส่วนนี้
นอกจาก
HTTPRoute
ก็ยังมีตัวอื่น ๆ เช่นTCPRoute
,UDPRoute
,TLSRoute
หรือGPRCRoute
ด้วยแต่ยังอยู่ในช่วงทดสอบ (experimental) อยู่ครับ ยังไม่รวมตัวที่อาจจะมาจาก community อีกเพียบหลังจากนี้
ตัวอย่าง HTTPRoute Manifest
สร้าง route สำหรับ app1.nopnithi.com
โดย…
- กำหนดให้ path
/blog
ชี้ไปที่ serviceblog
ใน namespaceapp1
- ส่วนที่เหลือ (default) ชี้ไป service
home
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app1
namespace: app1
spec:
parentRefs:
- name: nopnithi-gateway
namespace: infra
hostnames: ["app1.nopnithi.com"]
rules:
- backendRefs:
- name: home
port: 8080
- matches:
- path:
type: PathPrefix
value: /blog
backendRefs:
- name: blog
port: 8080
สร้าง route สำหรับ app2.nopnithi.com
โดยชี้ไปที่ service home
ทั้งหมด
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app2
namespace: app2
spec:
parentRefs:
- name: nopnithi-gateway
namespace: infra
hostnames: ["app2.nopnithi.com"]
rules:
- backendRefs:
- name: home
port: 8080
สังเกตว่า gateway ผมอยู่ที่ namespace
infra
ส่วน HTTPRoute อยู่ที่ namespaceapp1
และapp2
นี่เป็นอีกหนึ่งสิ่งที่ Ingress ทำไม่ได้และต้องพึ่งพา service mesh เข้ามาช่วย
สรุปสั้น ๆ ให้เข้าใจง่าย
GatewayClass
คือ แบบ (blueprint) สำหรับสร้างประตู / infrastructure provider เป็นคนสร้างGateway
คือ ประตูสำหรับ traffic ขาเข้า / operator เป็นคนสร้างและกำหนดว่าใครเข้ามาได้บ้างHTTPRoute
คือ เส้นทางหลังจากเข้าประตูมา / developer เป็นคนกำหนดว่าเข้ามาแล้วจะไปที่ไหนบ้าง
ข้อดีของ Gateway API และสิ่งที่ต่างจาก(เหนือกว่า) Ingress
- Ingress ทำงานได้ในระดับ layer 7 protocols (HTTP/HTTPS) เท่านั้น ส่วน Gateway API ทำได้ทั้ง layer 4 และ 7
- แม้ Ingress จะสามารถทำ routing customization หรือ traffic management ได้ แต่ก็ต้องพึ่งพาความสามารถของ controller ซึ่งแต่ละตัวก็ทำได้ไม่เท่ากัน รวมถึงมีวิธีการ configure ต่างกัน เช่น
- HTTP method routing
- HTTP redirect และ rewrite
- Header modification
- Traffic splitting
- Request mirroring
- Cross-namespace routing
- TCP/UDP/gRPC routing และอื่น ๆ
- ส่วนมากจะเป็นการใช้ annotations ซึ่งไม่มีมาตรฐานเพราะขึ้นอยู่กับแต่ละ controller ในขณะที่ Gateway API นั้นมี spec ที่เป็นมาตรฐานเดียวกันทั้งหมดไม่ว่าใช้
GatewayClass
ตัวไหน - Ingress ไม่สามารถแยกส่วนการจัดการที่ชัดเจนได้ เพราะ configuration ทั้งหมดอยู่ที่ Ingress resource ต่างกับ Gateway API ที่แยกชัดเจน (
GatewayClass
,Gateway
,HTTPRoute
) - Gateway API เปิดช่องให้สามารถสร้าง custom route เพิ่มเติมได้ด้วย CRDs (Custom Resource Definitions) เช่น
KafkaRoute
,MongoDBRoute
,MySQLRoute
,RedisRoute
หรือRabbitMQRoute
และอื่น ๆ
Gateway API มาแทน Ingress จริงมั้ย?
แน่นอนครับ เพราะใน Kubernetes docs ของ Ingress เขียนไว้ชัดเจนว่า “Ingress is frozen. New features are being added to the Gateway API” ดังนั้นหลังจากนี้ Ingress คงจะไม่มีฟีเจอร์ใหม่ ๆ เพิ่มแล้ว แต่จะไปต่อกันที่ Gateway API แทน
อย่าสับสนนะครับ Gateway API ไม่ใช่ API gateway นะ
บทสรุป (Conclusion)
ในบทความนี้เราได้ทำความรู้จัก Kubernetes Gateway API ซึ่งเป็น resource สำหรับจัดการ service networking บน Kubernetes ที่พึ่งจะ GA ไปได้ไม่กี่เดือน แต่มีแนวโน้มชัดเจนว่าจะเข้ามาแทนที่ Ingress ในอนาคต (Kubernetes platform หลายเจ้าเริ่ม support แล้ว)
เมื่อเทียบกับ Ingress แล้ว Gateway API มีความสามารถที่ดีกว่า, ยืดหยุ่นกว่า, เรียบง่ายกว่า, มีมาตรฐานเดียวกัน และบางกรณีก็อาจจะทำให้เราไม่ต้องใช้ service mesh โดยไม่จำเป็น แถมยังช่วยในการแบ่งหน้าที่ความรับผิดชอบระหว่างทีม operations และ development ได้ดีขึ้นด้วย
ส่วนตัวผมแนะนำว่าถ้าเริ่ม project ใหม่ก็ลองพิจารณาใช้ Gateway API แทน Ingress กันดูนะครับ