Tìm Hiểu Về Kubernetes Gateway API Với Kong Ingress Controller
Khám phá cách sử dụng Kubernetes Gateway API với Kong Ingress Controller. Hướng dẫn cấu hình HTTPRoute, GatewayClass, quản lý traffic và routing nâng cao.
Kubernetes đã trở thành tiêu chuẩn cho việc điều phối các ứng dụng container nhờ khả năng quản lý tự động và khai báo rõ ràng. Trước đây, đối tượng Ingress thường được sử dụng để xử lý lưu lượng truy cập từ bên ngoài vào các microservices bên trong cluster.
Tuy nhiên, Ingress có một số hạn chế nhất định: nó chủ yếu quản lý lưu lượng L7 (HTTP/HTTPS), giới hạn việc định tuyến trong cùng một namespace và thiếu các tính năng nâng cao như khớp (match) theo header hay query string.
Để giải quyết những hạn chế này, Gateway API đã ra đời. Nó cung cấp một bộ API Proxy linh hoạt hơn, hỗ trợ nhiều giao thức vượt ngoài HTTP và mô hình hóa chi tiết các thành phần hạ tầng. Đặc biệt, Gateway API phân chia rõ ràng vai trò và trách nhiệm (roles & personas) cho các team khác nhau trong hệ thống (như team hạ tầng, team vận hành cluster, team phát triển ứng dụng).
Trong bài viết này, TechCoBan sẽ cùng bạn tìm hiểu về Gateway API tiêu chuẩn và cách sử dụng Kong Ingress Controller (KIC) để khám phá sức mạnh mà Gateway API mang lại.
1. Cài đặt Gateway API CRD
Gateway API yêu cầu cài đặt thủ công một số Custom Resource Definitions (CRD). Chúng ta sẽ cài đặt các CRD tiêu chuẩn, bao gồm Package v1:
GatewayGatewayClassHTTPRoute
Chạy lệnh sau để cài đặt:
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
2. Infrastructure Ops (Vận hành hạ tầng)
Sau khi cài đặt CRD, bước tiếp theo là định nghĩa đối tượng GatewayClass. Đối tượng này mô tả các loại (loại hình) Gateway instances khác nhau. Thực chất, GatewayClass định nghĩa cách bạn muốn triển khai các instance Gateway với các cấu hình riêng biệt.
Ví dụ: Các nhà cung cấp hạ tầng có thể cung cấp GatewayClass nội bộ (internal) và bên ngoài (external). Gateway nội bộ có thể hỗ trợ stream listening, trong khi gateway bên ngoài chỉ hỗ trợ proxy listening.
Tạo GatewayClass
Hãy tạo một GatewayClass tên là kong-demo trong cluster và thiết lập controllerName là konghq.com/kic-gateway-controller. Đây là giá trị mặc định để Kong Ingress Controller nhận diện và quản lý các tài nguyên gắn với GatewayClass này.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong-demo
annotations:
konghq.com/gatewayclass-unmanaged: 'true'
spec:
controllerName: konghq.com/kic-gateway-controller
3. Cluster Operations (Vận hành Cluster)
Các đối tượng Gateway được dùng để tự động tạo ra các gateway instances dựa trên GatewayClass mà nó tham chiếu và các listeners được định nghĩa. Tuy nhiên, do Kong Gateway Operator vẫn đang trong giai đoạn thử nghiệm (tech preview), chúng ta sẽ tự triển khai Kong một cách thủ công.
Triển khai Kong Ingress Controller bằng Helm
Sử dụng Helm để cài đặt Kong. Đầu tiên, thêm repo của Kong và cập nhật:
helm repo add kong https://charts.konghq.com
helm repo update
Kiểm tra để chắc chắn phiên bản chart kong/ingress là 0.10.2 trở lên:
helm search repo kong/ingress -o json | jq .[].version
Cài đặt Kong Ingress Controller với tên release là my-kong:
helm upgrade -i my-kong kong/ingress -n kong \
--set gateway.image.tag=3.5 \
--set gateway.env.router_flavor=expressions \
--set gateway.admin.enabled=true \
--set gateway.admin.http.enabled=true \
--set controller.ingressController.installCRDs=false \
--create-namespace
Lưu ý: Nếu bạn dùng MetalLB và nó không tự động gán LoadBalancer IP, bạn có thể gán IP mong muốn (ví dụ:
192.168.18.150) vào Service proxy của Kong:
kubectl -n kong annotate service my-kong-gateway-proxy \
metallb.universe.tf/loadBalancerIPs=192.168.18.150
Tạo đối tượng Gateway
Vì chúng ta đang triển khai Kong thủ công, hãy đảm bảo rằng listener trên đối tượng Gateway khớp với Service Proxy của Kong.
Bạn có thể cấu hình Gateway dùng chung cho toàn bộ cluster (cho phép nhiều namespace sử dụng). Trong ví dụ dưới đây, chúng ta tạo Gateway tên kong-gw-demo ở namespace kong và cho phép các namespace có nhãn (label) shared-gateway-access: "true" được phép sử dụng Gateway này.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong-gw-demo
namespace: kong
spec:
gatewayClassName: kong-demo
listeners:
- name: proxy
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
shared-gateway-access: "true"
Mẹo: Bạn cũng có thể dùng matchExpressions để chỉ định đích danh tên của các namespaces được phép.
Triển khai ứng dụng Demo
Tiếp theo, hãy triển khai hai ứng dụng đơn giản (httpbin và nginx) để thử nghiệm:
Ứng dụng httpbin:
kubectl create namespace httpbin
kubectl label namespace httpbin shared-gateway-access=true
kubectl -n httpbin create deployment httpbin --image=mccutchen/go-httpbin
kubectl -n httpbin expose deployment httpbin --name httpbin-svc --port 8080
Ứng dụng nginx:
kubectl create namespace nginx
kubectl label namespace nginx shared-gateway-access=true
kubectl -n nginx create deployment nginx --image=nginx:alpine
kubectl -n nginx expose deployment nginx --name nginx-svc --port 80
4. Cấu hình HTTPRoute
HTTPRoute là thành phần quan trọng dùng để định nghĩa:
- Conditions (matches): Điều kiện để khớp với request.
- Process (filters): Xử lý request (ví dụ: sửa đổi header, chuyển hướng).
- Forward (backendRefs): Chuyển tiếp request đến Service backend.
A. HTTPRouteMatch (Các tiêu chí Match Request)
1. Match theo Path (Đường dẫn)
Tương tự Ingress, path hỗ trợ Exact (chính xác), PathPrefix (tiền tố) và RegularExpression (Biểu thức chính quy).
Exact Match:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: nginx-route
namespace: nginx
annotations:
konghq.com/strip-path: 'true'
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: kong-gw-demo
namespace: kong
rules:
- matches:
- path:
type: Exact
value: /nginx
backendRefs:
- name: nginx-svc
kind: Service
port: 80
PathPrefix Match:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: httpbin
annotations:
konghq.com/strip-path: 'true'
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: kong-gw-demo
namespace: kong
rules:
- matches:
- path:
type: PathPrefix
value: /test
backendRefs:
- name: httpbin-svc
kind: Service
port: 8080
RegularExpression (Regex):
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-regex-route
namespace: httpbin
annotations:
konghq.com/strip-path: 'true'
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: kong-gw-demo
namespace: kong
rules:
- matches:
- path:
type: RegularExpression
value: /api/v(1|2)
backendRefs:
- name: httpbin-svc
kind: Service
port: 8080
2. Match theo HTTP Header
Giờ đây, bạn có thể match trực tiếp theo Header trên HTTPRoute mà không cần dùng đến annotations.
Exact Header Match:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: httpbin
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: kong-gw-demo
namespace: kong
rules:
- matches:
- path:
type: PathPrefix
value: /test
headers:
- name: "x-version"
type: Exact
value: "2"
backendRefs:
- name: httpbin-svc
kind: Service
port: 8080
3. Match theo Query Parameters
Khi cấu hình router_flavor=expressions ở Kong, bạn có thể match request dựa theo query string của URL.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: httpbin
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: kong-gw-demo
namespace: kong
rules:
- matches:
- path:
type: PathPrefix
value: /test
queryParams:
- type: Exact
name: version
value: "2"
backendRefs:
- name: httpbin-svc
kind: Service
port: 8080
4. Match theo HTTP Method
Bạn cũng có thể chỉ định HTTPRoute chỉ nhận các phương thức cụ thể như GET hoặc POST.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: httpbin
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: kong-gw-demo
namespace: kong
rules:
- matches:
- path:
type: PathPrefix
value: /test
method: "POST"
- path:
type: PathPrefix
value: /test
method: "GET"
backendRefs:
- name: httpbin-svc
kind: Service
port: 8080
5. Match theo Hostname
Bạn có thể xác định hostnames cụ thể ở cấp độ HTTPRoute. Nếu Gateway listener không giới hạn hostname, nó sẽ chấp nhận tất cả. Tuy nhiên, nếu Listener trên Gateway quy định hostname (ví dụ: *.li.k8s), thì HTTPRoute chỉ hoạt động nếu hostname của nó khớp với điều kiện trên Gateway.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: httpbin
spec:
hostnames:
- proxy.li.k8s
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: kong-gw-demo
namespace: kong
rules:
- matches:
- path:
type: PathPrefix
value: /test
backendRefs:
- name: httpbin-svc
kind: Service
port: 8080
B. HTTPRouteFilter (Xử lý Request / Response)
HTTPRouteFilter giúp can thiệp vào vòng đời của request.
1. RequestHeaderModifier
Cho phép set (ghi đè), add (thêm), hoặc remove (xóa) header của Request trước khi gửi đến Backend.
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: x-test-id
value: fomm
set:
- name: User-Agent
value: fomm-local
remove: ["Accept"]
2. ResponseHeaderModifier
Hoạt động tương tự đối với Response trả về từ Backend.
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: x-test-id
value: fomm
set:
- name: User-Agent
value: fomm-local
remove: ["Access-Control-Allow-Origin"]
3. RequestRedirect
Cho phép chặn yêu cầu và Redirect thẳng đến một địa chỉ khác (sẽ bỏ qua backendRefs).
filters:
- type: RequestRedirect
requestRedirect:
scheme: http
hostname: httpbin.org
path:
type: ReplaceFullPath
replaceFullPath: /anything/paprika
statusCode: 301
port: 80
C. ExtensionRef (Tích hợp Kong Plugin)
ExtensionRef giúp tận dụng sức mạnh của nhà cung cấp (ở đây là Kong) bằng cách gán trực tiếp KongPlugin lên HTTPRoute.
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: key-auth-example
namespace: httpbin
plugin: key-auth
config:
key_names:
- apikey
---
# ... (Phần cấu hình HTTPRoute)
filters:
- type: ExtensionRef
extensionRef:
group: configuration.konghq.com
kind: KongPlugin
name: key-auth-example
5. BackendRefs nâng cao
Cross-namespace routing (Định tuyến khác Namespace)
Ingress truyền thống không cho phép route traffic đến Service ở một namespace khác. Với Gateway API, điều này hoàn toàn có thể thông qua ReferenceGrant.
Ví dụ, HTTPRoute ở namespace kong muốn trỏ đến httpbin-svc ở namespace httpbin:
Bước 1: HTTPRoute ở namespace kong trỏ đến httpbin-svc (namespace: httpbin).
Bước 2: Cấp quyền bằng ReferenceGrant ở namespace httpbin:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: httpbin-grant-kong
namespace: httpbin
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: kong
to:
- group: ""
kind: Service
Weighted routing (Chia tỷ lệ truy cập / Traffic Splitting)
Rất hữu ích cho Canary Deployment. Dưới đây là cách chia 90% traffic vào httpbin và 10% vào nginx:
backendRefs:
- name: httpbin-svc
namespace: httpbin
kind: Service
port: 8080
weight: 90
- name: nginx-svc
namespace: nginx
kind: Service
port: 80
weight: 10
Tổng kết
Kubernetes Gateway API là tương lai của việc quản lý lưu lượng K8s và nên bắt đầu khám phá tiêu chuẩn mới này. Sự kết hợp giữa Gateway API và Kong Ingress Controller mang lại một hệ thống định tuyến cực kỳ mạnh mẽ, rõ ràng, phân quyền tốt và dễ dàng mở rộng.
Vẫn còn rất nhiều tính năng thú vị để khám phá như TLS termination, tích hợp cert-manager và L4 routing. Hẹn gặp lại các bạn ở các bài viết tiếp theo của TechCoBan!
Bình luận
Bài viết liên quan
Tất Tần Tật Về kgateway: Đột Phá Mới Trong Quản Lý Lưu Lượng Kubernetes
Khám phá kgateway (trước đây là Gloo) - giải pháp API Gateway, Ingress Controller và AI Gateway toàn diện cho Kubernetes dựa trên Envoy Proxy.
Hướng Dẫn Triển Khai Cài Đặt RKE2 Chuẩn Production On-Premises
Bài viết hướng dẫn chi tiết từng bước cách cài đặt và cấu hình cụm Kubernetes với RKE2 (Rancher Kubernetes Engine 2) chuẩn Production, đảm bảo High Availability (HA) và an toàn bảo mật.
Xây dựng CI/CD Pipeline tự động với GitHub Actions
Học cách thiết lập hệ thống Tích hợp liên tục (CI) và Phân phối liên tục (CD) tự động hoàn toàn bằng GitHub Actions.