Skip to content
Chimera readability score 0.4081 out of 100, reading level.

With the Ingress-NGINX retirement scheduled for March 2026, the Kubernetes networking landscape is at a turning point. For most organizations, the question isn't whether to migrate to Gateway API, but how to do so safely.

Migrating from Ingress to Gateway API is a fundamental shift in API design. Gateway API provides a modular, extensible API with strong support for Kubernetes-native RBAC. Conversely, the Ingress API is simple, and implementations such as Ingress-NGINX extend the API through esoteric annotations, ConfigMaps, and CRDs. Migrating away from Ingress controllers such as Ingress-NGINX presents the daunting task of capturing all the nuances of the Ingress controller, and mapping that behavior to Gateway API.

Ingress2Gateway is an assistant that helps teams confidently move from Ingress to Gateway API. It translates Ingress resources/manifests along with implementation-specific annotations to Gateway API while warning you about untranslatable configuration and offering suggestions.

Today, SIG Network is proud to announce the 1.0 release of Ingress2Gateway. This milestone represents a stable, tested migration assistant for teams ready to modernize their networking stack.

Ingress2Gateway 1.0

Ingress-NGINX annotation support

The main improvement for the 1.0 release is more comprehensive Ingress-NGINX support. Before the 1.0 release, Ingress2Gateway only supported three Ingress-NGINX annotations. For the 1.0 release, Ingress2Gateway supports over 30 common annotations (CORS, backend TLS, regex matching, path rewrite, etc.).

Comprehensive integration testing

Each supported Ingress-NGINX annotation, and representative combinations of common annotations, is backed by controller-level integration tests that verify the behavioral equivalence of the Ingress-NGINX configuration and the generated Gateway API. These tests exercise real controllers in live clusters and compare runtime behavior (routing, redirects, rewrites, etc.), not just YAML structure.

The tests:

  • spin up an Ingress-NGINX controller
  • spin up multiple Gateway API controllers
  • apply Ingress resources that have implementation-specific configuration
  • translate Ingress resources to Gateway API with

ingress2gateway

and apply generated manifests - verify that the Gateway API controllers and the Ingress controller exhibit equivalent behavior.

A comprehensive test suite not only catches bugs in development, but also ensures the correctness of the translation, especially given surprising edge cases and unexpected defaults, so that you don't find out about them in production.

Notification & error handling

Migration is not a "one-click" affair. Surfacing subtleties and untranslatable behavior is as important as translating supported configuration. The 1.0 release cleans up the formatting and content of notifications, so it is clear what is missing and how you can fix it.

Using Ingress2Gateway

Ingress2Gateway is a migration assistant, not a one-shot replacement. Its goal is to

  • migrate supported Ingress configuration and behavior
  • identify unsupported configuration and suggest alternatives
  • reevaluate and potentially discard undesirable configuration

The rest of the section shows you how to safely migrate the following Ingress-NGINX configuration

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

annotations:

nginx.ingress.kubernetes.io/proxy-body-size: "1G"

nginx.ingress.kubernetes.io/use-regex: "true"

nginx.ingress.kubernetes.io/proxy-send-timeout: "1"

nginx.ingress.kubernetes.io/proxy-read-timeout: "1"

nginx.ingress.kubernetes.io/enable-cors: "true"

nginx.ingress.kubernetes.io/configuration-snippet: |

more_set_headers "Request-Id: $req_id";

name: my-ingress

namespace: my-ns

spec:

ingressClassName: nginx

rules:

  • host: my-host.example.com

http:

paths:

  • backend:

service:

name: website-service

port:

number: 80

path: /users/(\d+)

pathType: ImplementationSpecific

tls:

  • hosts:
  • my-host.example.com

secretName: my-secret

1. Install Ingress2Gateway

If you have a Go environment set up, you can install Ingress2Gateway with

go install github.com/kubernetes-sigs/ingress2gateway@v1.0.0

Otherwise,

brew install ingress2gateway

You can also download the binary from GitHub or build from source.

2. Run Ingress2Gateway

You can pass Ingress2Gateway Ingress manifests, or have the tool read directly from your cluster.

Pass it files

ingress2gateway print --input-file my-manifest.yaml,my-other-manifest.yaml --providers=ingress-nginx > gwapi.yaml

Use a namespace in your cluster

ingress2gateway print --namespace my-api --providers=ingress-nginx > gwapi.yaml

Or your whole cluster

ingress2gateway print --providers=ingress-nginx --all-namespaces > gwapi.yaml

Note:

You can also pass--emitter <agentgateway|envoy-gateway|kgateway>

