Migrating from Ingress-NGINX to Kubernetes Gateway API: A Production Migration Guide

Why Platform Teams Are Moving Beyond Ingress-NGINX

For nearly a decade, the Kubernetes ingress-nginx controller served as the de facto edge routing mechanism for cloud-native workloads. However, the legacy Ingress specification suffers from a fundamental architectural limitation: it is monolithic. In a standard Ingress manifest, edge infrastructure configuration (load balancer provisioning, TLS termination) is coupled directly with application routing rules in a single namespaced resource.

To overcome these constraints, teams turned to proprietary annotations (such as nginx.ingress.kubernetes.io/*) and arbitrary configuration snippets. Over time, this introduced severe annotation sprawl, fragmented routing logic, and brittle configurations that resisted standard validation. With community maintainers signaling long-term retirement and deprecation milestones for legacy controllers, migrating to the official Kubernetes Gateway API has transitioned from an optional modernization exercise to an urgent infrastructure requirement.

The Gateway API Architectural Model: Separation of Concerns

Maintained by Kubernetes SIG Network, the Gateway API replaces monolithic Ingress with an expressive, role-oriented hierarchy. By establishing clean boundaries across organizational personas, Gateway API enhances security and RBAC governance:

  • GatewayClass (Infrastructure Provider): A cluster-scoped resource defining the underlying gateway controller implementation (such as Envoy Gateway, NGINX Gateway Fabric, or cloud managed controllers).
  • Gateway (Platform / Cluster Operator): Defines the network entry points, listening ports (80, 443), TLS termination modes, and namespace attachment constraints (allowedRoutes).
  • HTTPRoute (Application Developer): Namespaced routing declarations that specify path matching, header routing, URL rewriting, and backend Service targets, binding to parent Gateways via parentRefs.
  • ReferenceGrant (Cross-Namespace Security): Enables explicit, audited cross-namespace references (for example, allowing an edge Gateway in gateway-system to bind to an application Service or TLS Secret in a separate tenant namespace).
Gateway API Resource HierarchyGatewayClassInfrastructure Provider · Cluster-ScopedGatewayPlatform Operator · Ports 80, 443 · TLS TerminationHTTPRoute (Team A)ns: app-a · /api/*HTTPRoute (Team B)ns: app-b · /web/*HTTPRoute (Team C)ns: app-c · /admin/*Service AService BService CReferenceGrant — Cross-Namespace Security

Figure 1: Gateway API separates infrastructure (GatewayClass), platform (Gateway), and application (HTTPRoute) concerns across organizational roles.

Automated Manifest Translation with ingress2gateway

Rather than hand-authoring hundreds of route manifests, platform engineers can leverage ingress2gateway, an open-source CLI developed under Kubernetes SIG Network. Built on a provider/emitter architecture, it translates Ingress declarations into standard Gateway API equivalents while highlighting unconvertible annotations for manual review.

Installation and CLI Usage

# Install via Go or package manager
go install github.com/kubernetes-sigs/ingress2gateway@latest

# Translate a single manifest
ingress2gateway print --providers=ingress-nginx --input-file=ingress.yaml > gateway-manifests.yaml

# Translate all Ingress resources in a live production namespace
ingress2gateway print --providers=ingress-nginx --namespace=production > production-routes.yaml

# Full cluster audit and extraction
ingress2gateway print --providers=ingress-nginx --all-namespaces > cluster-gateway-routes.yaml

The utility automatically maps common annotations to native typed Gateway API filters:

  • nginx.ingress.kubernetes.io/rewrite-target maps natively to the URLRewrite filter.
  • nginx.ingress.kubernetes.io/ssl-redirect maps natively to the RequestRedirect filter on port 80.
  • Header injections map directly to RequestHeaderModifier filters.

Topology Planning: Shared Gateway vs. Dedicated Gateways

When architecting your Gateway API deployment, selecting the right topology is critical to cloud cost management. As highlighted in production migrations by the Cloud Native Computing Foundation (CNCF), deploying an individual Gateway resource per microservice triggers the provisioning of independent cloud LoadBalancers (e.g., AWS NLB or GCP Forwarding Rules), rapidly escalating cloud infrastructure bills.

For most enterprise workloads, a Single Shared Gateway pattern is recommended. A centralized Gateway resource in a dedicated namespace (e.g., gateway-system) manages the external IP and wild-card TLS termination, while individual tenant teams manage isolated HTTPRoute manifests in their respective namespaces.

Example: Production Shared Gateway Manifest

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shared-edge-gateway
  namespace: gateway-system
spec:
  gatewayClassName: nginx
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
  - name: https
    port: 443
    protocol: HTTPS
    tls:
      mode: Terminate
      certificateRefs:
      - name: wildcard-tls-cert
    allowedRoutes:
      namespaces:
        from: All

Example: Application HTTPRoute with Header Filters

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: orders-service-route
  namespace: e-commerce
spec:
  parentRefs:
  - name: shared-edge-gateway
    namespace: gateway-system
  hostnames:
  - "api.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /orders
    filters:
    - type: RequestHeaderModifier
      requestHeaderModifier:
        set:
        - name: X-Forwarded-Gateway
          value: Gateway-API-Production
    backendRefs:
    - name: orders-service
      port: 8080
      weight: 100

Zero-Downtime Validation and Cutover Strategy

Migrating production ingress requires an airtight, zero-downtime execution strategy. The recommended operational workflow follows a parallel dual-stack deployment:

  1. Deploy the New Controller: Install the target Gateway API controller (such as NGINX Gateway Fabric or Envoy Gateway) alongside the existing ingress-nginx installation.
  2. Pre-Cutover Route Verification: Before altering DNS records, validate routing, TLS termination, and header filters by issuing HTTP requests directly against the new Gateway LoadBalancer IP using curl --resolve:
    curl -iv --resolve api.example.com:443:<GATEWAY_LB_IP> https://api.example.com/orders/health
  3. Weighted Canary DNS Shift: Utilize Route53 or Cloudflare weighted DNS records to shift 5% of incoming traffic to the Gateway API endpoint. Monitor latency metrics, 5xx error spikes, and access logs.
  4. Full Cutover & Decommissioning: Once the traffic shift reaches 100% and DNS TTLs elapse, safely delete legacy Ingress resources and uninstall the obsolete ingress-nginx Helm chart.

Verified References & Further Reading

Leave a Comment