Chọn chiến lược Gateway phù hợp cho Kubernetes
Việc mở rộng quy mô từ 5 lên đến 50 microservices chính là lúc những rắc rối thực sự bắt đầu. Trong khi việc quản lý một vài dịch vụ khá dễ dàng, thì việc nhúng logic xác thực và điều phối lưu lượng vào từng ứng dụng đơn lẻ sẽ tạo ra một khoản nợ bảo trì khổng lồ. Tôi đã chứng kiến nhiều đội ngũ tốn hàng tuần trời để đồng bộ hóa các chính sách rate-limiting (giới hạn lưu lượng) trên nhiều ngôn ngữ lập trình khác nhau, chỉ để nhận ra rằng họ cần một cách tiếp cận tập trung hơn ở phía biên (edge).
Khi lập kế hoạch cho chiến lược lưu lượng mạng trong Kubernetes, bạn thường sẽ gặp ba lựa chọn chính:
- Ingress Controller tiêu chuẩn (như Nginx): Đây là những công cụ đắc lực cho việc định tuyến L7 cơ bản và SSL. Tuy nhiên, chúng thường thiếu các tính năng nâng cao như phân tầng người tiêu dùng (consumer-tiering) hoặc quản lý API key phức tạp.
- Service Mesh (như Istio): Đây là giải pháp hạng nặng, hoàn hảo cho bảo mật nội bộ giữa các dịch vụ (service-to-service). Tuy nhiên, chi phí vận hành và chi phí tài nguyên của sidecar thường quá cao đối với các đội ngũ mới bắt đầu.
- API Gateway (như Kong): Đây là sự lựa chọn cân bằng nhất. Kong quản lý lưu lượng North-South (từ người dùng đến dịch vụ) với một thư viện khổng lồ gồm hơn 100 plugin có sẵn.
Trong thực tế, Kong chiếm ưu thế nhờ sự cân bằng giữa hiệu năng thuần túy và một hệ sinh thái mạnh mẽ. Tôi đã triển khai giải pháp này trong các môi trường production yêu cầu độ trễ dưới 1 mili giây. Mô hình Kubernetes Ingress Controller (KIC) giúp thiết lập này mang lại cảm giác như một phần gốc của cụm (cluster) thay vì là một thành phần bổ trợ rời rạc.
Sự đánh đổi: Tại sao chọn Kong?
Tại sao giải pháp này hiệu quả
- Hệ sinh thái Plugin: Bạn có thể bật/tắt JWT, OAuth2 và CORS thông qua file YAML. Không còn phải viết những đoạn mã lặp đi lặp lại (boilerplate) trong các dịch vụ Go hay Java của bạn nữa.
- Thông lượng cao: Được xây dựng trên Nginx và OpenResty, Kong xử lý hàng nghìn yêu cầu đồng thời với mức biến động CPU tối thiểu.
- Sẵn sàng cho GitOps: Cấu hình được lưu trữ trong các Custom Resource Definitions (CRDs). Điều này có nghĩa là các thiết lập gateway của bạn được quản lý phiên bản ngay cạnh mã nguồn ứng dụng.
Nhìn nhận thực tế
- Quá mức cần thiết cho ứng dụng đơn giản: Nếu bạn chỉ có hai dịch vụ và không cần xác thực ở phía biên, một Nginx controller cơ bản sẽ đơn giản hơn.
- Quản lý trạng thái: Mặc dù Kong truyền thống cần Postgres, nhưng chế độ DB-less là lựa chọn tối ưu cho K8s, dù nó đòi hỏi một tư duy khác khi cập nhật cấu hình.
Cấu hình khuyến nghị: DB-less và điều khiển bằng CRD
Đối với các môi trường Kubernetes hiện đại, tôi luôn khuyến nghị sử dụng chế độ DB-less. Thay vì phải duy trì một instance Postgres riêng biệt, chúng ta coi Kubernetes là nguồn chân lý (source of truth). Các thiết lập của bạn sẽ nằm trong ETCD. Kong Ingress Controller sẽ theo dõi các thay đổi và đẩy chúng trực tiếp vào bộ nhớ của Kong.
Kiến trúc này gọn nhẹ và có khả năng phục hồi cao. Chúng ta sẽ tập trung vào ba trụ cột của một API vững chắc: Bảo mật (JWT), Kiểm soát lưu lượng (Rate Limiting), và Khả năng quan sát (Prometheus/Grafana).
Hướng dẫn triển khai: Thiết lập Kong
1. Cài đặt qua Helm
Helm là tiêu chuẩn ở đây vì nó giúp chúng ta quản lý các định nghĩa RBAC và service phức tạp. Hãy khởi chạy gateway trong một namespace riêng biệt.
helm repo add kong https://charts.konghq.com
helm repo update
# Tạo một namespace để quản lý API
kubectl create namespace kong
# Cài đặt Kong ở chế độ DB-less
helm install kong kong/kong -n kong \
--set ingressController.enabled=true \
--set env.database=off
2. Triển khai một dịch vụ thử nghiệm
Chúng ta cần một mục tiêu. Dịch vụ echo đơn giản này sẽ đóng vai trò là microservice nội bộ để kiểm tra xem lưu lượng có đang lưu thông chính xác hay không.
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-service
spec:
replicas: 1
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: ealen/echo-server
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: echo-service
spec:
ports:
- port: 80
targetPort: 80
selector:
app: echo
3. Bảo vệ Backend bằng Rate Limiting
Một giải pháp nhanh chóng để ổn định hệ thống production là ngăn chặn các cuộc tấn công brute-force hoặc các script chạy ngoài tầm kiểm soát. Chúng ta sẽ định nghĩa một KongPlugin để giới hạn số lượng yêu cầu ở mức 5 lần mỗi phút cho bản demo này. Trong thực tế, bạn có thể đặt mức này là 1.000 lần mỗi giây tùy thuộc vào năng lực hệ thống.
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: global-rate-limit
namespace: kong
config:
minute: 5
policy: local
plugin: rate-limiting
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress
annotations:
konghq.com/plugins: global-rate-limit
spec:
ingressClassName: kong
rules:
- http:
paths:
- path: /echo
pathType: ImplementationSpecific
backend:
service:
name: echo-service
port:
number: 80
4. Chuyển giao xác thực JWT
Việc chuyển logic xác thực sang gateway giúp mã nguồn dịch vụ của bạn gọn gàng hơn. Đầu tiên, hãy bật plugin JWT. Sau đó, tạo một “Consumer” — một thực thể được phép gọi API của bạn.
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: jwt-auth
namespace: kong
plugin: jwt
---
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: mobile-app-user
namespace: kong
username: mobile-app-user
credentials:
- mobile-app-jwt-secret
---
apiVersion: v1
kind: Secret
metadata:
name: mobile-app-jwt-secret
namespace: kong
type: Opaque
stringData:
kongCredType: jwt
key: "issuer-77" # Khớp với claim 'iss' trong JWT của bạn
secret: "giu-bi-mat-nay-that-ky"
Sau khi cập nhật annotations của Ingress để bao gồm jwt-auth, Kong sẽ chặn mọi yêu cầu thiếu token hợp lệ. Backend của bạn thậm chí sẽ không bao giờ phải thấy những lưu lượng chưa được xác thực đó.
5. Giám sát với Prometheus
Khả năng quan sát (Observability) không phải là tùy chọn đối với lưu lượng production. Tôi luôn kết nối Kong với Prometheus để theo dõi độ trễ và tỷ lệ lỗi 4xx/5xx. Kong cung cấp một plugin gốc giúp hiển thị các chỉ số này ngay lập tức.
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: prometheus-metrics
namespace: kong
plugin: prometheus
config:
per_consumer: true
Sau khi áp dụng cấu hình này, Kong sẽ cung cấp một endpoint metrics trên cổng 8001. Hãy trỏ bộ thu thập dữ liệu (scraper) của Prometheus vào đó. Để có một hệ thống giám sát chuyên nghiệp nhanh chóng, hãy nhập Grafana Dashboard ID 7424 để xem khối lượng lưu lượng và tình trạng sức khỏe hệ thống theo thời gian thực.
Lời kết về việc mở rộng quy mô
Tôi đã từng lo lắng về việc thêm một bước nhảy (hop) nữa trên đường truyền mạng. Tuy nhiên, lợi ích của việc tập trung hóa bảo mật và kiểm soát lưu lượng vượt xa mức ảnh hưởng nhỏ về độ trễ. Bằng cách sử dụng DB-less, bạn loại bỏ rủi ro nghẽn kết nối cơ sở dữ liệu và giữ cho gateway của mình thực sự mang tính tạm thời (ephemeral).
Nếu sau này bạn cần OIDC hoặc hỗ trợ cấp doanh nghiệp (enterprise), việc nâng cấp từ thiết lập này là rất đơn giản. Đối với hầu hết các đội ngũ kỹ thuật, cách tiếp cận dựa trên CRD này mang lại sự cân bằng hoàn hảo về khả năng kiểm soát mà không gây ra cơn ác mộng vận hành như một hệ thống service mesh đầy đủ.

