Cloud

Migrating from NGINX Ingress to Envoy Gateway: Complete Guide (March 2026 Deadline)

admin

Executive Summary

CRITICAL UPDATE: Kubernetes SIG Network officially announced the retirement of NGINX Ingress Controller with a March 2026 deadline. After this date, there will be no security updates, bug fixes, or community support. Organizations running NGINX Ingress must migrate immediately to avoid security vulnerabilities and operational risks.

Envoy Gateway is the recommended migration path—a modern, Kubernetes Gateway API-compliant ingress controller built on Envoy Proxy. This comprehensive guide provides step-by-step migration strategies, configuration translation patterns, and production-proven best practices for zero-downtime migration.

If you need expert assistance with your NGINX to Envoy migration, our Envoy Gateway enterprise support team can help ensure a smooth, secure transition before the deadline.


Table of Contents

  1. Why NGINX Ingress Is Retiring
  2. Why Choose Envoy Gateway
  3. Pre-Migration Assessment
  4. Migration Strategy Options
  5. Step-by-Step Migration Guide
  6. Configuration Translation Reference
  7. Testing & Validation
  8. Rollback Strategy
  9. Post-Migration Optimization
  10. Common Migration Challenges

Why NGINX Ingress Is Retiring

The official Kubernetes blog announcement cites three critical reasons for retirement:

1. Insufficient Maintainership

Only 1-2 maintainers working in spare time, unable to sustain the project’s scale and complexity.

2. Accumulated Technical Debt

Features like annotation-based configuration snippets, once considered helpful, now pose significant security risks by allowing arbitrary NGINX configuration injection.

3. Security Prioritization

Rather than leaving the project unmaintained and vulnerable, Kubernetes SIG Network chose responsible retirement to protect the community.

Timeline

  • Now - March 2026: Best-effort maintenance only
  • March 2026+: No updates, no security patches, project archived

Organizations must migrate before March 2026 to maintain security compliance and avoid vulnerabilities. For cloud migration services and expert guidance, our team has migrated hundreds of production workloads to Envoy Gateway with zero downtime.


Why Choose Envoy Gateway

Envoy Gateway represents the future of Kubernetes ingress, built on proven cloud-native technologies.

Key Advantages Over NGINX

FeatureNGINX IngressEnvoy Gateway
Gateway API ComplianceLimited (annotation-based)Full native support
Configuration ModelStatic with reloadsDynamic (xDS API)
ObservabilityBasic metricsRich metrics, tracing, access logs
Multi-tenancyComplex via annotationsBuilt-in Gateway classes
Service Mesh IntegrationExternalNative (Istio, Consul)
HTTP/3 & QUICLimitedFull support
SecurityManual snippets (risky)Policy-driven, no arbitrary config
Community SupportRetiring March 2026Active CNCF project

Gateway API Benefits

The Kubernetes Gateway API is the successor to the Ingress API, offering:

  • Role-oriented design: Separate resources for platform teams vs. app teams
  • Stronger typing: Explicit, validated configuration
  • Extended protocol support: TCP, UDP, gRPC, WebSockets
  • Portable across controllers: Vendor-neutral specification

Envoy Gateway is one of the first Gateway API-compliant controllers, making it the natural migration path for NGINX Ingress users.


Pre-Migration Assessment

Before starting migration, conduct a thorough assessment of your current NGINX Ingress deployment.

1. Inventory Your NGINX Resources

# List all NGINX Ingress controllers
kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx

# Count total Ingress resources
kubectl get ingress --all-namespaces --no-headers | wc -l

# Identify custom annotations
kubectl get ingress --all-namespaces -o yaml | grep "nginx.ingress.kubernetes.io" | sort -u

# Check for ConfigMaps
kubectl get configmap -n ingress-nginx

2. Document Current Configuration

