Step-by-Step Guide: Moving From Ingress-Nginx to Envoy Gateway

This blog guides users through migrating from ingress-nginx to Envoy Gateway using the Gateway API. It covers the reasons for migration, step-by-step instructions on Minikube, and how the ingress2gateway tool simplifies the transition to a more modern ingress architecture.

Click to show the outline

This blog aims to help users currently relying on ingress-nginx to adopt Envoy Gateway and the Gateway API. We’ll walk through the motivation for migration, provide a hands-on Minikube-based demo, and showcase how tools like ingress2gateway simplify the transition.

Why Migrate?

Ingress controllers are foundational to Kubernetes networking, and many teams initially adopt ingress-nginx because it’s widely available and easy to get started with. However, as production requirements grow, the limitations of the traditional Ingress API and nginx controller become more apparent, from confusing annotation-based configurations to traffic disruptions during updates. More critically, recent security issues such as CVE-2025-1974 have highlighted the risks of continuing to rely on ingress-nginx. The maintainers have also announced that ingress-nginx will enter maintenance mode in 18 months, making it essential to explore modern, extensible alternatives like Envoy Gateway, which offers native support for the Kubernetes Gateway API, better observability, and robust extensibility.

Enter Envoy Gateway and the Gateway API

Envoy Proxy is a modern, cloud-native proxy, designed for observability, hot-reload, and extensibility. Envoy Gateway (EG) builds on Envoy to offer a powerful ingress solution using the new Kubernetes Gateway API.

Unlike the legacy Ingress API, the Gateway API provides typed resources like Gateway, HTTPRoute, and GatewayClass, enabling structured, annotation-free configuration. EG supports features such as:

These capabilities often eliminate the need for separate API Gateway products. EG is fully open source and governed under the CNCF.

Migration Workflow: From nginx to Envoy Gateway

Before diving into the hands-on migration steps, it’s important to understand how the ingress2gateway tool works. This CLI utility scans existing Kubernetes Ingress resources—specifically those configured for controllers like ingress-nginx—and converts them into Gateway API resources, namely Gateway and HTTPRoute. While it does not generate the GatewayClass, it expects one to be pre-created and referenced. This makes it easier for users to incrementally adopt the Gateway API and modern ingress controllers such as Envoy Gateway, without rewriting everything from scratch.

image
Migrating from ingress-nginx to Envoy Gateway workflow

We’ll walk through a practical migration using Minikube on macOS, starting with ingress-nginx and migrating to Envoy Gateway.

Step 1: Start Minikube and Enable NGINX Ingress

minikube start
minikube addons enable ingress

Step 2: Deploy httpbin and Ingress Resources

kubectl apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
  template:
    metadata:
      labels:
        app: httpbin
    spec:
      containers:
      - name: httpbin
        image: kennethreitz/httpbin
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
spec:
  selector:
    app: httpbin
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: httpbin
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: httpbin.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: httpbin
            port:
              number: 80
EOF

Step 3: Expose LoadBalancer via Tunnel

minikube tunnel

Step 4: Test NGINX Ingress

curl -H "Host: httpbin.local" http://127.0.0.1/get

Step 5: Install Envoy Gateway

helm install eg oci://docker.io/envoyproxy/gateway-helm \
  --version v1.3.2 \
  -n envoy-gateway-system --create-namespace

Step 6: Apply GatewayClass for nginx

kubectl apply -f - << EOF
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: nginx
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
EOF

Step 7: Convert Ingress to Gateway API

Install conversion tool:

go install github.com/kubernetes-sigs/ingress2gateway@latest

Convert config:

ingress2gateway print --providers ingress-nginx | kubectl apply -f -

Optionally specify --namespace if Ingress resources are not in default.

Step 8: Validate Migration

Test the route:

curl --header 'Host: httpbin.local' http://127.0.0.1/get

Step 9: Cleanup nginx (Optional)

Terminate the minikube tunnel and then disable the ingress:

minikube addons disable ingress

Summary

By migrating to Envoy Gateway, you gain access to a more expressive, robust ingress configuration backed by the CNCF community. Features like rate limiting, WAF, and identity integration come built-in and standards-based.

Further Reading

This blog was initially published at tetrate.io.