How to Set Up Kubernetes Gateway API to Replace Ingress (2026 Guide)
The Kubernetes Ingress API is being replaced by the Gateway API. Here's a complete step-by-step guide to setting it up with Nginx Gateway Fabric and migrating from Ingress.
If you've been using Kubernetes Ingress to route traffic to your services, there's something you need to know: the Kubernetes community has moved on. The Gateway API is the official successor to Ingress, and it's been Generally Available since Kubernetes 1.24.
The Ingress API isn't going away tomorrow, but the Gateway API is where all new features are being built. It solves the biggest pain points with Ingress: lack of expressiveness, no multi-tenancy, and too many custom annotations.
In this guide, you'll learn what the Gateway API is, why it's better, and how to set it up from scratch on a real cluster.
Why Replace Ingress?
Before diving into the how, let's understand the problem Ingress has.
The standard Ingress resource looks like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80Notice the annotations? Every advanced feature — canary routing, redirects, rate limiting, header manipulation — is implemented through custom annotations. These are not standardized. The nginx.ingress.kubernetes.io/ prefix tells you these only work with the NGINX Ingress Controller. Switch to Traefik or HAProxy, and your annotations change completely.
Problems with Ingress:
- Annotations chaos: no standard way to express advanced routing
- No role separation: cluster admins and app developers edit the same resource
- Limited expressiveness: can't do traffic splitting natively, no gRPC routing support
- Coupling: tied to specific controller implementations
What is the Gateway API?
The Gateway API is a collection of Kubernetes resources designed to replace Ingress. Instead of one Ingress resource, it splits responsibilities across multiple resource types:
GatewayClass → defines the controller (who handles traffic)
↓
Gateway → defines the entry point (load balancer, ports, TLS)
↓
HTTPRoute → defines routing rules (paths, headers, traffic splitting)
This separation enables role-based ownership:
- Cluster admins manage
GatewayClassandGateway— the infrastructure layer - App developers manage
HTTPRoute— their own routing rules
No more one big Ingress file that everyone on the team edits. Each team owns their routes.
Prerequisites
For this guide you need:
- A Kubernetes cluster (1.24+). If you don't have one, DigitalOcean Kubernetes is the fastest way to get one running — $12/month for a single node cluster.
kubectlconfigured and connected to your cluster- Basic familiarity with Kubernetes services and namespaces
Step 1 — Install the Gateway API CRDs
The Gateway API custom resource definitions need to be installed first. These define the new resource types (Gateway, HTTPRoute, etc.):
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yamlVerify the CRDs are installed:
kubectl get crds | grep gatewayYou should see:
gatewayclasses.gateway.networking.k8s.io
gateways.gateway.networking.k8s.io
httproutes.gateway.networking.k8s.io
referencegrants.gateway.networking.k8s.io
Step 2 — Install a Gateway Controller
The Gateway API is just a specification. You need a controller to implement it. Options include:
- NGINX Gateway Fabric — official NGINX implementation
- Cilium — eBPF-native, recommended if you're using Cilium as CNI
- Istio — if you're already using Istio
- Traefik — popular alternative
- Envoy Gateway — Envoy-based official implementation
We'll use NGINX Gateway Fabric as it's the most widely used:
# Install NGINX Gateway Fabric
kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.4.0/deploy/default/deploy.yamlVerify it's running:
kubectl get pods -n nginx-gatewayExpected output:
NAME READY STATUS RESTARTS AGE
nginx-gateway-7d8f9c46b9-xk2m9 2/2 Running 0 30s
Step 3 — Create a GatewayClass
GatewayClass tells Kubernetes which controller handles this class of gateways. NGINX Gateway Fabric creates one automatically, but here's what it looks like:
kubectl get gatewayclassNAME CONTROLLER ACCEPTED AGE
nginx gateway.nginx.org/nginx-gateway True 2m
You can also create a custom one:
# gatewayclass.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx
spec:
controllerName: gateway.nginx.org/nginx-gatewayStep 4 — Create a Gateway
The Gateway resource is the actual load balancer entry point. Cluster admins create this:
# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: main-gateway
namespace: nginx-gateway
spec:
gatewayClassName: nginx
listeners:
- name: http
protocol: HTTP
port: 80
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: tls-secret
namespace: nginx-gatewayApply it:
kubectl apply -f gateway.yamlCheck it's ready:
kubectl get gateway -n nginx-gatewayNAME CLASS ADDRESS PROGRAMMED AGE
main-gateway nginx 203.0.113.42 True 1m
The ADDRESS is your external load balancer IP. Point your DNS records here.
Step 5 — Deploy a Sample Application
Let's deploy a simple application to route traffic to:
# app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-app-svc
namespace: default
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 80kubectl apply -f app.yamlStep 6 — Create an HTTPRoute
This is where app developers work. The HTTPRoute defines routing rules:
# httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-app-route
namespace: default
spec:
parentRefs:
- name: main-gateway
namespace: nginx-gateway
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web-app-svc
port: 80Apply it:
kubectl apply -f httproute.yamlTest it:
curl -H "Host: app.example.com" http://203.0.113.42/You should see the NGINX welcome page.
Step 7 — Advanced Routing (No Annotations Needed)
This is where Gateway API really shines. Everything is native YAML — no controller-specific annotations.
Traffic splitting (canary deployments)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-route
namespace: default
spec:
parentRefs:
- name: main-gateway
namespace: nginx-gateway
hostnames:
- "app.example.com"
rules:
- backendRefs:
- name: web-app-svc # stable version (80% traffic)
port: 80
weight: 80
- name: web-app-canary-svc # canary version (20% traffic)
port: 80
weight: 20Header-based routing
rules:
- matches:
- headers:
- name: X-Beta-User
value: "true"
backendRefs:
- name: web-app-beta-svc
port: 80
- backendRefs:
- name: web-app-svc
port: 80Beta users (identified by header) go to the beta service. Everyone else goes to stable.
HTTP to HTTPS redirect
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-redirect
namespace: nginx-gateway
spec:
parentRefs:
- name: main-gateway
sectionName: http # only the HTTP listener
hostnames:
- "app.example.com"
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301Migrating from Ingress to Gateway API
If you have existing Ingress resources, migration is a phased process:
Phase 1: Install Gateway API CRDs and controller alongside existing Ingress controller.
Phase 2: Create equivalent HTTPRoutes for each Ingress resource. Run both in parallel.
Phase 3: Update DNS/load balancer to point to Gateway. Test thoroughly.
Phase 4: Remove old Ingress resources and Ingress controller.
Here's a mapping of common Ingress annotations to Gateway API equivalents:
| Ingress Annotation | Gateway API Equivalent |
|---|---|
nginx.ingress.kubernetes.io/ssl-redirect | HTTPRoute RequestRedirect filter |
nginx.ingress.kubernetes.io/canary-weight | HTTPRoute weight on backendRefs |
nginx.ingress.kubernetes.io/rewrite-target | HTTPRoute URLRewrite filter |
nginx.ingress.kubernetes.io/rate-limit | HTTPRoute with RequestCount policy |
Verify Everything is Working
# Check Gateway status
kubectl describe gateway main-gateway -n nginx-gateway
# Check HTTPRoute status
kubectl describe httproute web-app-route -n default
# Check route is attached to gateway
kubectl get httproute -AIn the HTTPRoute description, look for:
Status:
Parents:
- Conditions:
- Message: Route is accepted
Reason: Accepted
Status: True
Type: Accepted
Accepted: True means your route is working.
Summary
The Kubernetes Gateway API gives you:
- Role separation: admins control Gateways, developers control HTTPRoutes
- Native traffic splitting: no annotations, works across controllers
- Expressive routing: headers, methods, weights — all in standard YAML
- Future-proof: all Kubernetes networking innovation is here, not in Ingress
The migration path from Ingress is straightforward and you can run both in parallel during the transition.
Want to go deeper on Kubernetes networking — from CNI plugins and NetworkPolicy to the Gateway API and service meshes? KodeKloud's Kubernetes Networking course covers all of this with hands-on labs. It's the fastest way to build real fluency with how traffic actually moves in a Kubernetes cluster.
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
How to Migrate from Ingress-NGINX to Kubernetes Gateway API in 2026
Step-by-step guide to migrating from Ingress-NGINX to Kubernetes Gateway API. Includes YAML examples, implementation choices, testing strategy, and cutover plan.
What is a Service Mesh? Explained Simply (No Jargon)
Service mesh sounds complicated but the concept is simple. Here's what it actually does, why teams use it, and whether you need one — explained without the buzzwords.
Agentic Networking — How Kubernetes Is Adapting for AI Agent Traffic in 2026
AI agents are the next-gen microservices, but with unpredictable communication patterns. Learn how Kubernetes networking, Gateway API, Cilium, and eBPF are adapting for agentic traffic in 2026.