From NGINX Ingress to the Future: Our Journey Migrating to Kubernetes Gateway API

From NGINX Ingress to the Future: Our Journey Migrating to Kubernetes Gateway API

The wake-up call came without warning. The NGINX Ingress Controller, a cornerstone of countless Kubernetes deployments, was officially retired. For teams running production workloads, this wasn’t just another deprecation notice. It was time to evolve.

Here’s how we successfully migrated NGINX Ingress to the next-generation Kubernetes Gateway API, and why it transformed our entire approach to traffic management.

Why We Couldn’t Ignore This Migration

Migrations are painful. They consume time, introduce risk, and rarely spark joy. So why did we embrace this one?

Three compelling reasons:

  1. NGINX Ingress retirement meant no more security patches or feature updates
  2. Gateway API represents the future of Kubernetes traffic management with official support and a unified standard
  3. Modern gateway implementations unlock enterprise-grade features we were already planning to adopt

This wasn’t just about replacing deprecated technology. It was an opportunity to modernize our entire traffic management strategy.

The Old World: NGINX Ingress Controller

Our setup was straightforward. NGINX Ingress handled all external traffic routing with simple Ingress resources scattered across namespaces. It worked reliably, but it had limitations that became increasingly apparent as our infrastructure grew.

The pain points we lived with included basic traffic splitting, limited protocol support beyond HTTP/HTTPS, configuration sprawl across annotations, and no native service mesh integration.

The New Paradigm: Kubernetes Gateway API

The Kubernetes Gateway API is a collection of API resources for service networking in Kubernetes, designed as a more expressive and extensible successor to Ingress. It consists of GatewayClass, Gateway and various Route types (HTTPRoute, TLSRoute, TCPRoute, etc.) that map requests to Services. It improves on Ingress with better role separation, advanced routing features like traffic splitting and header-based routing, cross-namespace support, and portability across implementations

Choosing Your Gateway Implementation

One of Gateway controllers  strengths is choice. You’re not locked into a single implementation. We evaluated several options before making our decision:

Istio offers full service mesh capabilities with advanced traffic management, mutual TLS by default, and rich observability features. It’s powerful but comes with operational complexity.

Envoy Gateway provides a lightweight, focused gateway built on the proven Envoy proxy. It offers excellent performance and is simpler to operate than a full service mesh.

Traefik Proxy is a modern, cloud-native reverse proxy and load balancer that supports the Kubernetes Gateway API along with automatic service discovery, dynamic configuration, and built-in support for multiple protocols and backends

Kong Gateway combines API gateway features with ingress capabilities, perfect for teams already using Kong or needing API management features.

NGINX Gateway Fabric is an open-source implementation of the Kubernetes Gateway API built on NGINX, providing a lightweight and performant ingress solution with native Gateway API support

We ultimately chose a gateway controller as Istio that balanced our needs for advanced traffic management with operational simplicity.

Our Migration Journey

Phase 1: Foundation
We started by installing Istio on our kubeadm cluster and enabling Gateway API CRDs. The process was surprisingly streamlined compared to earlier generations of these tools.
1. Installing Istio by Helm chart (Link)
2.Install the Kubernetes Gateway API CRDs (Link). This way Kubernetes understands the Gateway API custom objects and Istio can watch for those Gateway API objects and act on them

Phase 2: Understanding the Model
The Gateway API’s separation took a moment to appreciate. Instead of monolithic Ingress resources mixing infrastructure and routing, we now had distinct layers. The Gateway defined infrastructure load balancers, ports, protocols. HTTPRoutes defines routing rule hosts, paths, and services. 

Phase 3: Migration Strategy
We started with non-critical development services, ran both systems in parallel for selected workloads,
gradually migrated development environments, and finally cut over production services one namespace at a time. At each step, we validated traffic flow, performance, and monitoring.

Phase 4: Route Transformation
Converting NGINX Ingress resources to HTTPRoutes was surprisingly straightforward. Each HTTPRoute referenced our central Gateway, specified hostnames, and defined routing rules with clear match conditions.


Sample Routing rule with Gateway creation


apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: route
  namespace: app1
spec:
  parentRefs:
    – name: gateway
      namespace: app1
  hostnames:
    – test.com
  rules:
    – matches:
        – path:
            type: PathPrefix
            value: “/”
      backendRefs:
        – name: app-service
          port: 5000

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway
  namespace: app1
spec:
  gatewayClassName: istio
  listeners:
    – name: https
      protocol: HTTPS
      port: 443
      hostname: example.com
      allowedRoutes:
        namespaces:
          from: All
   
    – name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: All

apiVersion: v1
kind: Service
metadata:
  name: gateway-istio
  namespace: app1
spec:
  type: NodePort
  selector:
    gateway.networking.k8s.io/gateway-name: gateway
  ports:
    – name: status-port
      port: 15021
      targetPort: 15021
      protocol: TCP
      nodePort: 31394
    – name: http
      port: 80
      targetPort: 80
      protocol: TCP
      nodePort: 32608
    – name: https
      port: 443
      targetPort: 443
      protocol: TCP
      nodePort: 32444

Our Migration Blueprint

Istio has historically offered its own Gateway and VirtualService APIs for this purpose; it now supports the newer, more standardized Kubernetes Gateway API. This API is slated to become the default for managing ingress and egress traffic in Istio clusters.

In my implementation, I have specifically configured a Gateway resource using istio as the gateway class, and I defined the routing rules for incoming traffic using only the HTTPRoute resource.

The image below shows the high-level architecture of what we are going to build.

CONCLUSION

Migrating from NGINX Ingress to the Kubernetes Gateway API with Istio represents a strategic evolution in traffic management, not just a technical upgrade. The Gateway API’s standardized approach delivers enhanced routing flexibility, better role separation, and advanced features like traffic splitting and header-based routing. While the migration required careful planning through phased implementation, the long-term benefits of adopting this modern standard far outweigh the initial effort. As the Gateway API becomes the default for Kubernetes traffic management, early adoption positions teams to leverage future innovations in cloud-native networking.

 

Leave a Reply

Your email address will not be published. Required fields are marked *