GKE Gateway API with Path-Based Routing¶
This tutorial shows you how to use the Kubernetes Gateway API in a GKE cluster to provision a Regional External HTTP Load Balancer and configure path-based routing across two microservices.
The Gateway API is the modern successor to Kubernetes Ingress. It provides richer routing semantics and a cleaner separation of concerns between infrastructure and application owners.
Prerequisite: GKE Cluster Already Provisioned
For this tutorial, we assume a GKE cluster is already provisioned. If you haven't created one yet, follow one of these guides first:
What is the Kubernetes Gateway API?¶
The Gateway API is a collection of resources (GatewayClass, Gateway, HTTPRoute) that model service networking in Kubernetes. Compared to Ingress:
| Feature | Ingress | Gateway API |
|---|---|---|
| Role separation | Single resource | Infra (Gateway) vs. App (HTTPRoute) |
| Path matching | Limited | Rich (prefix, exact, regex) |
| Traffic weighting | Not native | Native |
| TLS | Basic | Full lifecycle management |
| Extensibility | Annotations | Typed policy objects |
In GKE, the gke-l7-regional-external-managed GatewayClass provisions a Regional External Application Load Balancer backed by Google Cloud's L7 infrastructure.
Architecture¶
Internet โ Regional External LB โ Gateway
โโโ /api/orders โ orders-service (port 8080)
โโโ /api/products โ products-service (port 8080)
Step 1: Set Environment Variables¶
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export CLUSTER_NAME=my-private-autopilot # or my-private-standard
Step 2: Enable Gateway API on the Cluster¶
The Gateway API is enabled by default on new GKE clusters. Verify the GatewayClasses are available:
kubectl get gatewayclass
You should see GatewayClasses including gke-l7-regional-external-managed.
Enable Gateway API on an Existing Cluster
If the GatewayClasses are not present, enable the Gateway API on your cluster:
gcloud container clusters update $CLUSTER_NAME \
--gateway-api=standard \
--region=$REGION
Step 3: Deploy the Microservices¶
We will deploy two microservices using Google's official sample images hosted on us-docker.pkg.dev/google-samples/. These images are accessible directly from private GKE clusters without any additional Artifact Registry configuration.
About google-samples Images
us-docker.pkg.dev/google-samples/containers/gke/hello-app is an official GCP demo app that responds with its version number. Using 1.0 and 2.0 makes it immediately obvious which service handled each request.
-
Deploy the
ordersservice (hello-app v1.0):kubectl create deployment orders \ --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 \ --port=8080 kubectl expose deployment orders --port=8080 --target-port=8080 -
Deploy the
productsservice (hello-app v2.0):kubectl create deployment products \ --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0 \ --port=8080 kubectl expose deployment products --port=8080 --target-port=8080 -
Verify the pods are running:
kubectl get podsWait until both pods are in
Runningstate.
Step 4: Create the Gateway¶
Create a Gateway resource that provisions a Regional External Load Balancer.
cat <<EOF | kubectl apply -f -
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: external-gateway
namespace: default
spec:
gatewayClassName: gke-l7-regional-external-managed
listeners:
- name: http
protocol: HTTP
port: 80
EOF
Wait for the Gateway to get an external IP (this may take a few minutes):
kubectl get gateway external-gateway --watch
Once the ADDRESS is populated, note the IP:
export GATEWAY_IP=$(kubectl get gateway external-gateway \
-o jsonpath='{.status.addresses[0].value}')
echo "Gateway IP: $GATEWAY_IP"
Step 5: Create the HTTPRoute with Path-Based Routing¶
Create an HTTPRoute that routes traffic based on the URL path:
/api/ordersโordersService/api/productsโproductsService
cat <<EOF | kubectl apply -f -
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: microservices-route
namespace: default
spec:
parentRefs:
- name: external-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api/orders
backendRefs:
- name: orders
port: 8080
- matches:
- path:
type: PathPrefix
value: /api/products
backendRefs:
- name: products
port: 8080
EOF
Step 6: Verify Path-Based Routing¶
Test that requests reach the correct microservice based on the path:
-
Test the
ordersroute:curl http://${GATEWAY_IP}/api/ordersExpected output:
Hello, world! Version: 1.0.0 Hostname: orders-xxxxxxxxx-xxxxx -
Test the
productsroute:curl http://${GATEWAY_IP}/api/productsExpected output:
Hello, world! Version: 2.0.0 Hostname: products-xxxxxxxxx-xxxxxThe different version numbers (
1.0.0vs2.0.0) confirm each path is hitting the correct backend service.
Propagation Time
It may take 2โ5 minutes for the load balancer rules to fully propagate after creating the HTTPRoute. If you get a 404 immediately, wait a moment and retry.
Cleanup¶
kubectl delete httproute microservices-route
kubectl delete gateway external-gateway
kubectl delete service orders products
kubectl delete deployment orders products
Quiz¶
Which Kubernetes resource defines the routing rules (e.g., path-based routing) in the Gateway API?
Which GatewayClass provisions a Regional External Application Load Balancer in GKE?
๐ฌ DevopsPilot Weekly โ Learn DevOps, Cloud & Gen AI the simple way.
๐ Subscribe here