Skip to content

Gateway API

The Kubernetes Gateway API is a set of custom resources for managing ingress and traffic routing. It is a more expressive and extensible alternative to the Ingress API, supporting advanced features such as weighted traffic splitting and header-based routing.

Prerequisites

Before proceeding, make sure you have a running Kubernetes cluster. See one of the following guides depending on your setup:

Install the Gateway API CRDs

Install the standard Gateway API custom resource definitions:

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yaml

Expected output:

customresourcedefinition.apiextensions.k8s.io/backendtlspolicies.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/listenersets.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/tlsroutes.gateway.networking.k8s.io created
validatingadmissionpolicy.admissionregistration.k8s.io/safe-upgrades.gateway.networking.k8s.io created
validatingadmissionpolicybinding.admissionregistration.k8s.io/safe-upgrades.gateway.networking.k8s.io created

Verify the CRDs were installed:

kubectl get crd | grep gateway

Expected output:

backendtlspolicies.gateway.networking.k8s.io            2026-05-05T17:22:12Z
gatewayclasses.gateway.networking.k8s.io                2026-05-05T17:22:12Z
gateways.gateway.networking.k8s.io                      2026-05-05T17:22:12Z
grpcroutes.gateway.networking.k8s.io                    2026-05-05T17:22:13Z
httproutes.gateway.networking.k8s.io                    2026-05-05T17:22:13Z
listenersets.gateway.networking.k8s.io                  2026-05-05T17:22:13Z
referencegrants.gateway.networking.k8s.io               2026-05-05T17:22:14Z
tlsroutes.gateway.networking.k8s.io                     2026-05-05T17:22:14Z

Install the Nginx Gateway Fabric

Install the Nginx Gateway Fabric controller, which implements the Gateway API using Nginx:

helm install nginx-gateway-fabric oci://ghcr.io/nginx/charts/nginx-gateway-fabric --create-namespace -n nginx-gateway

Verify all resources are running:

kubectl get all -n nginx-gateway

Expected output:

NAME                                            READY   STATUS      RESTARTS   AGE
pod/nginx-gateway-fabric-5869bf65f9-mvbz7       1/1     Running     0          13s
pod/nginx-gateway-fabric-cert-generator-gz425   0/1     Completed   0          19s

NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/nginx-gateway-fabric   ClusterIP   10.254.31.204   <none>        443/TCP   14s

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-gateway-fabric   1/1     1            1           13s

NAME                                              DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-gateway-fabric-5869bf65f9   1         1         1       13s

NAME                                            STATUS     COMPLETIONS   DURATION   AGE
job.batch/nginx-gateway-fabric-cert-generator   Complete   1/1           5s         20s

Verify the nginx GatewayClass was registered:

kubectl get gatewayclass

Expected output:

NAME    CONTROLLER                                   ACCEPTED   AGE
nginx   gateway.nginx.org/nginx-gateway-controller   True       64s

Create a Gateway

Create a Gateway resource that listens for HTTP traffic on port 80:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: inference-gateway
  namespace: default
spec:
  gatewayClassName: nginx
  listeners:
  - name: http
    protocol: HTTP
    port: 80

Verify the Gateway was created and has been assigned an address:

kubectl get gateway

Expected output:

NAME                CLASS   ADDRESS       PROGRAMMED   AGE
inference-gateway   nginx   10.106.0.88   True         2m33s

The Gateway controller automatically creates a LoadBalancer service to expose the gateway. Verify it was created:

kubectl get svc

Expected output:

NAME                      TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
inference-gateway-nginx   LoadBalancer   10.254.149.97   10.106.0.88   80:31156/TCP   2m57s
kubernetes                ClusterIP      10.254.0.1      <none>        443/TCP        23h

Create an HTTPRoute

HTTPRoutes define how traffic is routed to backend services. The example below demonstrates weighted traffic splitting between two model services, routing 80% of requests to model-v1 and 20% to model-v2 when the content-type: application/json header is present.

First, create the backend services:

apiVersion: v1
kind: Service
metadata:
  name: model-v1
  namespace: default
spec:
  selector:
    app: model-v1
  ports:
  - port: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: model-v2
  namespace: default
spec:
  selector:
    app: model-v2
  ports:
  - port: 8080

Then create the HTTPRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: inference-route
  namespace: default
spec:
  parentRefs:
  - name: inference-gateway
  rules:
  - matches:
    - headers:
      - name: "content-type"
        value: "application/json"
    backendRefs:
    - name: model-v1
      port: 8080
      weight: 80
    - name: model-v2
      port: 8080
      weight: 20

Verify the route was created:

kubectl get httproute

Expected output:

NAME              HOSTNAMES   AGE
inference-route               56s

Check the route status to confirm it has been accepted by the gateway controller:

kubectl describe httproute inference-route

Expected output:

Name:         inference-route
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  gateway.networking.k8s.io/v1
Kind:         HTTPRoute
Metadata:
  Creation Timestamp:  2026-05-05T18:42:14Z
  Generation:          1
  Resource Version:    308640
  UID:                 b300a5d1-ad4f-4208-b6f7-966763e175ba
Spec:
  Parent Refs:
    Group:  gateway.networking.k8s.io
    Kind:   Gateway
    Name:   inference-gateway
  Rules:
    Backend Refs:
      Group:
      Kind:    Service
      Name:    model-v1
      Port:    8080
      Weight:  80
      Group:
      Kind:    Service
      Name:    model-v2
      Port:    8080
      Weight:  20
    Matches:
      Headers:
        Name:   content-type
        Type:   Exact
        Value:  application/json
      Path:
        Type:   PathPrefix
        Value:  /
Status:
  Parents:
    Conditions:
      Last Transition Time:  2026-05-05T18:42:14Z
      Message:               The Route is accepted
      Observed Generation:   1
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2026-05-05T18:42:14Z
      Message:               All references are resolved
      Observed Generation:   1
      Reason:                ResolvedRefs
      Status:                True
      Type:                  ResolvedRefs
    Controller Name:         gateway.nginx.org/nginx-gateway-controller
    Parent Ref:
      Group:         gateway.networking.k8s.io
      Kind:          Gateway
      Name:          inference-gateway
      Namespace:     default
      Section Name:  http
Events:              <none>