to output implementation-specific extensions.3. Review the output

This is the most critical step.

The commands from the previous section output a Gateway API manifest to gwapi.yaml

, and they also emit warnings that explain what did not translate exactly and what to review manually.

apiVersion: gateway.networking.k8s.io/v1

kind: Gateway

metadata:

annotations:

gateway.networking.k8s.io/generator: ingress2gateway-dev

name: nginx

namespace: my-ns

spec:

gatewayClassName: nginx

listeners:

  • hostname: my-host.example.com

name: my-host-example-com-http

port: 80

protocol: HTTP

  • hostname: my-host.example.com

name: my-host-example-com-https

port: 443

protocol: HTTPS

tls:

certificateRefs:

  • group: ""

kind: Secret

name: my-secret


apiVersion: gateway.networking.k8s.io/v1

kind: HTTPRoute

metadata:

annotations:

gateway.networking.k8s.io/generator: ingress2gateway-dev

name: my-ingress-my-host-example-com

namespace: my-ns

spec:

hostnames:

  • my-host.example.com

parentRefs:

  • name: nginx

port: 443

rules:

  • backendRefs:
  • name: website-service

port: 80

filters:

  • cors:

allowCredentials: true

allowHeaders:

  • DNT
  • Keep-Alive
  • User-Agent
  • X-Requested-With
  • If-Modified-Since
  • Cache-Control
  • Content-Type
  • Range
  • Authorization

allowMethods:

  • GET
  • PUT
  • POST
  • DELETE
  • PATCH
  • OPTIONS

allowOrigins:

  • '*'

maxAge: 1728000

type: CORS

matches:

  • path:

type: RegularExpression

value: (?i)/users/(\d+).*

name: rule-0

timeouts:

request: 10s


apiVersion: gateway.networking.k8s.io/v1

kind: HTTPRoute

metadata:

annotations:

gateway.networking.k8s.io/generator: ingress2gateway-dev

name: my-ingress-my-host-example-com-ssl-redirect

namespace: my-ns

spec:

hostnames:

  • my-host.example.com

parentRefs:

  • name: nginx

port: 80

rules:

  • filters:
  • requestRedirect:

scheme: https

statusCode: 308

type: RequestRedirect

Ingress2Gateway successfully translated some annotations into their Gateway API equivalents.

For example, the nginx.ingress.kubernetes.io/enable-cors

annotation was translated into a CORS filter.

But upon closer inspection, the nginx.ingress.kubernetes.io/proxy-{read,send}-timeout

and nginx.ingress.kubernetes.io/proxy-body-size

annotations do not map perfectly.

The logs show the reason for these omissions as well as reasoning behind the translation.

┌─ WARN ────────────────────────────────────────

│ Unsupported annotation nginx.ingress.kubernetes.io/configuration-snippet

│ source: INGRESS-NGINX

│ object: Ingress: my-ns/my-ingress

└─

┌─ INFO ────────────────────────────────────────

│ Using case-insensitive regex path matches. You may want to change this.

│ source: INGRESS-NGINX

│ object: HTTPRoute: my-ns/my-ingress-my-host-example-com

└─

┌─ WARN ────────────────────────────────────────

│ ingress-nginx only supports TCP-level timeouts; i2gw has made a best-effort translation to Gateway API timeouts.request. Please verify that this meets your needs. See documentation: https://gateway-api.sigs.k8s.io/guides/http-timeouts/

│ source: INGRESS-NGINX

│ object: HTTPRoute: my-ns/my-ingress-my-host-example-com

└─

┌─ WARN ────────────────────────────────────────

│ Failed to apply my-ns.my-ingress.metadata.annotations."nginx.ingress.kubernetes.io/proxy-body-size" from my-ns/my-ingress: Most Gateway API implementations have reasonable body size and buffering defaults

│ source: STANDARD_EMITTER

│ object: HTTPRoute: my-ns/my-ingress-my-host-example-com

└─

┌─ WARN ────────────────────────────────────────

│ Gateway API does not support configuring URL normalization (RFC 3986, Section 6). Please check if this matters for your use case and consult implementation-specific details.

│ source: STANDARD_EMITTER

└─

There is a warning that Ingress2Gateway does not support the nginx.ingress.kubernetes.io/configuration-snippet

annotation.

You will have to check your Gateway API implementation documentation to see if there is a way to achieve equivalent behavior.

The tool also notified us that Ingress-NGINX regex matches are case-insensitive prefix matches, which is why there is a match pattern of (?i)/users/(\d+).*

.

