Skip to content

Latest commit

 

History

History
326 lines (248 loc) · 8.02 KB

File metadata and controls

326 lines (248 loc) · 8.02 KB

Kubernetes Gateway API 101

The Kubernetes Gateway API is the next-generation traffic management API for Kubernetes, designed to be a more expressive, extensible, and role-oriented successor to the Ingress API. It is a standard part of the Kubernetes ecosystem (maintained by the SIG-Network community) and is now the recommended way to expose HTTP, HTTPS, and TCP services in Kubernetes.

What You Will Learn

  • What the Gateway API is and how it differs from Ingress
  • Core resources: GatewayClass, Gateway, and HTTPRoute
  • How to install a Gateway API-compatible controller
  • How to expose a service using the Gateway API
  • Advanced routing: path-based, header-based, and traffic splitting

Why Gateway API Over Ingress?

Feature Ingress Gateway API
Role separation Single resource GatewayClass (infra), Gateway (operator), HTTPRoute (developer)
Multiple protocols HTTP/HTTPS only HTTP, HTTPS, TCP, TLS, UDP
Traffic splitting Vendor annotation Native weight-based routing
Header/path matching Limited Rich, expressive matching
Cross-namespace routing Not supported Supported via ReferenceGrant
Extensibility Vendor annotations Typed extension points

Core Resources

1. GatewayClass

A GatewayClass defines the type of load balancer infrastructure to provision. It is cluster-scoped and managed by infrastructure providers (similar to StorageClass).

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

2. Gateway

A Gateway represents an instance of a load balancer. It is managed by cluster operators and specifies listeners (ports and protocols).

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

3. HTTPRoute

An HTTPRoute defines how HTTP traffic reaching the Gateway is routed to backend services. Developers manage this resource to define application-level routing rules.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: my-app-route
  namespace: default
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - "myapp.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: my-service
          port: 8080

Lab 1: Installing the Gateway API CRDs

The Gateway API CRDs must be installed before any controller. Run the following to install the latest stable CRDs:

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

Verify the CRDs are installed:

kubectl get crd gateways.gateway.networking.k8s.io \
               gatewayclasses.gateway.networking.k8s.io \
               httproutes.gateway.networking.k8s.io

Expected output:

NAME                                        CREATED AT
gateways.gateway.networking.k8s.io         2024-01-01T00:00:00Z
gatewayclasses.gateway.networking.k8s.io   2024-01-01T00:00:00Z
httproutes.gateway.networking.k8s.io       2024-01-01T00:00:00Z

Lab 2: Installing NGINX Gateway Fabric (Controller)

We will use NGINX Gateway Fabric as our Gateway API controller. It is a CNCF-certified implementation.

# Install NGINX Gateway Fabric
kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.3.0/deploy/crds.yaml
kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.3.0/deploy/default/deploy.yaml

Verify the controller is running:

kubectl get pods -n nginx-gateway

Expected output:

NAME                             READY   STATUS    RESTARTS   AGE
nginx-gateway-5d4f7b9c8d-xklt2  2/2     Running   0          30s

Lab 3: Deploy a Sample Application

Apply the sample Deployment and Service:

kubectl apply -f https://raw.githubusercontent.com/collabnix/kubelabs/master/Gateway101/demo-app.yaml

Or create them manually:

kubectl create deployment demo --image=httpd:alpine --port=80
kubectl expose deployment demo --port=80

Lab 4: Create the GatewayClass and Gateway

Apply the GatewayClass and Gateway manifests:

kubectl apply -f https://raw.githubusercontent.com/collabnix/kubelabs/master/Gateway101/gateway.yaml

Check the Gateway status:

kubectl get gateway my-gateway

Expected output:

NAME         CLASS   ADDRESS        PROGRAMMED   AGE
my-gateway   nginx   192.168.1.10   True         60s

The PROGRAMMED: True status means the Gateway is ready to route traffic.


Lab 5: Create an HTTPRoute

Apply the HTTPRoute manifest:

kubectl apply -f https://raw.githubusercontent.com/collabnix/kubelabs/master/Gateway101/http-route.yaml

Check the HTTPRoute status:

kubectl get httproute demo-route

Test the route using the Gateway address:

GATEWAY_IP=$(kubectl get gateway my-gateway -o jsonpath='{.status.addresses[0].value}')
curl http://$GATEWAY_IP/ -H "Host: demo.example.com"

Expected output:

<html><body><h1>It works!</h1></body></html>

Lab 6: Advanced Routing — Path-Based Routing

The Gateway API supports rich routing rules. This example routes /api to one service and /web to another:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: path-based-route
  namespace: default
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - "myapp.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api-service
          port: 8080
    - matches:
        - path:
            type: PathPrefix
            value: /web
      backendRefs:
        - name: web-service
          port: 80

Lab 7: Traffic Splitting (Canary / Blue-Green)

The Gateway API natively supports weight-based traffic splitting, making canary deployments easy without any vendor annotations:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: canary-route
  namespace: default
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - "myapp.example.com"
  rules:
    - backendRefs:
        - name: my-app-stable
          port: 80
          weight: 90
        - name: my-app-canary
          port: 80
          weight: 10

This sends 90% of traffic to the stable version and 10% to the canary.


Lab 8: Header-Based Routing

Route requests to a specific backend based on request headers (useful for A/B testing):

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: header-route
  namespace: default
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - "myapp.example.com"
  rules:
    - matches:
        - headers:
            - name: X-User-Group
              value: beta-testers
      backendRefs:
        - name: my-app-beta
          port: 80
    - backendRefs:
        - name: my-app-stable
          port: 80

Cleaning Up

Remove all Gateway API resources created in this tutorial:

kubectl delete httproute demo-route path-based-route canary-route header-route --ignore-not-found
kubectl delete gateway my-gateway --ignore-not-found
kubectl delete gatewayclass nginx --ignore-not-found
kubectl delete deployment demo --ignore-not-found
kubectl delete service demo --ignore-not-found

Further Reading