Sau bài này bạn làm được: cấu hình Ingress route HTTP theo host/path; hiểu Gateway API và khi nào chuyển từ Ingress sang; cấu hình TLS với cert-manager.
Vấn đề: expose nhiều service qua 1 IP
LoadBalancer Service tạo 1 LB per service → 10 service = 10 LB = 10 IP = 10× chi phí.
Ingress (và Gateway API) cho phép 1 LB route traffic tới nhiều service dựa trên host và path.
[Internet]
│
▼
[Cloud LB] ← 1 IP, 1 LB
│
▼
[Ingress Controller (nginx/traefik)]
│
├── Host: api.example.com → Service: my-api
├── Host: web.example.com → Service: my-web
└── Path: /admin → Service: admin-panel
Ingress
Ingress resource vs Ingress controller
- Ingress resource: YAML bạn viết, khai báo routing rules.
- Ingress controller: pod thực sự xử lý traffic (nginx, traefik, HAProxy, AWS ALB…). Phải cài riêng — Kubernetes không có sẵn.
Ingress spec cơ bản
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx # Chỉ định controller
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-api
port:
number: 80
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-web
port:
number: 80
pathType
| Type | Hành vi |
|---|---|
Prefix | Match prefix: /api match /api, /api/users, /api/ |
Exact | Match chính xác: /api chỉ match /api |
ImplementationSpecific | Tuỳ controller |
TLS termination
spec:
tls:
- hosts:
- api.example.com
secretName: api-tls-cert # Secret chứa cert + key
rules:
- host: api.example.com
# ...
Cert lưu trong Secret type kubernetes.io/tls:
kubectl create secret tls api-tls-cert \
--cert=tls.crt --key=tls.key
Tự động với cert-manager: chi tiết → Mạng bài 13 — TLS tự động với cert-manager.
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- api.example.com
secretName: api-tls-cert # cert-manager tự tạo + renew
Annotations phổ biến (nginx-ingress)
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
nginx.ingress.kubernetes.io/rate-limit-rps: "10"
Vấn đề: annotations là controller-specific, không portable. Đây là lý do Gateway API ra đời.
Gateway API (GA v1.0+)
Gateway API là tiêu chuẩn mới thay thế Ingress, giải quyết các giới hạn:
- Annotations không portable → typed config trong spec.
- Ingress chỉ hỗ trợ HTTP → Gateway API hỗ trợ TCP, UDP, gRPC, TLS passthrough.
- Không phân quyền rõ → Gateway API tách role: infra admin vs app developer.
Kiến trúc 3 tầng
┌──────────────────────────────────┐
│ GatewayClass (infra provider) │ ← Ai cung cấp LB (nginx, Cilium, AWS...)
└──────────────────────────────────┘
│
┌──────────────────────────────────┐
│ Gateway (platform team) │ ← Listener: port, protocol, hostname, TLS
└──────────────────────────────────┘
│
┌──────────────────────────────────┐
│ HTTPRoute (app team) │ ← Path/header routing, backend refs
└──────────────────────────────────┘
GatewayClass
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx
spec:
controllerName: k8s.nginx.org/nginx-gateway-controller
Tương tự IngressClass. Thường do infra team hoặc addon cài sẵn.
Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: main-gateway
namespace: infra
spec:
gatewayClassName: nginx
listeners:
- name: https
port: 443
protocol: HTTPS
hostname: "*.example.com"
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: wildcard-cert
allowedRoutes:
namespaces:
from: All # Cho phép HTTPRoute từ mọi namespace
HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
namespace: default # App team namespace
spec:
parentRefs:
- name: main-gateway
namespace: infra
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /v1
backendRefs:
- name: my-api-v1
port: 80
- matches:
- path:
type: PathPrefix
value: /v2
backendRefs:
- name: my-api-v2
port: 80
Traffic splitting (canary)
rules:
- backendRefs:
- name: my-api-v1
port: 80
weight: 90 # 90% traffic
- name: my-api-v2
port: 80
weight: 10 # 10% canary
Header-based routing
rules:
- matches:
- headers:
- name: X-Canary
value: "true"
backendRefs:
- name: my-api-v2
port: 80
Hai tính năng trên trong Ingress đòi hỏi annotations riêng biệt theo controller — Gateway API có sẵn trong spec.
Ingress vs Gateway API
| Khía cạnh | Ingress | Gateway API |
|---|---|---|
| Status | Stable, widely deployed | GA v1.0 (2023), adoption tăng |
| Config | annotations (non-portable) | Typed spec (portable) |
| Protocol | HTTP/HTTPS only | HTTP, TCP, UDP, gRPC, TLS |
| Role separation | Không | GatewayClass (infra) → Gateway (platform) → Route (app) |
| Traffic splitting | Annotation-dependent | Native weight |
| Header routing | Annotation-dependent | Native matches.headers |
Khi nào chọn cái nào
- Ingress: cluster đã có, team quen, không cần tính năng nâng cao → giữ nguyên.
- Gateway API: project mới, cần traffic splitting/header routing, multi-team cluster (cần role separation), hoặc non-HTTP protocol.
- Migration: có thể chạy song song — Ingress và Gateway API trên cùng controller (nginx, Cilium hỗ trợ cả hai).
Debug Ingress/Gateway
# Ingress controller logs
kubectl -n ingress-nginx logs -l app.kubernetes.io/name=ingress-nginx
# Ingress status (address?)
kubectl get ingress my-ingress
# NAME CLASS HOSTS ADDRESS PORTS AGE
# my-ingress nginx api.example.com 203.0.113.10 80,443 5m
# Nếu ADDRESS trống: controller chưa cài, hoặc LB chưa provision
# Gateway status
kubectl get gateway main-gateway
kubectl describe gateway main-gateway # Xem conditions
# HTTPRoute status
kubectl describe httproute api-route # Xem parentRef accepted?
Checklist khi traffic không vào
- DNS trỏ tới đúng IP (Ingress ADDRESS hoặc Gateway external IP)?
- Ingress controller/Gateway pod đang chạy?
- Service backend có endpoints? (
kubectl get endpoints) - TLS cert valid? (
curl -v https://...kiểm tra cert chain) - Path/host match đúng?
- NetworkPolicy có chặn traffic từ controller tới pod không? (bài 10)
Tóm tắt
- Ingress: 1 LB cho nhiều service, route theo host/path. Cần cài controller riêng.
- Gateway API: tiêu chuẩn mới, typed config, hỗ trợ traffic splitting/header routing native, phân quyền rõ ràng.
- TLS: dùng cert-manager tự động renew. Secret type
kubernetes.io/tls. - Chạy song song Ingress + Gateway API khi migration.
Câu hỏi hay gặp
Ingress controller cài ở đâu? Có sẵn trong K8s không?
Trả lời: Không có sẵn. Bạn phải cài riêng: helm install ingress-nginx ingress-nginx/ingress-nginx hoặc tương đương. Trên managed K8s (EKS, GKE, AKS), cloud thường có addon hoặc controller riêng.
Gateway API có thay thế Ingress hoàn toàn không?
Trả lời: Về lâu dài, có. Nhưng hiện tại (2026) Ingress vẫn stable và không bị deprecated. Migration không bắt buộc. Kubernetes SIG Network khuyến khích project mới dùng Gateway API.
Nhiều Ingress resource cùng host có conflict không?
Trả lời: Tuỳ controller. Nginx-ingress merge rules cùng host. Nếu path overlap → rule đầu tiên (theo creation time) thắng. Gateway API xử lý rõ ràng hơn: HTTPRoute có sectionName chỉ định listener cụ thể.
Bài tiếp theo (Giai đoạn III): Network Policy — kiểm soát traffic — ai được nói chuyện với ai trong cluster.