Bối cảnh: NGINX Ingress Controller sẽ ngừng hỗ trợ (End-of-Life) vào tháng 3/2026. Hướng dẫn này sử dụng Traefik làm Gateway Controller ví dụ để thay thế.
Giai đoạn 1: Khảo sát & Chuẩn bị (Audit)
Trước khi cài đặt cái mới, bạn phải hiểu rõ cái cũ đang chạy như thế nào.
Bước 1: Kiểm tra Ingress Class
Đảm bảo không có Ingress nào bị “mồ côi” (thiếu class). Nếu thiếu, việc cài Gateway API mới có thể gây conflict.
Command:
kubectl get ingress -A -o custom-columns=\ NAMESPACE:.metadata.namespace,\ NAME:.metadata.name,\ CLASS:.spec.ingressClassName
Output mẫu (Bạn sẽ thấy):
NAMESPACE NAME CLASS
default python-route nginx
default go-route nginx
legacy-app old-portal <none> <-- CẢNH BÁO: Cần fix cái này
👉 Hành động: Nếu thấy <none>, hãy thêm ingressClassName: nginx vào YAML của Ingress đó ngay.
Bước 2: Liệt kê các tính năng NGINX đang dùng
Bạn cần biết mình đang phụ thuộc vào annotation nào của NGINX (Rewrite, Auth, SSL Redirect…).
Command:
# Lọc ra tất cả annotation bắt đầu bằng "nginx" kubectl get ingress -A -o json | \ jq -r '.items[].metadata.annotations | keys[]' | \ grep nginx | \ sort -u
Output mẫu:
textnginx.ingress.kubernetes.io/auth-type
nginx.ingress.kubernetes.io/configuration-snippet
nginx.ingress.kubernetes.io/rewrite-target
nginx.ingress.kubernetes.io/ssl-redirect
Bước 3: Tạo bảng quy hoạch Migration
Tạo một báo cáo tổng thể để theo dõi tiến độ.
Command:
# 1. Định nghĩa các cột
audit_fields=(
"NAMESPACE:.metadata.namespace"
"NAME:.metadata.name"
"HOST:.spec.rules[0].host"
"MIGRATED:.metadata.labels.migrated"
"REWRITE:.metadata.annotations.nginx\.ingress\.kubernetes\.io/rewrite-target"
"TLS:.spec.tls[0].secretName"
)
columns=$(IFS=,; echo "${audit_fields[*]}")
# 2. Xuất báo cáo
kubectl get ingress -A -o custom-columns="$columns"
Output mẫu:
textNAMESPACE NAME HOST MIGRATED REWRITE TLS
default python-route example-app.com <none> <none> <none>
default api-rewrite api.example.com <none> /$2 tls-secret
Giai đoạn 2: Cài đặt Hạ tầng Gateway API
Bước 4: Cài đặt CRDs (Core Resources)
Đây là bước bắt buộc để cluster hiểu khái niệm Gateway, HTTPRoute.
Command:
bashkubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
Verify Command:
kubectl get gatewayclass
Output: No resources found (Nhưng không báo lỗi error là thành công).
Bước 5: Cài đặt Gateway Controller (Traefik)
Sử dụng Helm để cài Traefik làm Controller xử lý traffic.
Command:
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik --namespace traefik --create-namespace
Verify Output:
bashkubectl get pods -n traefik
# NAME READY STATUS RESTARTS AGE
# traefik-7d5fc87d6b-x9z2p 1/1 Running 0 45s
Bước 6: Tạo Gateway (Cánh cổng đón traffic)
Tạo file gateway.yaml:
textapiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: traefik
spec:
controllerName: traefik.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: default
spec:
gatewayClassName: traefik
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All # Quan trọng: Cho phép nhận route từ mọi namespace
Apply & Verify:
bashkubectl apply -f gateway.yaml
kubectl get gateway my-gateway
Output mẫu (Quan trọng nhất):
textNAME CLASS ADDRESS PROGRAMMED AGE
my-gateway traefik 203.0.113.88 True 2m
👉 Lưu ý: ADDRESS là IP Public mới. PROGRAMMED=True nghĩa là Gateway đã sẵn sàng.
Giai đoạn 3: Thực hiện Migration (Code Transformation)
Đây là lúc chuyển đổi từ Ingress cũ sang HTTPRoute mới.
Ví dụ 1: Basic Routing (Cơ bản)
Cũ (Ingress):
textkind: Ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /
backend: { service: { name: python-svc, port: { number: 5000 } } }
Mới (HTTPRoute):
textapiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: python-route
spec:
parentRefs:
- name: my-gateway
hostnames:
- example.com
rules:
- backendRefs:
- name: python-svc
port: 5000
Ví dụ 2: Rewrite Path (Nâng cao)
Cũ (Ingress Annotation):
textannotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
paths:
- path: /api/python(/|$)(.*)
Mới (HTTPRoute Filters):
textapiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: rewrite-route
spec:
parentRefs:
- name: my-gateway
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /api/python
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: python-svc
port: 5000
Verify Route sau khi Apply:
bashkubectl get httproute
# NAME HOSTNAMES AGE
# python-route ["example.com"] 10s
Giai đoạn 4: Testing & Cutover
Bước 7: Test song song (Side-by-side)
Sử dụng port-forward để test Gateway mới mà không ảnh hưởng traffic thật.
Cửa sổ terminal 1 (Gateway mới):
bash# Forward port 8080 local vào port 80 của Traefik Gateway
kubectl port-forward -n traefik svc/traefik 8080:80
Cửa sổ terminal 2 (Thực hiện test):
bash# Giả lập request vào Gateway mới
curl -i -H "Host: example.com" http://localhost:8080
Output mong đợi:
textHTTP/1.1 200 OK
Content-Type: application/json
...
{"message": "Success from Gateway API"}
So sánh với hệ thống cũ (đang chạy trên port 80 thật hoặc port-forward khác) để đảm bảo response giống hệt nhau.
Bước 8: Đánh dấu đã xong
Sau khi test OK, đánh dấu vào Ingress cũ để cập nhật bảng theo dõi.
Command:
bashkubectl label ingress python-route migrated=true
Bước 9: Chuyển đổi DNS (Phút sự thật)
- Lấy IP của Gateway mới:
kubectl get gateway my-gateway. - Vào trang quản trị Domain (GoDaddy, Cloudflare, Route53…).
- Sửa bản ghi A (hoặc CNAME) của
example.comtrỏ về IP mới. - Chờ DNS lan truyền (Propagation).
Bước 10: Dọn dẹp (Cleanup)
Sau khi traffic đã ổn định trên hệ thống mới vài ngày:
bash# Xóa Ingress cũ
kubectl delete ingress python-route
# (Cuối cùng) Gỡ NGINX Controller khi đã migrate hết 100%
helm uninstall ingress-nginx -n ingress-nginx
Tóm tắt: Bạn đang xây dựng một hệ thống đường mới song song với đường cũ. Bạn test đường mới bằng xe máy (port-forward) trước, sau đó mới cắm biển chỉ dẫn (DNS) để lùa toàn bộ xe cộ sang đường mới.