In January 2026, the Kubernetes Steering and Security Response Committees issued a critical warning: Ingress NGINX will cease receiving security patches from March 2026. With approximately 50% of cloud-native environments relying on this controller, this deprecation represents one of the most significant infrastructure migrations in Kubernetes history. This comprehensive guide provides a step-by-step migration path from Ingress NGINX to the Kubernetes Gateway API, including traffic management patterns, TLS configuration, and enterprise deployment strategies.
Ingress NGINX will stop receiving security patches in March 2026. Any vulnerabilities discovered after this date will remain unpatched. Begin migration immediately to avoid exposure to zero-day exploits.
Understanding the Deprecation Timeline
The Ingress NGINX project has been in maintenance mode since late 2024, with the Kubernetes community focusing resources on the Gateway API as the future standard for ingress traffic management. The deprecation follows a clear timeline:
| Date | Milestone | Action Required |
|---|---|---|
| January 2026 | Official deprecation announcement | Begin migration planning |
| March 2026 | Security patches cease | Complete migration or accept risk |
| June 2026 | Repository archived | No further updates of any kind |
Why Gateway API is the Future
The Kubernetes Gateway API is not merely a replacement for Ingress—it’s a complete rethinking of how traffic enters and routes through Kubernetes clusters. Key advantages include:
Role-Based Resource Model
Gateway API separates concerns across three personas:
graph TB
subgraph InfraTeam ["Infrastructure Team"]
GC[GatewayClass]
end
subgraph PlatformTeam ["Platform Team"]
GW[Gateway]
end
subgraph AppTeam ["Application Team"]
HR[HTTPRoute]
GR[GRPCRoute]
TR[TCPRoute]
end
GC --> GW
GW --> HR
GW --> GR
GW --> TR
style GC fill:#E3F2FD,stroke:#1565C0
style GW fill:#E8F5E9,stroke:#2E7D32
style HR fill:#FFF3E0,stroke:#EF6C00
style GR fill:#FFF3E0,stroke:#EF6C00
style TR fill:#FFF3E0,stroke:#EF6C00
- GatewayClass (Infrastructure): Defines which controller handles traffic (e.g., Envoy, Cilium, NGINX Gateway Fabric)
- Gateway (Platform): Configures listeners, TLS certificates, and allowed route types
- HTTPRoute/GRPCRoute (Application): Defines routing rules, path matching, and backend services
Feature Comparison
| Feature | Ingress | Gateway API |
|---|---|---|
| Header-based routing | Annotations (non-standard) | Native support |
| Traffic splitting | Not supported | Native weights |
| Cross-namespace routing | Complex workarounds | ReferenceGrant |
| gRPC routing | Annotations | Native GRPCRoute |
| TCP/UDP routing | Separate CRDs | Native TCPRoute/UDPRoute |
| Request/response modification | Annotations | Native filters |
Choosing a Gateway API Implementation
Unlike Ingress (where NGINX dominated), Gateway API has multiple mature implementations. Each has distinct strengths:
| Implementation | Best For | Key Features |
|---|---|---|
| Envoy Gateway | General purpose, familiar to Istio users | Full Gateway API conformance, extensible via EnvoyPatchPolicy |
| Cilium Gateway | eBPF-native networking, high performance | Kernel-level routing, no sidecar required |
| NGINX Gateway Fabric | Teams with NGINX expertise | Familiar configuration model, commercial support |
| Traefik | Developer-friendly, Let’s Encrypt integration | Dashboard, automatic TLS, middleware |
| Kong Gateway | API management integration | Plugin ecosystem, rate limiting, auth |
For most enterprises migrating from Ingress NGINX, we recommend Envoy Gateway due to its full Gateway API conformance and extensibility, or NGINX Gateway Fabric if your team has deep NGINX operational expertise.
Step-by-Step Migration Guide
Step 1: Install Gateway API CRDs
Gateway API resources are not installed by default. Install the standard channel CRDs:
# Install Gateway API v1.2 CRDs (January 2026 stable)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
# Verify installation
kubectl get crd | grep gateway
# Expected output:
# gatewayclasses.gateway.networking.k8s.io
# gateways.gateway.networking.k8s.io
# httproutes.gateway.networking.k8s.io
# referencegrants.gateway.networking.k8s.io
Step 2: Deploy a Gateway Controller
Example using Envoy Gateway:
# Install Envoy Gateway via Helm
helm install envoy-gateway oci://docker.io/envoyproxy/gateway-helm --version v1.2.0 --namespace envoy-gateway-system --create-namespace
# Verify the GatewayClass is available
kubectl get gatewayclass
# NAME CONTROLLER ACCEPTED
# envoy-gateway gateway.envoyproxy.io/gateway True
Step 3: Create a Gateway Resource
The Gateway defines listeners (ports, protocols, TLS) and replaces the ingress controller’s global configuration:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
namespace: gateway-system
spec:
gatewayClassName: envoy-gateway
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: wildcard-tls
namespace: gateway-system
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: "true"
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
Step 4: Migrate Ingress Rules to HTTPRoute
Here’s a side-by-side comparison of Ingress vs HTTPRoute:
# BEFORE: Ingress NGINX
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: api-tls
rules:
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 80
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 80
# AFTER: Gateway API HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-routes
namespace: api-namespace
spec:
parentRefs:
- name: production-gateway
namespace: gateway-system
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /v1
backendRefs:
- name: api-v1
port: 80
- matches:
- path:
type: PathPrefix
value: /v2
backendRefs:
- name: api-v2
port: 80
Step 5: Implement Traffic Splitting (Canary Deployments)
One of Gateway API’s killer features is native traffic splitting:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-deployment
spec:
parentRefs:
- name: production-gateway
namespace: gateway-system
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: app-stable
port: 80
weight: 90 # 90% to stable
- name: app-canary
port: 80
weight: 10 # 10% to canary
Step 6: Cross-Namespace Routing with ReferenceGrant
To allow routes in one namespace to reference services in another:
# In the target namespace (backend-services)
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-gateway-routes
namespace: backend-services
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: frontend-apps
to:
- group: ""
kind: Service
Migration Architecture Pattern
For zero-downtime migration, run both controllers in parallel during the transition:
graph LR
subgraph External ["External Traffic"]
LB["Cloud Load Balancer"]
end
subgraph Cluster ["Kubernetes Cluster"]
NGINX["Ingress NGINX (Legacy)"]
GW["Gateway API (New)"]
SVC1["Service A"]
SVC2["Service B"]
SVC3["Service C"]
end
LB --> NGINX
LB --> GW
NGINX --> SVC1
NGINX --> SVC2
GW --> SVC2
GW --> SVC3
style NGINX fill:#FFCDD2,stroke:#C62828
style GW fill:#C8E6C9,stroke:#2E7D32
Migration phases:
- Phase 1: Deploy Gateway API controller alongside Ingress NGINX
- Phase 2: Migrate low-risk services to HTTPRoute (both controllers serve traffic)
- Phase 3: Migrate remaining services, validate with synthetic traffic
- Phase 4: Update DNS/Load Balancer to point only to Gateway
- Phase 5: Decommission Ingress NGINX controller
Common Migration Challenges
Challenge 1: Annotation-Heavy Configurations
Ingress NGINX uses annotations for features like rate limiting, CORS, and authentication. Gateway API uses Filters and Policies:
# Request header modification (replaces rewrite annotations)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
spec:
rules:
- matches:
- path:
type: PathPrefix
value: /legacy
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /api
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Forwarded-Prefix
value: /legacy
backendRefs:
- name: api-service
port: 80
Challenge 2: Custom Error Pages
Use the controller’s extension mechanisms. For Envoy Gateway:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: custom-error-responses
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: api-routes
responseOverride:
rules:
- match:
statusCodes:
- value: 503
response:
contentType: application/json
body:
type: Inline
inline: '{"error": "Service temporarily unavailable"}'
Validation and Testing
# Validate HTTPRoute status
kubectl get httproute api-routes -o jsonpath='{.status.parents[*].conditions}'
# Test with curl through the new gateway
curl -H "Host: api.example.com" http://GATEWAY_IP/v1/health
# Compare responses between old and new paths
diff <(curl -s http://OLD_NGINX_IP/v1/users) <(curl -s http://GATEWAY_IP/v1/users)
Key Takeaways
- Ingress NGINX security patches end March 2026—migration is not optional for security-conscious organizations.
- Gateway API is the Kubernetes-native replacement with superior features: traffic splitting, cross-namespace routing, and role-based resource ownership.
- Run controllers in parallel during migration to enable gradual, zero-downtime cutover.
- Choose your implementation based on team expertise: Envoy Gateway for flexibility, NGINX Gateway Fabric for familiarity.
- Plan for annotation translation—most Ingress NGINX annotations have Gateway API equivalents via Filters or controller-specific policies.
Conclusion
The deprecation of Ingress NGINX marks the end of an era, but Gateway API represents a significant improvement in how Kubernetes handles ingress traffic. Its role-based model, native traffic management features, and growing ecosystem make it the clear path forward. Start your migration now—waiting until March puts your infrastructure at risk of unpatched vulnerabilities. Use the parallel-running strategy outlined in this guide to minimize disruption and validate thoroughly before final cutover.
References
- Kubernetes Blog: Ingress NGINX Deprecation Announcement
- Gateway API Official Documentation
- Envoy Gateway Documentation
- NGINX Gateway Fabric GitHub
- Gateway API Implementations Comparison
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.