Kubernetes Gateway API in 2026: A Practical Migration Guide for SMBs

For years, the Kubernetes Ingress object was the de facto way to expose services to the outside world. But as traffic patterns got more complex — path-based routing, weighted canary splits, header-based routing, and multiple ingress controllers — the classic Ingress API started to show its seams. In 2026, the Kubernetes Gateway API has officially reached GA for most core resources and is rapidly becoming the standard way SMBs route traffic into their clusters. If you’re still glued to nginx-ingress annotations, this guide will show you why — and how — to make the switch.

Why Gateway API Is Replacing Ingress

The original Ingress API was designed when Kubernetes had just a handful of users and one or two ingress controllers. It could only express a limited set of routing rules, and every controller vendor built its own proprietary annotations to fill the gaps. The result? Your Ingress config was locked to your controller, and advanced routing meant copying magic strings from vendor docs.

Gateway API fixes this with a role-based, expressive, and vendor-neutral model built around three core concepts:

  • Gateway — the infrastructure itself (the load balancer, one or more listeners/ports).
  • GatewayClass — the controller that implements the Gateway (e.g., nginx, traefik, istio, cilium).
  • HTTPRoute (and TCPRoute, TLSRoute, UDPRoute) — the routing rules that attach to a Gateway.

This separation means a platform team defines the infrastructure, while application teams define the routes — a clean boundary that maps perfectly to a DevOps/SRE operating model.

Core Concepts: Gateway, GatewayClass, and HTTPRoute

Let’s look at a real example. First, define a GatewayClass to say which controller implements the gateway:

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

Next, define the Gateway itself — the actual load balancer listening on a port:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: public-gateway
  namespace: infra
spec:
  gatewayClassName: nginx
  listeners:
    - name: http
      protocol: HTTP
      port: 80
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        certificateRefs:
          - name: wildcard-tls

Now the app team attaches an HTTPRoute — no annotations, no controller-specific magic:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-routes
  namespace: shop
spec:
  parentRefs:
    - name: public-gateway
      namespace: infra
  hostnames:
    - shop.example.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: shop-api
          port: 8080
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: shop-web
          port: 3000

Notice that Gateway and HTTPRoute live in different namespaces. This is the role-based model in action: the platform team owns infra/public-gateway, and the app team owns its routes. No cross-team bikeshedding, no conflicting annotation wars.

Canary Deployments and Traffic Splitting Without Custom Annotations

One of the biggest wins for SMBs is built-in traffic splitting. With classic Ingress, canary releases meant installing a dedicated canary ingress controller and copying vendor annotations. With Gateway API, it’s just fields on the route:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop-routes
  namespace: shop
spec:
  parentRefs:
    - name: public-gateway
      namespace: infra
  hostnames:
    - shop.example.com
  rules:
    - backendRefs:
        - name: shop-web-v2
          port: 3000
          weight: 10
        - name: shop-web
          port: 3000
          weight: 90

Here 10% of traffic goes to shop-web-v2 and 90% to the stable shop-web. When your canary passes the error budget check, bump the weight to 100 and cut over. Combined with a GitOps tool like Argo CD, this becomes a fully declarative, auditable progressive-delivery workflow that any lean DevOps team can operate.

You can also add header-based routing to send only internal testers to the canary:

    - matches:
        - headers:
            - name: x-canary
              value: "true"
      backendRefs:
        - name: shop-web-v2
          port: 3000

Moving from Ingress to Gateway API: A Migration Path

Don’t rip out your Ingress resources overnight. The cleanest migration is to run both in parallel while you progressively migrate traffic. Most mature ingress controllers (nginx-ingress, Traefik, Istio ingress, Cilium) now support the Gateway API, so you can point both at the same underlying load balancer.

A pragmatic rollout looks like this:

  1. Audit: List every Ingress resource and its routes: kubectl get ingress -A
  2. Install a Gateway API–compliant controller and create your GatewayClass + Gateway.
  3. Migrate one namespace at a time: translate each Ingress into an HTTPRoute and attach it to the new Gateway.
  4. Validate: confirm traffic flows, then delete the old Ingress resource in that namespace.
  5. Cut over DNS/load balancer when the Gateway has taken over all namespaces.

Here’s a handy one-liner to see which Ingress objects still exist so you don’t leave stragglers behind:

kubectl get ingress -A --no-headers | wc -l
kubectl get httproute -A --no-headers | wc -l

Migration is the ideal time to consolidate. If you have five separate Ingress controllers, replacing them with one Gateway-based controller immediately reduces your operational surface — a small but meaningful step in the fight against tool sprawl.

TLS, Certificates, and Real-World Gotchas

A few things trip up teams during migration:

  • Wildcard listeners conflict: Gateway validates hostnames against listener ports. If two routes on the same listener claim overlapping hostnames, the more specific match wins — but overlapping *.example.com routes can silently shadow each other. Use kubectl get httproute -A -o jsonpath='{.items[*].spec.hostnames}' to audit.
  • TLS lives on the Gateway, not the route. Certificate management moves up to the platform layer, which is actually great for SMBs — one team rotates certs centrally instead of every app team reinventing it.
  • Not every controller supports every route type. Check your controller’s supported features table before promising HTTPRoute, TCPRoute, and GRPCRoute support to your teams.

If you’re pairing this with a service mesh, Gateway API integrates tightly with the mesh’s inbound traffic handling, giving you a single, standards-based way to express both mesh ingress and east-west routing — worth reviewing before you standardize. Check out our deep dive on when a service mesh makes sense for your SMB.

Is Now the Right Time to Move?

If your cluster is small, your routing is simple, and your nginx Ingress “just works,” the Gateway API may not be urgent. But if you’re layering on canary releases, multi-tenancy, team boundaries, or multiple entry points, the migration pays for itself quickly in reduced config complexity and fewer controller-specific hacks. The Gateway API is also the path forward — Ingress is in maintenance mode, and the ecosystem is consolidating around the new standard.

Migrating your traffic layer is a perfect “safe deployment” project: it’s incremental, reversible, and you can validate every namespace independently before cutting over. If you’d like a hand planning the rollout for your cluster, our engineers can help you move safely without the all-weekend guessing game that used to be the norm for infrastructure rewrites. Book a free architecture review today and let’s get your ingress on solid, standards-based footing.

es_ESEspañol
Scroll al inicio