Skip to content

How-to

Gateway API

Route HTTP traffic into a BKS cluster with the Kubernetes Gateway API, using NGINX Gateway Fabric as the controller.

The Gateway API describes how traffic enters a cluster with a few resources: a GatewayClass names the controller, a Gateway listens on a port, and an HTTPRoute sends matching requests to Services. It can split traffic by weight or route by header, which the older Ingress API can't do on its own. A BKS cluster doesn't include a Gateway API controller: you install one, and keep it up to date, as part of the cluster you own.

Before you start

Install the Gateway API and the controller

Install the Gateway API resources that NGINX Gateway Fabric 2.8.0 supports, then the controller:

kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v2.8.0" | kubectl apply -f -
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric --version 2.8.0 --create-namespace -n nginx-gateway --wait

Check the controller is running and has registered its class:

kubectl get pods -n nginx-gateway
kubectl get gatewayclass

The nginx class shows ACCEPTED as True.

Create a Gateway

gateway.yaml:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: web-gateway
spec:
  gatewayClassName: nginx
  listeners:
    - name: http
      protocol: HTTP
      port: 80
kubectl apply -f gateway.yaml
kubectl get gateway web-gateway

The controller creates a LoadBalancer Service for the Gateway, web-gateway-nginx, and BKS creates a load balancer in your project for it. The Gateway's ADDRESS is that load balancer's address, and the load balancer appears under Load balancers in the Breqwatr Cloud Portal (Strata). Deleting the Gateway deletes it.

Route traffic

This route sends 80% of requests to app-v1 and 20% to app-v2, for example to try a new version on some of your traffic. Each backend is a Service in the same namespace.

route.yaml:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web-route
spec:
  parentRefs:
    - name: web-gateway
  rules:
    - backendRefs:
        - name: app-v1
          port: 8080
          weight: 80
        - name: app-v2
          port: 8080
          weight: 20
kubectl apply -f route.yaml
kubectl describe httproute web-route

Under Status, Accepted and ResolvedRefs are True once the Gateway has taken the route and found the Services.

A rule can also match requests before it routes them, for example by path or header:

  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api
          port: 8080

Check it worked

  • kubectl get gateway web-gateway shows PROGRAMMED as True, with an address.
  • Requests to the address are answered by both backends, about four times as often by app-v1:

    for i in $(seq 1 20); do curl -s http://<gateway-address>/; done
    
  • Before the address is ready, or to test from your computer, forward a local port to the Gateway's Service: kubectl port-forward svc/web-gateway-nginx 8080:80, then send requests to http://localhost:8080/.