Gateway API Architecture — GatewayClass, Gateway, HTTPRoute và GKE Implementation
Tại sao Gateway API ra đời
Ingress API trong Kubernetes có một vấn đề thiết kế cơ bản: nó cố gắng phục vụ tất cả trong một resource. Platform operator, application developer, và infrastructure provider đều thao tác trên cùng một Ingress object. Điều này dẫn đến:
- Conflict permissions: developer phải có quyền edit Ingress để thêm routing rule, nhưng cùng Ingress đó cũng chứa TLS config và IP assignment mà chỉ operator mới nên touch
- Thiếu expressiveness: không thể làm header matching hay traffic weighting chỉ với Ingress annotations
- Fragmentation: mỗi Ingress controller (nginx, HAProxy, Traefik) implement annotations khác nhau, không portable
Gateway API (Kubernetes SIG Network standard) giải quyết bằng cách tách biệt theo role và tăng expressiveness thông qua resources riêng biệt.
Ba-layer resource model
Gateway API chia control thành ba lớp resource, mỗi lớp thuộc về một role khác nhau:
Infrastructure Provider
│ định nghĩa
▼
GatewayClass ← "Loại LB nào tồn tại trong cluster này?"
│
│ tham chiếu
▼
Cluster Operator
│ tạo
▼
Gateway ← "Frontend: IP, port, TLS, namespace policy"
│
│ route attachment
▼
Application Developer
│ tạo
▼
HTTPRoute ← "Routing rules: path, header, weight"Điểm quan trọng: Gateway và HTTPRoute không nhất thiết phải cùng namespace. Một Gateway ở namespace infra có thể nhận HTTPRoutes từ nhiều namespaces khác nhau — đây là enabler cho self-service routing trong platform model.
GatewayClass — Infrastructure definition
GatewayClass là cluster-scoped resource (không thuộc namespace nào). Mỗi GatewayClass định nghĩa một loại load balancer infrastructure cụ thể mà controller biết cách provision.
GKE tự động cài sẵn các GatewayClasses khi enable Gateway API:
# Ví dụ: xem GatewayClasses có sẵn
kubectl get gatewayclass
# NAME CONTROLLER
# gke-l7-global-external-managed networking.gke.io/gateway
# gke-l7-regional-external-managed networking.gke.io/gateway
# gke-l7-rilb networking.gke.io/gateway
# gke-l7-gxlb networking.gke.io/gatewayMapping GatewayClass → GCP Load Balancer
| GatewayClass | GCP LB type | Scope | Ghi chú |
|---|---|---|---|
gke-l7-global-external-managed | Global External Application LB | Global (Premium tier) | Recommended cho internet-facing |
gke-l7-regional-external-managed | Regional External Application LB | Regional | Internet-facing, regional scope |
gke-l7-rilb | Internal Application LB | Regional (trong VPC) | Private services |
gke-l7-gxlb | Classic Global External ALB | Global | Legacy, không support advanced features |
Cơ chế: GatewayClass chứa spec.controllerName chỉ định controller nào xử lý. Tất cả GKE GatewayClasses đều có controllerName: networking.gke.io/gateway — đây là GKE Gateway controller được Google quản lý.
Khi bạn tạo một Gateway tham chiếu một GatewayClass, GKE Gateway controller nhận event và bắt đầu provision GCP LB resources phù hợp với loại LB được định nghĩa bởi GatewayClass đó.
Gateway — Frontend definition
Gateway là cluster-scoped (có thể thuộc bất kỳ namespace nào). Nó định nghĩa "frontend" của load balancer: IP address, ports, protocols, TLS termination, và ai được phép attach routes.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: external-gateway
namespace: infra
spec:
gatewayClassName: gke-l7-global-external-managed
listeners:
- name: https
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: my-tls-cert
namespace: infra
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: "allowed"
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Same # Chỉ namespace "infra"Listeners — Cổng vào
Mỗi listener trong Gateway tương ứng với một forwarding rule trong GCP. Một Gateway có thể có nhiều listeners với ports khác nhau.
allowedRoutes kiểm soát namespace nào được phép attach HTTPRoutes vào listener này:
from: Same— chỉ cùng namespace với Gatewayfrom: All— tất cả namespacesfrom: Selector— namespaces matching label selector
Đây là cơ chế namespace isolation quan trọng: cluster operator quyết định team nào được routing traffic qua Gateway của mình.
Static IP Address
Mặc định, controller tự assign IP. Để pin một static IP:
metadata:
annotations:
networking.gke.io/static-ip: "my-reserved-ip-name"
# Hoặc cho ephemeral premium tier:
# networking.gke.io/premium-ephemeral-ipv4-address: "true"Static IP tồn tại độc lập với Gateway lifecycle — xóa Gateway không xóa reserved IP.
HTTPRoute — Routing definition
HTTPRoute là namespaced resource, thường được tạo bởi application developer. Nó định nghĩa routing rules: request nào đi đến backend nào.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
namespace: team-a
spec:
parentRefs:
- name: external-gateway
namespace: infra
sectionName: https # Attach vào listener "https"
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /v2
headers:
- name: X-API-Version
value: "2"
backendRefs:
- name: api-v2-service
port: 8080
weight: 100
- matches:
- path:
type: PathPrefix
value: /v2
backendRefs:
- name: api-v2-service
port: 8080
weight: 90
- name: api-v2-canary
port: 8080
weight: 10
- backendRefs:
- name: api-v1-service
port: 8080Matching precedence
HTTPRoute rules được evaluate theo thứ tự trong spec — rule đầu tiên match sẽ được dùng. Nhưng khi nhiều HTTPRoutes từ các namespaces khác nhau đều attach vào cùng một Gateway và có rules conflicting, GKE Gateway controller dùng precedence ordering theo:
- Specificity của hostname match (exact > wildcard)
- Specificity của path match (exact > prefix > regex)
- Specificity của header match (nhiều headers > ít headers)
Nếu vẫn tie, route được tạo trước (theo creation timestamp) sẽ thắng.
Traffic splitting (Canary deployment)
Traffic splitting trong HTTPRoute là một cơ chế native, không cần annotation:
rules:
- backendRefs:
- name: stable-service
port: 8080
weight: 95
- name: canary-service
port: 8080
weight: 5Cơ chế: Controller dịch weight thành tỷ lệ phần trăm traffic cho mỗi backend service trong URL Map. GFE phân phối traffic theo tỷ lệ này dựa trên consistent hashing — không phải per-request round-robin thuần túy.
Điểm quan trọng: weight: 0 không nghĩa là "gửi 0% traffic" theo cách bạn nghĩ. Nó nghĩa backend vẫn tồn tại trong URL Map nhưng không nhận traffic thông thường. Để loại bỏ hoàn toàn, phải xóa backend khỏi backendRefs.
Header matching
matches:
- headers:
- name: "X-Experiment"
value: "new-ui"
type: ExactHeader matching cho phép route specific requests đến specific backends — enabler cho A/B testing theo user segment.
GKE Gateway Controller — Cơ chế hoạt động
Controller là gì
GKE Gateway controller là Google-hosted controller (không chạy trong cluster của bạn, tương tự như GKE Ingress controller). Controller watch Kubernetes API của cluster và provision GCP LB resources tương ứng.
Theo tài liệu GKE: "Google-hosted controllers that watch the Kubernetes API for GKE clusters". Controller không phải networking data plane — nó quản lý load balancers out-of-band.
Có hai loại controller:
- Single-cluster controller: Được enable mặc định khi enable Gateway API feature. Xử lý single-cluster Gateways.
- Multi-cluster controller: Yêu cầu fleet registration. Xử lý Gateways với
-mcsuffix GatewayClasses, provision global LB với backends từ nhiều clusters.
Reconciliation flow
Khi bạn kubectl apply một Gateway:
- Controller nhận Watch event từ Kubernetes API
- Validate spec (GatewayClass tồn tại, listeners hợp lệ, etc.)
- Provision GCP resources theo dependency order:
- Reserve IP address (nếu chưa có)
- Tạo Target HTTPS Proxy (hoặc HTTP)
- Tạo Forwarding Rule
- (Đợi HTTPRoutes được attach)
- Update Gateway
.status.conditionsvới provisioning progress
Khi HTTPRoute được tạo và attach vào Gateway:
- Controller compile tất cả HTTPRoutes attach vào Gateway thành một URL Map
- URL Map được áp vào Target Proxy
- Backend Services được tạo cho mỗi Service reference trong HTTPRoutes
- NEGs được tạo/attach vào Backend Services
Điểm quan trọng: Mỗi khi có HTTPRoute mới attach hoặc thay đổi, controller phải update URL Map — đây là operation trên GCP API, không phải chỉ trên Kubernetes objects.
Policy attachment model
Gateway API sử dụng Policy attachment thay vì CRDs riêng lẻ như BackendConfig/FrontendConfig:
# Tương đương BackendConfig trong Gateway API
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
name: api-backend-policy
namespace: team-a
spec:
targetRef:
group: ""
kind: Service
name: api-service
default:
securityPolicy: "my-cloud-armor-policy"
timeoutSec: 30
connectionDraining:
drainingTimeoutSec: 60
healthCheck:
checkIntervalSec: 15
timeoutSec: 5
healthyThreshold: 1
unhealthyThreshold: 3
type: HTTP
requestPath: /healthz
port: 8080# Tương đương FrontendConfig
apiVersion: networking.gke.io/v1
kind: GCPGatewayPolicy
metadata:
name: gateway-frontend-policy
namespace: infra
spec:
targetRef:
kind: Gateway
name: external-gateway
default:
sslPolicy: "my-ssl-policy"TLS Termination — Ba cách tiếp cận
Cách 1: Kubernetes Secrets
Đơn giản nhất, phù hợp cho một hoặc vài certs:
# Tạo Secret từ cert/key
kubectl create secret tls my-tls-cert \
--cert=tls.crt \
--key=tls.key \
-n infra
# Tham chiếu trong Gateway
spec:
listeners:
- tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: my-tls-certLimitation: Kubernetes Secrets không tự-renew. Cần external tool (cert-manager) để tự động hóa renewal.
Cách 2: Certificate Manager
Certificate Manager là GCP-native service quản lý certificate lifecycle. Đây là cách khuyến nghị cho production:
# Tạo Certificate Manager Certificate
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: my-managed-cert
spec:
domains:
- app.example.com
# Trong Gateway — dùng annotation để reference Certificate Map
metadata:
annotations:
networking.gke.io/certmap: "my-cert-map"Certificate Manager hỗ trợ đến 15+ certificates per Gateway — quan trọng cho multi-tenant Gateways phục vụ nhiều domains. Kubernetes Secret approach bị giới hạn hơn.
Certificate tự động được provision qua Google Trust Services (certs do Google quản lý, renew tự động) hoặc qua CA được import.
Cách 3: Google-managed SSL Certificates (legacy)
Cách cũ hơn, vẫn được hỗ trợ nhưng Certificate Manager là recommended:
metadata:
annotations:
networking.gke.io/managed-certificates: "my-cert"Proxy-only subnet cho regional và internal Gateways
Giống như Internal Ingress, các Gateway sử dụng gke-l7-rilb (Internal) hoặc gke-l7-regional-external-managed (Regional External) đều yêu cầu proxy-only subnet trong VPC:
gcloud compute networks subnets create proxy-only-subnet \
--purpose=REGIONAL_MANAGED_PROXY \
--role=ACTIVE \
--region=us-central1 \
--range=10.129.0.0/23 \
--network=my-vpcGateway controller sẽ fail provision nếu proxy-only subnet không tồn tại. Error sẽ appear trong Gateway .status.conditions.
Giới hạn và constraints của GKE Gateway API
Chỉ hỗ trợ HTTPRoute
Theo tài liệu GKE hiện tại, GKE Gateway chỉ hỗ trợ HTTPRoute. Các route types khác trong Gateway API spec (TCPRoute, UDPRoute, TLSRoute, GRPCRoute) chưa được GKE implement. Nếu cần expose TCP services, vẫn phải dùng Service type: LoadBalancer.
Giới hạn số Gateways
GKE recommend giới hạn số Gateways tối đa là 100 per cluster để tránh controller overload. Mỗi Gateway là một forwarding rule + target proxy trong GCP — GCP quotas cũng áp dụng.
URL Map quota từ nhiều HTTPRoutes
Nhiều HTTPRoutes compile thành một URL Map. GCP URL Maps có quota về số lượng rules. Nếu cluster có nhiều teams, nhiều HTTPRoutes, URL Map rule count có thể hit quota — cần monitor và request quota increase.
Không hỗ trợ path redirect cùng lúc với URL rewrite
HTTPRoute filter hỗ trợ hoặc RequestRedirect (redirect đến URL khác) hoặc URLRewrite (rewrite path trước khi forward), nhưng không thể dùng cả hai trong cùng một rule. Đây là limitation từ GCP URL Map design.
Tính năng advanced cần GKE 1.27+
Custom request/response headers, path manipulation trong HTTPRoute filters chỉ được hỗ trợ từ GKE 1.27+. Cluster cũ hơn sẽ ignore các fields này mà không báo error.
Tại sao Gateway API thay thế Ingress
Nhìn lại, sự chuyển dịch từ Ingress sang Gateway API không chỉ là "API mới". Đây là sự chuyển dịch về operating model:
| Khía cạnh | Ingress | Gateway API |
|---|---|---|
| Ai quản lý routing? | Một người/team quản lý toàn bộ Ingress | Platform team quản lý Gateway, app team quản lý HTTPRoute |
| Feature extensibility | Qua annotations (hacky, implementation-specific) | Qua Policy CRDs (structured, typed) |
| Traffic splitting | Không native (cần annotations của specific controller) | Native (weight trong backendRefs) |
| Header routing | Không native | Native (matches.headers) |
| Multi-namespace isolation | Không (một Ingress cross-namespace qua ExternalName) | Có (allowedRoutes, ReferenceGrant) |
| Portability | Không (annotations thay đổi theo controller) | Có (HTTPRoute spec là Kubernetes standard) |
| Certificate management | Manual hoặc cert-manager | Certificate Manager native integration |
Với các hệ thống mới trên GKE, Gateway API là lựa chọn mặc định. Ingress nên được giữ lại chỉ khi đang vận hành hệ thống legacy có chi phí migration cao.