Most organizations will want to change this behavior to be an exact case-sensitive match by removing the leading (?i)

and the trailing .*

from the path pattern.

Ingress2Gateway made a best-effort translation from the nginx.ingress.kubernetes.io/proxy-{send,read}-timeout

annotations to a 10 second request timeout in our HTTP route.

If requests for this service should be much shorter, say 3 seconds, you can make the corresponding changes to your Gateway API manifests.

Also, nginx.ingress.kubernetes.io/proxy-body-size

does not have a Gateway API equivalent, and was thus not translated.

However, most Gateway API implementations have reasonable defaults for maximum body size and buffering, so this might not be a problem in practice.

Further, some emitters might offer support for this annotation through implementation-specific extensions.

For example, adding the --emitter agentgateway

, --emitter envoy-gateway

, or --emitter kgateway

flag to the previous ingress2gateway print

command would have resulted in additional implementation-specific configuration in the generated Gateway API manifests that attempted to capture the body size configuration.

We also see a warning about URL normalization. Gateway API implementations such as Agentgateway, Envoy Gateway, Kgateway, and Istio have some level of URL normalization, but the behavior varies across implementations and is not configurable through standard Gateway API. You should check and test the URL normalization behavior of your Gateway API implementation to ensure it is compatible with your use case.

To match Ingress-NGINX default behavior, Ingress2Gateway also added a listener on port 80 and a HTTP Request redirect filter to redirect HTTP traffic to HTTPS. You may not want to serve HTTP traffic at all and remove the listener on port 80 and the corresponding HTTPRoute.

Caution:

Always thoroughly review the generated output and logs.After manually applying these changes, the Gateway API manifests might look as follows.


apiVersion: gateway.networking.k8s.io/v1

kind: Gateway

metadata:

annotations:

gateway.networking.k8s.io/generator: ingress2gateway-dev

name: nginx

namespace: my-ns

spec:

gatewayClassName: nginx

listeners:

  • hostname: my-host.example.com

name: my-host-example-com-https

port: 443

protocol: HTTPS

tls:

certificateRefs:

  • group: ""

kind: Secret

name: my-secret


apiVersion: gateway.networking.k8s.io/v1

kind: HTTPRoute

metadata:

annotations:

gateway.networking.k8s.io/generator: ingress2gateway-dev

name: my-ingress-my-host-example-com

namespace: my-ns

spec:

hostnames:

  • my-host.example.com

parentRefs:

  • name: nginx

port: 443

rules:

  • backendRefs:
  • name: website-service

port: 80

filters:

  • cors:

allowCredentials: true

allowHeaders:

  • DNT

...

allowMethods:

  • GET

...

allowOrigins:

  • '*'

maxAge: 1728000

type: CORS

matches:

  • path:

type: RegularExpression

value: /users/(\d+)

name: rule-0

timeouts:

request: 3s

4. Verify

Now that you have Gateway API manifests, you should thoroughly test them in a development cluster. In this case, you should at least double-check that your Gateway API implementation's maximum body size defaults are appropriate for you and verify that a three-second timeout is enough.

After validating behavior in a development cluster, deploy your Gateway API configuration alongside your existing Ingress. We strongly suggest that you then gradually shift traffic using weighted DNS, your cloud load balancer, or traffic-splitting features of your platform. This way, you can quickly recover from any misconfiguration that made it through your tests.

Finally, when you have shifted all your traffic to your Gateway API controller, delete your Ingress resources and uninstall your Ingress controller.

Conclusion

The Ingress2Gateway 1.0 release is just the beginning, and we hope that you use Ingress2Gateway to safely migrate to Gateway API. As we approach the March 2026 Ingress-NGINX retirement, we invite the community to help us increase our configuration coverage, expand testing, and improve UX.

Resources about Gateway API

The scope of Gateway API can be daunting. Here are some resources to help you work with Gateway API:

  • Listener sets allow application developers to manage gateway listeners.

gwctl

gives you a comprehensive view of your Gateway resources, such as attachments and linter errors.- Gateway API Slack:

#sig-network-gateway-api

on Kubernetes Slack - Ingress2Gateway Slack:

#sig-network-ingress2gateway

on Kubernetes Slack - GitHub: kubernetes-sigs/ingress2gateway

Facts Only

