Moving an application from Ingress NGINX to Gateway API is a change to the request path, the ownership model and the failure modes of the platform. Converting a manifest is only the beginning.
The Kubernetes Steering and Security Response Committees announced the retirement of the community Ingress NGINX controller for March 2026, with no subsequent security patches or maintenance releases. Their official statement makes this a concrete operational concern. This guide, reviewed on 29 September 2026, develops a migration rehearsal for a hypothetical Spring Boot service. It is an engineering exercise, not a report of a production migration at my employer.
Identify exactly what is being replaced
Start by separating three things: the Kubernetes Ingress resource, the community Ingress NGINX controller, and other products that use NGINX. The Ingress documentation says the Ingress API is frozen but remains available; retiring one controller does not remove that API. A standalone Nginx reverse proxy in a virtual-machine lab is also a different component.
Inventory deployed controller images, IngressClasses, exposed load balancers and the configuration repository. Trace one real request from DNS through TLS termination to the application. Record where authentication runs, which component rewrites the path, and how the backend obtains client identity. A diagram that ends at the load balancer misses the behavior that application owners will notice.
For the example service, assume a public hostname, an HTTPS listener and a backend Service exposing port 8080. Keep that scope narrow for the first rehearsal. WebSocket sessions, gRPC traffic and shared wildcard hosts should receive separate acceptance cases rather than being assumed equivalent to a successful HTTP health check.
Map responsibilities before translating YAML
Gateway API distinguishes infrastructure configuration from application routing. In the Kubernetes Gateway overview, GatewayClass describes the implementation class, Gateway describes a traffic-handling instance, and route resources describe how requests reach backends. These resources provide a useful starting point for dividing platform and application responsibilities.
My suggested operating model is simple: the platform team owns the controller, GatewayClass, shared listeners and certificate lifecycle; the service owner maintains routes and backend readiness. Write down who can attach routes to a shared Gateway. Otherwise, a technically valid change can unexpectedly claim a hostname another application depends on.
Gateway API is an API, not a running proxy by itself. Select and install an implementation that supports the features your inventory requires. Compare its supported API versions, conformance results, cloud integration and upgrade process. A familiar vendor name does not prove that a particular authentication or timeout policy behaves the same way.
Establish a small routing baseline
The following illustrative resource attaches one application route to an existing HTTPS listener. It assumes the Gateway, certificate, controller, CRDs and backend Service already exist in the interview namespace. Replace the example hostname and names with the isolated test environment's values. It deliberately does not install infrastructure or change public DNS.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: interview-api
namespace: interview
spec:
parentRefs:
- name: interview-edge
sectionName: https
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: interview-api
port: 8080
The HTTP routing guide explains host matching, parent references and backend selection. In this example, the listener must allow the route attachment and its hostname must be compatible. The route forwards the original path; it does not silently strip /api. If the application expects a rewritten path, specify and test that behavior separately.
Keep the first route and Service in the same namespace to reduce moving parts. A later shared-platform design can introduce cross-namespace attachment or backend references with the appropriate permissions. Those are different relationships: permission to attach a route to a Gateway is not the same as permission to reference a Service in another namespace.
Test behavior that annotations used to hide
The Kubernetes article on surprising Ingress NGINX behaviors documents why seemingly equivalent rules can differ, including regular-expression matching. Treat each existing annotation as a question to answer. Is it required application behavior, an old workaround, or a controller-specific default that nobody intended to preserve?
| Boundary | Request to exercise | Evidence to compare |
|---|---|---|
| Path matching | /api, /api/bookings and /apix | Selected backend and observed upstream path |
| Authentication | Missing, expired and valid credentials | Status, challenge headers and application decision |
| Transport | HTTPS, redirects and certificate renewal | Hostname validation and redirect destination |
| Streaming | A long-lived connection across an idle period | Disconnect timing and reconnect behavior |
| Failure | No ready endpoints and a slow backend | Timeout, error response and retry behavior |
Include negative cases. A route that serves a legitimate request but also accepts an unintended hostname has not passed. Test encoded paths, trailing slashes and unusually large request bodies where those inputs matter. Compare response headers as well as status codes; an authentication callback may fail because its redirect location changed even though the first response is successful.
Be especially careful with retries on booking or payment-like operations. A gateway timeout does not establish that the backend abandoned the transaction. Preserve application idempotency and understand which requests the selected implementation can retry. Do not add retries merely to make an error-rate chart look better.
Check control-plane state and real traffic
Read the Gateway and HTTPRoute status after applying a candidate configuration in the test cluster. The Gateway API implementation guide explains conditions and the importance of observedGeneration. Look for current Gateway readiness/programming conditions and route parent conditions such as Accepted and ResolvedRefs, including their reason and message fields.
# Read-only inspection in the explicitly selected rehearsal context.
kubectl --context gateway-lab -n interview get gateway interview-edge -o yaml
kubectl --context gateway-lab -n interview get httproute interview-api -o yaml
kubectl --context gateway-lab -n interview get endpointslices
These commands inspect configuration and discovery state; they do not verify the complete client path. Send test traffic through the candidate endpoint using the intended hostname and TLS identity. Correlate edge access logs with application traces, and distinguish DNS, handshake, routing, authorization and backend failures. The investigation approach in my OpenTelemetry guide is useful here.
Use conversion tools as review inputs
Ingress2Gateway 1.0, announced in March 2026, expands support for translating Ingress NGINX annotations and reports configuration it cannot translate. Use its output to accelerate the inventory and create a reviewable starting point. A converter cannot know whether an undocumented workaround is part of your application's public contract.
Save the original configuration, generated output, warnings and the acceptance results together. Review one route at a time before merging common policies. If translation requires an implementation-specific extension, document that dependency explicitly. This makes the next controller upgrade easier to assess and prevents a claim of portability that the configuration cannot support.
Make cutover a measured operational change
Bring up the new path alongside the old one and test it before shifting public traffic. Define success using application outcomes: completed bookings, expected authorization decisions, latency distributions and connection stability. Set stop conditions before starting. A small traffic share should not advance simply because no alert happened during a quiet period.
Account for DNS caching, persistent connections and load-balancer behavior when planning rollback. Keep the old path only for a controlled transition period with an owner and a removal date; an unmaintained controller is not a long-term recovery strategy. After the observation window, remove unused certificates, addresses and configuration only when their remaining consumers are known.
The deliverable is a working route with reproducible evidence: ownership, exact implementation versions, acceptance cases, observed outcomes and a recovery procedure. That is where networking fundamentals, backend contracts and cloud operations meet. The YAML expresses the desired route; the rehearsal demonstrates what users will actually experience.
