Giới hạn của Ingress truyền thống
Tôi đã mất không biết bao nhiêu giờ vật lộn với các Nginx Ingress annotations. Nếu bạn đã từng thử triển khai canary release hoặc blue-green deployment bằng Ingress tiêu chuẩn, có lẽ bạn đã phải đối mặt với một “bức tường” metadata nginx.ingress.kubernetes.io/... dài tới 50 dòng. Những annotation này rất dễ lỗi, khó debug và—tệ nhất là—chúng khóa bạn vào một nhà cung cấp cụ thể. Nếu bạn chuyển từ Nginx sang HAProxy, bạn sẽ phải viết lại toàn bộ logic định tuyến từ đầu.
Vấn đề không chỉ nằm ở cú pháp; đó là vấn đề về cấu trúc. Ingress được xây dựng cho một kỷ nguyên đơn giản hơn của web. Nó giả định một mô hình cơ bản: một host, một path, một backend. Các yêu cầu hiện đại như định tuyến dựa trên header (header-based routing), traffic mirroring hoặc cân bằng tải theo trọng số (weighted balancing) không phù hợp với khuôn mẫu đó. Chúng ta đã dành nhiều năm ép buộc Ingress hoạt động bằng các bản hack từ nhà cung cấp, nhưng điều này đã tạo ra một hệ sinh thái phân mảnh, nơi các cấu hình không thể chuyển đổi linh hoạt giữa các controller khác nhau.
Nút thắt cổ chai về mặt tổ chức
Trong thực tế, điểm gây khó khăn lớn nhất thường là yếu tố con người, không phải kỹ thuật. Ingress truyền thống buộc các quản trị viên cluster và nhà phát triển ứng dụng phải chỉnh sửa cùng một tệp YAML. Khi một developer cập nhật path cho microservice của họ, họ có thể vô tình làm hỏng cấu hình TLS toàn cục do đội ngũ bảo mật quản lý. Đây chính là “công thức” dẫn đến các sự cố trên môi trường production.
Kubernetes Gateway API giải quyết vấn đề này bằng cách chia cấu hình thành các tài nguyên riêng biệt, hướng theo vai trò:
- GatewayClass: Được thiết lập bởi Platform Team để xác định loại load balancer (ví dụ: AWS, GKE hoặc Envoy).
- Gateway: Được quản lý bởi Cluster Operators để xử lý các điểm truy cập (entry points), địa chỉ IP và chứng chỉ TLS.
- HTTPRoute: Thuộc sở hữu của App Developers để xác định cách lưu lượng truy cập đến các dịch vụ cụ thể của họ.
Sự phân tách trách nhiệm này biến việc quản trị mạng thành một mô hình tự phục vụ (self-service). Các nhà phát triển có thể triển khai mã nguồn và thay đổi định tuyến mà không bao giờ cần chạm vào các thiết lập Gateway ở cấp độ hạ tầng.
Bắt đầu nhanh: Triển khai Gateway đầu tiên của bạn (5 phút)
Để thử nghiệm điều này, bạn cần Gateway API Custom Resource Definitions (CRDs) và một controller tương thích. Mặc dù các tùy chọn như Cilium hoặc Istio rất phổ biến, nhưng Envoy Gateway là lựa chọn ưu tiên của tôi nhờ thiết kế gọn nhẹ và tuân thủ các tiêu chuẩn.
1. Cài đặt các CRD
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml
2. Cài đặt Envoy Gateway
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system --create-namespace
3. Định nghĩa một Gateway
Tài nguyên này đóng vai trò là điểm truy cập của bạn. Nó hướng dẫn controller lắng nghe lưu lượng HTTP trên cổng 80.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-gateway
namespace: infra-ns
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
4. Ánh xạ một Service với HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
namespace: app-ns
spec:
parentRefs:
- name: prod-gateway
namespace: infra-ns
rules:
- matches:
- path:
type: PathPrefix
value: /v1/api
backendRefs:
- name: user-service
port: 8080
Sức mạnh của cơ chế “Bắt tay”
Lưu ý phần parentRefs trong HTTPRoute ở trên. Đây chính là “bí kíp”. Route phải trỏ rõ ràng đến một Gateway và Gateway phải cho phép các Route từ namespace cụ thể đó. Cơ chế bắt tay hai chiều này ngăn chặn việc một developer trong namespace ‘test’ vô tình chiếm dụng lưu lượng dành cho namespace ‘production’. Đó là bảo mật ngay từ khâu thiết kế (security by design).
Kiểm soát lưu lượng nâng cao: Không cần Service Mesh
Phân tách lưu lượng gốc (Native traffic splitting) là nơi Gateway API vượt xa Ingress. Bạn không còn cần một Service Mesh nặng nề chỉ để chạy thử nghiệm canary.
Định tuyến theo trọng số cho Canary Releases
Giả sử bạn đang triển khai phiên bản v2 cho dịch vụ thanh toán (checkout service). Bạn có thể gửi chính xác 10% lưu lượng truy cập đến phiên bản mới chỉ với một thay đổi trọng số đơn giản:
spec:
rules:
- backendRefs:
- name: checkout-v1
port: 80
weight: 90
- name: checkout-v2
port: 80
weight: 10
Định tuyến chính xác qua Headers
Tôi thường xuyên sử dụng định tuyến dựa trên header để thử nghiệm các tính năng mới với nhân viên nội bộ. Bạn có thể định tuyến người dùng có cookie hoặc header cụ thể trực tiếp đến một pod beta mà không ảnh hưởng đến người dùng chung:
rules:
- matches:
- headers:
- name: x-user-group
value: internal-beta
backendRefs:
- name: feature-lab-service
port: 80
- backendRefs:
- name: stable-service
port: 80
Ba bài học từ môi trường Production
Việc chuyển đổi không chỉ là thay đổi tệp YAML; đó là thay đổi cách bạn quản lý cluster. Dưới đây là những gì tôi đã học được sau khi di chuyển nhiều môi trường production.
1. Loại bỏ tình trạng “Tràn lan Load Balancer”
Một AWS NLB đơn lẻ tiêu tốn khoảng 18 USD/tháng trước khi tính phí xử lý dữ liệu. Trong một cluster có 50 dịch vụ, nơi mỗi dịch vụ sử dụng Ingress riêng, bạn có thể đang lãng phí gần 1.000 USD hàng tháng cho hạ tầng nhàn rỗi. Gateway API cho phép bạn chia sẻ một Gateway (và một IP) trên hàng chục namespace, giúp cắt giảm đáng kể hóa đơn đám mây của bạn.
2. Kiểm tra hỗ trợ tính năng
Mặc dù API cốt lõi đã đạt trạng thái GA (General Availability), các bộ lọc nâng cao như viết lại URL (URL rewrites) hoặc header tùy chỉnh có thể vẫn đang ở kênh “Experimental” đối với nhà cung cấp cụ thể của bạn. Hãy luôn chạy lệnh kubectl get gatewayclass để xem controller của bạn thực sự hỗ trợ những gì trước khi bắt tay vào thiết kế.
3. Tin tưởng vào khối Status
Việc debug Ingress trước đây thường liên quan đến việc lục tìm trong các log controller khó hiểu. Gateway API hiển thị các lỗi trực tiếp trong trạng thái (status) của tài nguyên. Nếu một route bị lỗi, hãy chạy lệnh:
kubectl describe httproute api-route
Phần Conditions sẽ cho bạn biết ngay lập tức nếu dịch vụ backend bị thiếu hoặc nếu Gateway từ chối kết nối. Đây là một cải thiện lớn về trải nghiệm làm việc cho các kỹ sư trực chiến (on-call engineers).
Lời kết
Gateway API là tiêu chuẩn mới cho kết nối mạng trong Kubernetes. Nó thay thế các annotation đặc thù của nhà cung cấp bằng logic sạch sẽ, có khả năng di động cao, phù hợp với cách các đội ngũ hiện đại thực sự làm việc. Mặc dù Ingress vẫn hoạt động tốt cho các dự án nhỏ và đơn giản, nhưng bất kỳ môi trường nào mở rộng quy mô vượt quá một vài dịch vụ nên bắt đầu chuyển sang Gateway API ngay hôm nay. Nó mạnh mẽ hơn, chi phí vận hành rẻ hơn và dễ dàng khắc phục sự cố hơn nhiều khi có vấn đề xảy ra.