Ingress-NGINX is scheduled for retirement in March 2026.
Gateway API is a modular, extensible alternative with native Kubernetes RBAC support.
Ingress2Gateway 1.0 is a migration tool released by SIG Network.
The tool supports over 30 Ingress-NGINX annotations, including CORS, backend TLS, and regex matching.
Integration tests verify behavioral equivalence between Ingress-NGINX and Gateway API configurations.
Ingress2Gateway can be installed via Go, Homebrew, or direct download.
The tool generates Gateway API manifests from Ingress resources and flags untranslatable configurations.
Warnings are provided for unsupported features like `nginx.ingress.kubernetes.io/configuration-snippet`.
Implementation-specific emitters (e.g., Agentgateway, Envoy Gateway) can extend functionality.
A gradual migration strategy is recommended, including testing in development and phased traffic shifting.
Community contributions are encouraged to expand configuration coverage.

Executive Summary

The Kubernetes networking ecosystem is undergoing a significant transition with the scheduled retirement of Ingress-NGINX in March 2026. Organizations are moving toward Gateway API, a more modular and extensible solution with native Kubernetes RBAC support. The shift presents challenges, as Ingress-NGINX relies on annotations, ConfigMaps, and CRDs, which require careful translation to Gateway API. Ingress2Gateway 1.0 has been released as a migration assistant to address these challenges, offering comprehensive support for over 30 common Ingress-NGINX annotations, including CORS, backend TLS, and path rewrites. The tool includes rigorous integration testing to ensure behavioral equivalence between Ingress-NGINX and Gateway API configurations, along with clear warnings for untranslatable features. Users can install Ingress2Gateway via Go, Homebrew, or direct download, then generate Gateway API manifests from existing Ingress resources. The tool highlights gaps, such as unsupported annotations or implementation-specific behaviors, and suggests manual adjustments. A gradual migration strategy is recommended, with testing in development environments and phased traffic shifting to minimize risks. The project invites community contributions to expand coverage and improve usability as the 2026 deadline approaches.

Full Take

The transition from Ingress-NGINX to Gateway API represents more than a technical upgrade—it reflects a broader shift toward standardization and modularity in Kubernetes networking. The strongest version of this narrative is that Ingress2Gateway 1.0 provides a pragmatic, well-tested path for organizations to modernize their infrastructure while mitigating risks. The tool’s emphasis on behavioral equivalence testing and clear warnings about gaps demonstrates a commitment to transparency and user agency.
However, the narrative assumes that Gateway API is the inevitable successor, which may overlook valid use cases where Ingress-NGINX’s simplicity or specific features remain preferable. The focus on "unsupported" annotations could also create pressure to conform to Gateway API’s design, potentially discarding legacy configurations that still serve operational needs. The call for community contributions, while collaborative, might also shift maintenance burdens onto users rather than core developers.
Root cause: This narrative is driven by the Kubernetes ecosystem’s push for standardization, where flexibility (Ingress-NGINX’s annotations) is traded for consistency (Gateway API’s structured filters). The unstated assumption is that modularity and RBAC are universally superior, which may not hold for teams with stable, annotation-heavy setups.
Implications: Organizations gain long-term maintainability but may face short-term disruption. Smaller teams with limited resources could struggle with the migration’s complexity, while larger enterprises benefit from Gateway API’s scalability. The retirement timeline also creates urgency, potentially forcing migrations before teams are fully prepared.
Bridge questions: What trade-offs between simplicity and extensibility are being made in this transition? How might teams with deeply embedded Ingress-NGINX configurations weigh the costs of migration against the benefits? What alternatives exist for those who cannot migrate by 2026?
Counterstrike scan: A coordinated influence campaign would exaggerate the risks of staying on Ingress-NGINX while downplaying Gateway API’s learning curve. The actual content avoids this, focusing on practical migration steps and acknowledging gaps. No manipulation patterns detected.
Patterns detected: none

Sentinel — Human

Confidence

The article shows strong signs of human authorship, with technical depth, idiosyncratic emphasis, and practical cautionary advice that are inconsistent with AI-generated content.

Signals Detected
low severity: Sentence length variance is high, with a mix of short and long sentences, inconsistent with AI-generated uniformity.
low severity: Text exhibits passionate emphasis on specific technical details (e.g., warnings about untranslatable configurations), which is atypical of AI-generated content.
low severity: No signs of template-driven argumentation or verbatim repetition of talking points across sources.
low severity: All claims are attributed to specific technical configurations or documented behaviors, with no vague or unverifiable assertions.
Human Indicators
Idiosyncratic emphasis on edge cases and manual review steps, reflecting real-world engineering experience.
Detailed, implementation-specific examples (e.g., regex patterns, timeout translations) that suggest hands-on expertise.
Natural digressions into cautionary advice and testing methodologies, which are unlikely to be AI-generated.