Catalog all NGINX-specific features in use:

  • Annotations: nginx.ingress.kubernetes.io/*
  • Configuration snippets: Custom NGINX directives
  • TLS/SSL settings: Certificate management, SNI
  • Rewrite rules: URL path rewrites
  • Authentication: Basic auth, OAuth, external auth
  • Rate limiting: Request throttling
  • Custom error pages: Error handling
  • Upstream parameters: Connection pooling, timeouts

3. Assess Complexity

Low Complexity (1-2 weeks):

  • Simple path-based routing
  • Basic TLS termination
  • Few custom annotations

Medium Complexity (2-4 weeks):

  • Multiple authentication methods
  • Complex rewrite rules
  • Rate limiting and circuit breaking
  • Custom error handling

High Complexity (1-3 months):

  • Heavy use of configuration snippets
  • Custom Lua scripts
  • Advanced traffic splitting
  • Multi-cluster ingress

For Kubernetes consulting services and migration complexity assessment, our certified engineers can provide detailed analysis and migration roadmaps.


Migration Strategy Options

Choose the migration approach based on your risk tolerance and operational constraints.

Best for: Production workloads, risk-averse organizations

Run NGINX and Envoy side-by-side, gradually shifting traffic:

┌─────────────┐
│   Clients   │
└──────┬──────┘

   ┌───▼────┐
   │   DNS  │ (Gradual weight shift)
   └───┬────┘

   ┌───┴────────────────┐
   ▼                    ▼
┌──────────┐      ┌────────────┐
│  NGINX   │      │   Envoy    │
│ Ingress  │      │  Gateway   │
└────┬─────┘      └─────┬──────┘
     │                  │
     └────────┬─────────┘

        ┌──────────┐
        │ Backend  │
        │ Services │
        └──────────┘

Pros:

  • Zero downtime
  • Easy rollback
  • Gradual validation
  • Traffic comparison

Cons:

  • Requires extra resources
  • Dual maintenance window
  • DNS TTL considerations

Strategy 2: Blue-Green Deployment

Best for: Organizations with multiple environments

Deploy Envoy in a separate cluster/namespace, switch via DNS:

Pros:

  • Complete isolation
  • Full testing before cutover
  • Instant rollback

Cons:

  • Requires duplicate infrastructure
  • DNS propagation delay
  • Higher cost during migration

Strategy 3: In-Place Replacement

Best for: Non-critical environments, tight resource constraints

Replace NGINX directly with Envoy:

Pros:

  • Minimal resource overhead
  • Faster migration
  • Simpler architecture

Cons:

  • Higher risk
  • Potential downtime
  • Limited rollback options

Step-by-Step Migration Guide

Phase 1: Environment Preparation

1.1 Install Envoy Gateway

Install Envoy Gateway using Helm:

# Add Envoy Gateway Helm repository
helm repo add envoy-gateway https://gateway.envoyproxy.io/
helm repo update

# Install Envoy Gateway
helm install eg envoy-gateway/gateway-helm \
  --namespace envoy-gateway-system \
  --create-namespace \
  --set deployment.envoyGateway.resources.limits.cpu=1000m \
  --set deployment.envoyGateway.resources.limits.memory=1024Mi

Verify installation:

kubectl get pods -n envoy-gateway-system
kubectl get gatewayclass

Expected output:

NAME            CONTROLLER                  ACCEPTED   AGE
eg              gateway.envoyproxy.io/eg    True       1m

1.2 Create Gateway Resource

Define a Gateway resource (equivalent to NGINX Ingress Controller):

# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: production-gateway
  namespace: default
spec:
  gatewayClassName: eg
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    allowedRoutes:
      namespaces:
        from: All
  - name: https
    protocol: HTTPS
    port: 443
    tls:
      mode: Terminate
      certificateRefs:
      - name: production-tls-cert
        kind: Secret
    allowedRoutes:
      namespaces:
        from: All

Apply:

kubectl apply -f gateway.yaml

For cloud-native consulting and Gateway API architecture design, our team can help optimize your ingress strategy.


Phase 2: Configuration Translation

2.1 Simple Path-Based Routing

NGINX Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 3000

Envoy Gateway (HTTPRoute):

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-route
spec:
  parentRefs:
  - name: production-gateway
  hostnames:
  - "example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api
    backendRefs:
    - name: api-service
      port: 8080
  - matches:
    - path:
        type: PathPrefix
        value: /web
    backendRefs:
    - name: web-service
      port: 3000

2.2 TLS/SSL Configuration

NGINX Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - secure.example.com
    secretName: tls-secret
  rules:
  - host: secure.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: secure-app
            port:
              number: 443

Envoy Gateway:

# TLS certificate (same Secret format)
apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
type: kubernetes.io/tls
data:
  tls.crt: <base64-cert>
  tls.key: <base64-key>
---
# Gateway with TLS listener (already defined above)
# HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: tls-route
spec:
  parentRefs:
  - name: production-gateway
    sectionName: https
  hostnames:
  - "secure.example.com"
  rules:
  - backendRefs:
    - name: secure-app
      port: 443

Envoy Gateway integrates seamlessly with cert-manager for automated certificate management.

2.3 Rewrite Rules

NGINX Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rewrite-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /old-api(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080

Envoy Gateway:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: rewrite-route
spec:
  parentRefs:
  - name: production-gateway
  hostnames:
  - "example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /old-api
    filters:
    - type: URLRewrite
      urlRewrite:
        path:
          type: ReplacePrefixMatch
          replacePrefixMatch: /
    backendRefs:
    - name: api-service
      port: 8080

2.4 Rate Limiting

NGINX Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ratelimit-ingress
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "10"
    nginx.ingress.kubernetes.io/limit-connections: "20"
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080

Envoy Gateway:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: ratelimit-policy
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: api-route
  rateLimit:
    type: Global
    global:
      rules:
      - clientSelectors:
        - headers:
          - name: x-user-id
            type: Distinct
        limit:
          requests: 10
          unit: Second

For advanced Envoy Proxy configuration and optimization, our certified engineers provide production-grade implementations.


Phase 3: Gradual Traffic Migration

3.1 DNS-Based Canary

Use weighted DNS records to shift traffic gradually:

# Week 1: 10% Envoy, 90% NGINX
# Week 2: 25% Envoy, 75% NGINX
# Week 3: 50% Envoy, 50% NGINX
# Week 4: 75% Envoy, 25% NGINX
# Week 5: 100% Envoy

Example with AWS Route 53:

{
  "ResourceRecordSets": [
    {
      "Name": "example.com",
      "Type": "A",
      "SetIdentifier": "nginx-ingress",
      "Weight": 90,
      "TTL": 60,
      "ResourceRecords": [{"Value": "NGINX_LB_IP"}]
    },
    {
      "Name": "example.com",
      "Type": "A",
      "SetIdentifier": "envoy-gateway",
      "Weight": 10,
      "TTL": 60,
      "ResourceRecords": [{"Value": "ENVOY_LB_IP"}]
    }
  ]
}

3.2 Service Mesh Traffic Splitting

If using Istio or similar service mesh:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: ingress-split
spec:
  hosts:
  - example.com
  http:
  - match:
    - headers:
        x-canary:
          exact: "true"
    route:
    - destination:
        host: envoy-gateway.envoy-gateway-system.svc.cluster.local
      weight: 100
  - route:
    - destination:
        host: envoy-gateway.envoy-gateway-system.svc.cluster.local
      weight: 10
    - destination:
        host: ingress-nginx-controller.ingress-nginx.svc.cluster.local
      weight: 90

Phase 4: Monitoring & Observability

Implement comprehensive monitoring to compare NGINX vs. Envoy performance during migration.

4.1 Prometheus Metrics

Envoy Gateway exposes rich Prometheus metrics:

# ServiceMonitor for Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: envoy-gateway
  namespace: envoy-gateway-system
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: envoy-gateway
  endpoints:
  - port: metrics
    interval: 30s
    path: /stats/prometheus

Key metrics to monitor:

  • envoy_http_downstream_rq_total - Total requests
  • envoy_http_downstream_rq_xx - Response codes (2xx, 4xx, 5xx)
  • envoy_http_downstream_rq_time_bucket - Request latency
  • envoy_cluster_upstream_cx_connect_fail - Backend failures
  • envoy_cluster_upstream_cx_active - Active connections

For Prometheus and Grafana support, our team provides complete observability stack implementation.

4.2 Grafana Dashboards

Import pre-built Envoy Proxy Grafana dashboards:

# Import dashboard ID 11021 (Envoy Proxy)
# Import dashboard ID 14114 (Envoy Gateway)

4.3 Distributed Tracing

Enable Jaeger tracing for request flow visualization:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: tracing-config
  namespace: envoy-gateway-system
spec:
  telemetry:
    tracing:
      provider:
        jaeger:
          endpoint: jaeger-collector.observability.svc.cluster.local:4317
      samplingRate: 100

Configuration Translation Reference

Common NGINX Annotations → Envoy Gateway

NGINX AnnotationEnvoy Gateway Equivalent
nginx.ingress.kubernetes.io/rewrite-targetHTTPRoute.spec.rules.filters.urlRewrite
nginx.ingress.kubernetes.io/ssl-redirectGateway.spec.listeners.tls.mode: Redirect
nginx.ingress.kubernetes.io/limit-rpsBackendTrafficPolicy.spec.rateLimit
nginx.ingress.kubernetes.io/auth-type: basicSecurityPolicy.spec.basicAuth
nginx.ingress.kubernetes.io/cors-allow-originSecurityPolicy.spec.cors
nginx.ingress.kubernetes.io/backend-protocolBackendRef protocol field
nginx.ingress.kubernetes.io/configuration-snippetPolicy-based (no arbitrary config)

Authentication Migration

NGINX Basic Auth:

annotations:
  nginx.ingress.kubernetes.io/auth-type: basic
  nginx.ingress.kubernetes.io/auth-secret: basic-auth
  nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"

Envoy Gateway SecurityPolicy:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: basic-auth-policy
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: protected-route
  basicAuth:
    users:
      secretRef:
        name: basic-auth

For complete DevOps automation and CI/CD pipelines integrating Envoy Gateway, our consultants deliver production-ready implementations.


Testing & Validation

Pre-Cutover Testing

1. Functional Testing

# Test routing
curl -H "Host: example.com" http://ENVOY_LB_IP/api/health

# Test HTTPS/TLS
curl -v https://example.com/api/health

# Test rewrites
curl -H "Host: example.com" http://ENVOY_LB_IP/old-api/users

# Test rate limiting
for i in {1..20}; do curl -H "Host: api.example.com" http://ENVOY_LB_IP/; done

2. Load Testing

Use k6 or Apache Bench:

// k6 load test
import http from 'k6/http';
import { check } from 'k6';

export let options = {
  stages: [
    { duration: '2m', target: 100 },
    { duration: '5m', target: 100 },
    { duration: '2m', target: 0 },
  ],
};

export default function () {
  let response = http.get('https://example.com/api/health');
  check(response, {
    'status is 200': (r) => r.status === 200,
    'response time < 200ms': (r) => r.timings.duration < 200,
  });
}

3. Chaos Testing

Validate Envoy Gateway resilience:

# Chaos Mesh experiment
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: envoy-pod-failure
spec:
  action: pod-failure
  mode: one
  selector:
    namespaces:
    - envoy-gateway-system
    labelSelectors:
      app.kubernetes.io/name: envoy-gateway
  duration: "30s"
  scheduler:
    cron: "@every 10m"

Rollback Strategy

Immediate Rollback (DNS)

# Revert DNS weights to 100% NGINX
# TTL-dependent (typically 60-300 seconds)

Pod-Level Rollback

# Scale down Envoy Gateway
kubectl scale deployment -n envoy-gateway-system \
  gateway-helm-envoy-gateway --replicas=0

# Verify NGINX is handling traffic
kubectl get pods -n ingress-nginx

Full Rollback

# Delete HTTPRoutes
kubectl delete httproute --all -A

# Delete Gateway
kubectl delete gateway production-gateway

# Keep Envoy Gateway installed for future attempts

Post-Migration Optimization

1. Enable HTTP/3

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: production-gateway
spec:
  gatewayClassName: eg
  listeners:
  - name: https-http3
    protocol: HTTPS
    port: 443
    tls:
      mode: Terminate
      certificateRefs:
      - name: production-tls-cert
    allowedRoutes:
      namespaces:
        from: All

2. Implement Circuit Breaking

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: circuit-breaker
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: api-route
  circuitBreaker:
    maxConnections: 1024
    maxPendingRequests: 1024
    maxRequests: 1024
    maxRetries: 3

3. Configure Health Checks

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
  name: health-check-policy
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: api-route
  healthCheck:
    active:
      interval: 10s
      timeout: 1s
      unhealthyThreshold: 3
      healthyThreshold: 2
      http:
        path: /health
        expectedStatuses:
        - 200

Common Migration Challenges

Challenge 1: Configuration Snippets

Problem: NGINX configuration-snippet annotations are not supported in Envoy Gateway (by design, for security).

Solution: Use EnvoyPatchPolicy for advanced configuration (use sparingly):

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
  name: custom-headers
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: production-gateway
  type: JSONPatch
  jsonPatches:
  - type: "type.googleapis.com/envoy.config.listener.v3.Listener"
    name: default-https
    operation:
      op: add
      path: "/filter_chains/0/filters/0/typed_config/http_filters/0"
      value:
        name: envoy.filters.http.header_to_metadata
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config

Challenge 2: External Authentication

Problem: NGINX auth-url annotation requires migration to Envoy external authorization.

Solution: Deploy ext-authz server:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: ext-authz
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: protected-route
  extAuth:
    http:
      service:
        name: auth-service
        namespace: auth
        port: 8080
      path: /verify
      headersToBackend:
      - x-user-id
      - x-user-role

Challenge 3: Custom Lua Scripts

Problem: NGINX Lua scripts are not portable to Envoy.

Solution: Rewrite logic in:

  • Wasm filters (WebAssembly) - Portable, secure
  • External processors - Dedicated microservices
  • Upstream services - Move logic to backends

For Terraform infrastructure as code automating Envoy Gateway deployments, our experts provide production-ready modules.


Production Checklist

Before declaring migration complete:

  • All HTTPRoutes validated and tested
  • TLS certificates migrated and verified
  • Monitoring dashboards configured (Prometheus/Grafana)
  • Distributed tracing enabled (Jaeger/Zipkin)
  • Load testing completed (equal or better performance)
  • Rollback procedure documented and tested
  • On-call runbooks updated
  • DNS TTLs optimized for quick rollback
  • Security policies reviewed (rate limiting, CORS, auth)
  • Health checks configured for all backends
  • Circuit breakers tuned for traffic patterns
  • Documentation updated for developer teams
  • Training completed for operations team
  • Post-migration monitoring period (2+ weeks)
  • NGINX Ingress decommissioned after validation period

Migration Timeline Example

Week 1-2: Preparation

  • Assessment and inventory
  • Envoy Gateway installation in staging
  • Team training

Week 3-4: Translation

  • Convert Ingress → HTTPRoute
  • Test in staging environment
  • Load testing

Week 5-6: Production Canary

  • 10% traffic to Envoy
  • Monitor metrics and errors
  • Adjust as needed

Week 7-8: Gradual Rollout

  • 25% → 50% → 75% traffic shift
  • Continuous monitoring
  • Performance comparison

Week 9: Full Cutover

  • 100% traffic to Envoy Gateway
  • Monitor for 2 weeks
  • Keep NGINX as hot standby

Week 11-12: Decommission

  • Remove NGINX Ingress
  • Final documentation
  • Retrospective

Next Steps

The March 2026 NGINX Ingress retirement is approaching fast. Organizations must act now to ensure secure, compliant ingress infrastructure.

Need Expert Help?

Our official Envoy Gateway enterprise support team provides:

Migration Assessment - Free 30-minute consultation ✅ Zero-Downtime Migration - Production-proven strategies ✅ Configuration Translation - Automated and manual conversion ✅ 24/7 Support - SLA-backed incident response ✅ Training & Knowledge Transfer - Team enablement

Schedule a free consultation to discuss your NGINX to Envoy migration timeline and strategy.

For comprehensive AWS managed services including Envoy Gateway on EKS, our certified cloud engineers deliver end-to-end solutions.


Additional Resources

Official Documentation:

Migration Tools:

Related Services:

Don’t wait until March 2026—start your migration today to ensure a smooth, secure transition to Envoy Gateway.

Related Articles

Continue exploring these related topics

Chat with real humans