

Vào tháng 11/2025, Kubernetes thông báo Ingress-NGINX sẽ chính thức kết thúc vòng đời (End of Life – EOL) vào tháng 3/2026. Đến tháng 1/2026, quyết định này tiếp tục được SIG Network và Steering Committee xác nhận.
Một số nguyên nhân chính dẫn đến quyết định này gồm:
Điều đó có nghĩa là:
Nếu xuất hiện CVE mới, bạn sẽ phải tự chấp nhận rủi ro.

Việc Ingress-NGINX kết thúc vòng đời không có nghĩa các hệ thống đang sử dụng Ingress-NGINX phải chuyển đổi ngay lập tức. Tuy nhiên, với những hệ thống đang vận hành trong môi trường production, đây là thời điểm phù hợp để đánh giá lộ trình migration và chuẩn bị phương án thay thế.
Gateway API đang được Kubernetes định hướng là mô hình API hiện đại hơn cho việc quản lý traffic trong cluster, với khả năng mở rộng và phân tách rõ ràng hơn so với Ingress API truyền thống.
Để hỗ trợ quá trình chuyển đổi, Kubernetes cung cấp Ingress2Gateway – một công cụ giúp phân tích các tài nguyên Ingress hiện tại và chuyển đổi chúng sang các resource tương ứng của Gateway API.
Trong phần tiếp theo, chúng ta sẽ thực hiện migration từ Ingress-NGINX sang Gateway API với Ingress2Gateway 1.0, từ bước kiểm tra cấu hình hiện tại, chuyển đổi manifest cho đến xác minh hệ thống sau migration.
Trước khi bắt đầu quá trình migration từ Ingress-NGINX sang Gateway API, hãy đảm bảo môi trường đã đáp ứng các yêu cầu sau:
Lưu ý: Ingress2Gateway chỉ hỗ trợ chuyển đổi các cấu hình Ingress mà nó có thể ánh xạ sang Gateway API. Các annotation hoặc cấu hình đặc thù của Ingress-NGINX có thể cần được xử lý thủ công sau khi chuyển đổi. Vì vậy, không nên xem migration output là cấu hình production-ready ngay lập tức.
Trước khi thực hiện migration, cần kiểm kê toàn bộ Ingress đang tồn tại trong cluster và xác định các annotation mà Ingress-NGINX đang sử dụng. Đây là bước quan trọng để đánh giá phạm vi migration và phát hiện những cấu hình không thể chuyển đổi tự động.
kubectl get ingress -A \
-o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: {.spec.rules[*].host}{"\n"}{end}'
Kết quả giúp xác định nhanh:
Tiếp theo, liệt kê toàn bộ annotation thuộc nhóm nginx.ingress.kubernetes.io/:
kubectl get ingress -A -o json \
| jq -r '.items[]
| .metadata as $m
| (.metadata.annotations // {})
| to_entries[]
| "\($m.namespace)/\($m.name)\t\(.key)\t\(.value)"' \
| grep '^[^\t]*\tnginx.ingress.kubernetes.io/' \
| sort -k2Thông qua danh sách này, có thể xác định các annotation đang được sử dụng, chẳng hạn như:
Những annotation nguy hiểm cần chú ý
Ví dụ:
configuration-snippet
server-snippet
auth-snippet
auth-url
auth-signin
session-cookie-name
load-balance
upstream-hash-by
mirror-targetNếu cluster của bạn đang dùng những annotation này thì sẽ không thể migration hoàn toàn tự động.
Kết quả kiểm kê sẽ được sử dụng để:
Lưu ý: Không nên chỉ kiểm tra Ingress resource. Các cấu hình liên quan như ConfigMap của Ingress-NGINX, TLS Secret, IngressClass và các resource phụ trợ cũng cần được rà soát trước khi chuyển traffic production.
Gateway API là một API specification, không phải một implementation cụ thể. Vì vậy, sau khi xác định migration từ Ingress-NGINX, bước tiếp theo là lựa chọn một Gateway API controller phù hợp với kiến trúc và nhu cầu vận hành của hệ thống.
Trong bài viết này, chúng ta xem xét bốn lựa chọn phổ biến:
| Controller | Phù hợp nhất khi bạn đã | Điểm cần lưu ý |
|---|---|---|
| Envoy Gateway | Bạn muốn một frontend Envoy gọn nhẹ, tập trung, được CNCF quản lý, không mang theo sự phức tạp của service mesh | Dự án còn khá mới, cộng đồng nhỏ hơn so với Istio |
| kgateway | Bạn đang sử dụng hệ sinh thái Gloo của Solo.io và muốn có sẵn các tính năng định tuyến AI/MCP | Lịch sử cấp phép đã từng thay đổi; hãy xác minh rằng phiên bản mã nguồn mở của kgateway đáp ứng đúng nhu cầu của bạn |
| Cilium Gateway | Bạn đã dùng Cilium làm CNI; việc hợp nhất vào một control plane là lợi thế lớn | Việc định tuyến L7 sẽ gắn chặt với lựa chọn CNI của bạn |
| Istio Gateway | Bạn đã triển khai Istio cho service mesh và muốn tái sử dụng control plane hiện có | Nếu chưa dùng Istio từ trước, việc mang theo toàn bộ control plane của Istio sẽ là một bước triển khai khá nặng |
Sau khi lựa chọn Gateway API controller, bước tiếp theo là sử dụng Ingress2Gateway để phân tích các Ingress hiện tại và tạo ra cấu hình tương ứng cho Gateway API.
Ingress2Gateway hỗ trợ nhiều provider khác nhau. Với cluster đang sử dụng Ingress-NGINX, có thể sử dụng ingress-nginx làm provider và lựa chọn emitter tương ứng với Gateway API controller đã chọn.
Ví dụ với Envoy Gateway:
ingress2gateway print \
--providers=ingress-nginx \
-A \
--emitter envoy-gateway \
> gateway.yaml
Sau khi chạy lệnh, công cụ sẽ phân tích các Ingress, Service và các cấu hình liên quan, sau đó sinh ra các Gateway API resource phù hợp, chẳng hạn:
Các resource được sinh ra phụ thuộc vào cấu hình thực tế của Ingress và những tính năng mà Ingress2Gateway hỗ trợ.
Một số annotation phổ biến của Ingress-NGINX có thể được Ingress2Gateway ánh xạ sang Gateway API, ví dụ:
Đối với những cấu hình được hỗ trợ, Ingress2Gateway sẽ cố gắng chuyển đổi sang các resource hoặc field tương ứng của Gateway API.
Tuy nhiên, “được hỗ trợ” không đồng nghĩa với “chuyển đổi hoàn toàn tương đương về behavior”. Sau khi sinh manifest, vẫn cần review và kiểm thử trước khi đưa vào production.
Một số tính năng có thể được Ingress2Gateway nhận diện nhưng không thể chuyển đổi trực tiếp sang Gateway API.
Ví dụ:
cookie canary
regex header matching
custom headersTrong các trường hợp này, tool có thể đưa ra cảnh báo để người vận hành biết rằng cấu hình tương ứng cần được xử lý thêm.
Một số annotation hoặc tính năng mang tính đặc thù của Ingress-NGINX không có mapping trực tiếp sang Gateway API, chẳng hạn:
configuration-snippet
server-snippet
auth-snippet
auth-url
sticky session
load-balance
mirror-targetCác cấu hình này có thể không được chuyển đổi và trong một số trường hợp không tạo ra resource tương ứng trong output.
Do đó, không nên coi file gateway.yaml được sinh ra là cấu hình hoàn chỉnh để triển khai ngay.
Tùy vào tính năng cụ thể, cần lựa chọn một trong các hướng xử lý:
Quan trọng: Ingress2Gateway là công cụ hỗ trợ migration, không phải một công cụ chuyển đổi 1:1 toàn bộ tính năng của Ingress-NGINX. Sau khi generate manifest, cần review output, xử lý các warning và kiểm thử behavior của từng API trước khi chuyển traffic production.
Sau khi Ingress2Gateway hoàn tất quá trình chuyển đổi, không nên triển khai ngay file gateway.yaml lên production. Output được sinh tự động cần được kiểm tra để đảm bảo các resource đã được tạo đúng, các dependency cần thiết đã đầy đủ và không còn cấu hình nào bị bỏ sót trong quá trình migration. Trước khi apply chính thức, có thể thực hiện validation ở hai mức: kiểm tra nội dung manifest và kiểm tra khả năng Kubernetes API chấp nhận resource.
cat gateway.yamlapiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
annotations:
gateway.networking.k8s.io/generator: ingress2gateway-dev
name: nginx
namespace: cattle-system
spec:
gatewayClassName: nginx
listeners:
- hostname: k8s-b2hopk1i-rancher.vnptplatform.vn
name: k8s-b2hopk1i-rancher-vnptplatform-vn-http
port: 80
protocol: HTTP
- hostname: k8s-b2hopk1i-rancher.vnptplatform.vn
name: k8s-b2hopk1i-rancher-vnptplatform-vn-https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: tls-rancher-ingress---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
annotations:
gateway.networking.k8s.io/generator: ingress2gateway-dev
name: rancher-k8s-b2hopk1i-rancher-vnptplatform-vn-http
namespace: cattle-system
spec:
hostnames:
- k8s-b2hopk1i-rancher.vnptplatform.vn
parentRefs:
- name: nginx
port: 80
rules:
- filters:
- requestRedirect:
scheme: https
statusCode: 301
type: RequestRedirect
matches:
- path:
type: PathPrefix
value: /
status:
parents: null
---kubectl apply -f --dry-run=server gateway.yaml

Nếu bước validation không phát hiện lỗi, có thể triển khai các resource Gateway API vào cluster:
kubectl apply -f gateway.yaml
Sau khi apply, cần kiểm tra lại các resource vừa được tạo để đảm bảo Gateway và HTTPRoute đã được Kubernetes chấp nhận và controller xử lý thành công.
Trước khi chuyển sang bước kiểm thử traffic, hãy xác nhận trạng thái của các resource:
kubectl get gateway -A
kubectl get httproute -A 
Nếu cần kiểm tra chi tiết nguyên nhân khi resource chưa ở trạng thái Ready, sử dụng:
kubectl describe gateway -A
kubectl describe httproute -AĐặc biệt, cần chú ý các trường Status, Conditions và các event liên quan. Chỉ nên tiếp tục sang bước side-by-side testing khi Gateway và các HTTPRoute đã được controller reconcile thành công và có thể nhận request kiểm thử.
Để hạn chế downtime và giảm rủi ro khi migration, không nên thay thế Ingress-NGINX ngay lập tức. Thay vào đó, có thể triển khai Gateway API controller song song với Ingress-NGINX, kiểm thử và chuyển traffic từng bước.
Mô hình này thường được gọi là side-by-side migration.
Luồng migration tổng quát:
┌─── Ingress-NGINX ────┐
Client ── DNS/LB ───┤ ├── Backend
└─── Gateway API ──────┘
│
Test trafficQuy trình đề xuất:
Sau khi Gateway API controller đã chạy và có thể phản hồi các request kiểm thử, chưa nên thay đổi DNS ngay.
Trước tiên, hãy gửi synthetic traffic đến Gateway mới và sử dụng Prometheus để so sánh các chỉ số với baseline của Ingress-NGINX.
Mục tiêu là xác nhận rằng cấu hình được chuyển đổi từ Ingress sang HTTPRoute vẫn giữ được behavior tương đương trước khi đưa traffic production vào Gateway mới.
Một số metrics cơ bản có thể sử dụng để đánh giá Ingress-NGINX:
Request rate theo Ingress:
sum(rate(nginx_ingress_controller_requests[5m])) by (ingress)Tỷ lệ HTTP 5xx theo Ingress:
sum(rate(nginx_ingress_controller_requests{status=~"5.."}[5m])) by (ingress)
sum(rate(nginx_ingress_controller_requests[5m])) by (ingress)P99 request duration theo Ingress:
histogram_quantile(0.99,
sum(rate(nginx_ingress_controller_request_duration_seconds_bucket[5m])) by (le, ingress))Các metrics này tạo thành baseline để so sánh với Gateway API controller mới.
Nếu sử dụng Envoy Gateway, có thể sử dụng các Envoy metrics tương ứng.
Request rate theo upstream cluster:
sum(rate(envoy_cluster_upstream_rq_total[5m])) by (envoy_cluster_name)Tỷ lệ HTTP 5xx theo upstream cluster:
sum(rate(envoy_cluster_upstream_rq_xx{envoy_response_code_class="5"}[5m]))
by (envoy_cluster_name)
sum(rate(envoy_cluster_upstream_rq_total[5m])) by (envoy_cluster_name)P99 upstream request time:
histogram_quantile(0.99,
sum(rate(envoy_cluster_upstream_rq_time_bucket[5m])) by (le, envoy_cluster_name))Lưu ý: Tên metric và label phụ thuộc vào Gateway API controller. Với kgateway, Cilium Gateway API hoặc Istio, cần tham khảo tài liệu metrics của từng controller. Tuy nhiên, cách tiếp cận vẫn tương tự: sử dụng rate() để tính tốc độ, by (...) để phân nhóm và histogram_quantile() để tính percentile.
Các chỉ số thu được từ synthetic traffic trên Gateway mới nên tương đương với baseline của Ingress-NGINX trong phạm vi sai số hợp lý.
Không nhất thiết phải đạt giá trị tuyệt đối giống nhau vì hai controller có thể có cách instrument và tính metrics khác nhau. Điều quan trọng là phải kiểm tra xu hướng và behavior của hệ thống, đặc biệt:
Nếu Gateway API xuất hiện tỷ lệ 5xx cao hơn đáng kể trong khi Ingress-NGINX vẫn hoạt động bình thường, không nên chuyển DNS production.
Trong trường hợp này, cần kiểm tra lại:
Chỉ tiếp tục migration khi behavior của Gateway mới đã được xác nhận.
Khi Gateway API đã vượt qua giai đoạn kiểm thử, có thể bắt đầu chuyển traffic production.
Không nên chuyển thẳng từ 0% → 100%. Thay vào đó, sử dụng weighted DNS hoặc cơ chế traffic splitting tương ứng để tăng dần tỷ lệ traffic:
1% → 5% → 25% → 50% → 100%
Sau mỗi bước, tiếp tục theo dõi các dashboard Prometheus/Grafana và kiểm tra:
Nếu hệ thống ổn định, tiếp tục tăng tỷ lệ traffic.
Nếu xuất hiện bất thường, dừng quá trình migration và rollback về Ingress-NGINX.
Nếu Gateway nằm phía sau CDN, reverse proxy hoặc service mesh có hỗ trợ traffic splitting, có thể sử dụng HTTP header-based routing thay cho weighted DNS.
Cách này có một ưu điểm lớn: rollback nhanh hơn vì không phải chờ DNS cache/TTL hết hiệu lực.
Chỉ thực hiện bước này sau khi 100% traffic đã được chuyển sang Gateway API và hệ thống đã ổn định trong một khoảng thời gian đủ dài.
Thay vì xóa Ingress-NGINX ngay lập tức, nên thực hiện theo hai bước.
Nếu Ingress-NGINX đang sử dụng LoadBalancer Service, có thể chuyển Service về ClusterIP:
kubectl -n ingress-nginx patch svc ingress-nginx-controller \
-p '{"spec":{"type":"ClusterIP"}}'
Thao tác này giúp loại bỏ LoadBalancer nhưng vẫn giữ lại resource để phục vụ rollback nếu cần.
Sau khi xác nhận traffic không còn đi qua Ingress-NGINX:
kubectl scale deploy ingress-nginx-controller --replicas=0
Nên giữ lại các resource và Helm release trong một khoảng thời gian đủ để rollback, thay vì xóa ngay lập tức.
Sau khi hệ thống đã ổn định, có thể xóa Helm release:
helm uninstall ingress-nginx -n ingress-nginx Khuyến nghị: Thời gian giữ lại resource phụ thuộc vào mức độ quan trọng của hệ thống và quy trình vận hành. Với production workload, nên xác định rõ rollback window trước khi thực hiện migration.
Một trong những ưu điểm lớn nhất của side-by-side migration là rollback tương đối đơn giản.
Nếu Gateway API gặp vấn đề sau khi chuyển traffic, có thể đưa traffic quay lại Ingress-NGINX bằng cách điều chỉnh weighted DNS hoặc traffic routing về controller cũ.
Ví dụ:

Không cần phải:
Sau khi thay đổi routing, traffic sẽ quay trở lại Ingress-NGINX theo cơ chế của DNS hoặc traffic management đang sử dụng.
Lưu ý: Nếu rollback thông qua DNS, thời gian traffic quay lại controller cũ phụ thuộc vào TTL, caching của resolver và các lớp DNS/CDN trung gian. Nếu yêu cầu rollback gần như tức thời, nên cân nhắc sử dụng HTTP-based traffic shifting hoặc một lớp traffic management có khả năng chuyển traffic trực tiếp.
Việc Ingress-NGINX kết thúc vòng đời không chỉ là câu chuyện thay thế một Ingress Controller, mà còn là cơ hội để các hệ thống Kubernetes chuyển sang một mô hình quản lý traffic hiện đại và linh hoạt hơn với Gateway API.
Quá trình migration không nhất thiết phải thực hiện theo kiểu “big bang”. Với Ingress2Gateway, phần lớn cấu hình Ingress có thể được phân tích và chuyển đổi sang các resource của Gateway API, giúp giảm đáng kể công sức migration. Tuy nhiên, các annotation và tính năng đặc thù của Ingress-NGINX vẫn cần được rà soát, xử lý thủ công và kiểm thử behavior trước khi đưa vào production.
Một chiến lược an toàn là thực hiện side-by-side migration:
Inventory
↓
Chọn Gateway API Controller
↓
Ingress2Gateway
↓
Review & xử lý cấu hình chưa được hỗ trợ
↓
Deploy Gateway API song song
↓
Synthetic Testing
↓
So sánh Metrics / SLO
↓
Traffic shifting
↓
100% Traffic → Gateway API
↓
Giữ Ingress-NGINX cho Rollback Window
↓
Decommission Ingress-NGINXCách tiếp cận này cho phép tổ chức giảm thiểu downtime, kiểm soát rủi ro và duy trì khả năng rollback trong toàn bộ quá trình chuyển đổi.
Quan trọng hơn, migration nên được xem là một quá trình đánh giá và chuyển đổi kiến trúc, không đơn thuần là chuyển đổi YAML. Việc lựa chọn Gateway API controller, mapping các annotation, kiểm thử traffic, quan sát metrics và xác định chiến lược rollback đều cần được thực hiện dựa trên workload và yêu cầu vận hành thực tế.
Với các hệ thống Kubernetes đang sử dụng Ingress-NGINX, đây là thời điểm phù hợp để bắt đầu inventory, đánh giá mức độ tương thích và xây dựng migration plan, thay vì chờ đến khi cần thay thế gấp trong production.
