Skip to content

For the complete documentation index and AI-optimized content, see /llms.txt. All pages support markdown format via .md extension or Accept: text/markdown header.

HTTP Scaling with Gloo Gateway

For the complete documentation index and AI-optimized content, see /llms.txt. All pages support markdown format via .md extension or Accept: text/markdown header.

This guide demonstrates how to scale applications exposed through Gloo Gateway using the kedify-http scaler. Kedify can autowire Gloo Edge VirtualService routes, delegated RouteTable routes, and Upstream destinations. Kedify also supports Gloo Mesh/Gateway v2 networking.gloo.solo.io/v2 RouteTable resources when they point directly to a Kubernetes SERVICE or to a VIRTUAL_DESTINATION backed by the scaled Kubernetes Service.

For applications exposed through Gloo Gateway, Kedify integrates with Gloo resources using traffic autowiring:

Gloo Gateway -> VirtualService/RouteTable -> kedify-proxy -> Service -> Deployment

The kedify-proxy collects HTTP traffic metrics for the host configured on the HTTPScaledObject. Kedify then scales the target workload up or down, including scale-to-zero when no traffic is present.

When trafficAutowire: gloo is set in kedify-http trigger metadata, Kedify rewrites matching Gloo routes to a Kubernetes service destination pointing at kedify-proxy. Routes that originally point directly to a Kubernetes service and routes that point through a Gloo Upstream are both supported.

  • A running Kubernetes cluster.
  • Kedify installed with HTTP Scaler enabled.
  • Gloo Gateway installed.
  • The kubectl and helm command line utilities installed and accessible.

For a local walkthrough, install Gloo Gateway with a LoadBalancer gateway proxy:

Terminal window
kubectl create namespace gloo-system
helm repo add gloo https://storage.googleapis.com/solo-public-helm
helm repo update gloo
helm upgrade --install gloo gloo/gloo \
--version 1.21.9 \
--namespace gloo-system \
--set gatewayProxies.gatewayProxy.disableCoreDumps=true \
--set gatewayProxies.gatewayProxy.service.type=LoadBalancer \
--wait

Create a sample deployment and service:

apiVersion: apps/v1
kind: Deployment
metadata:
name: http-server
namespace: default
spec:
replicas: 0
selector:
matchLabels:
app: http-server
template:
metadata:
labels:
app: http-server
spec:
containers:
- name: http-server
image: ghcr.io/kedify/sample-http-server:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: http-server
namespace: default
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: http-server

Apply the application manifest:

Terminal window
kubectl apply -f app.yaml

You can expose the service with a direct Gloo VirtualService route:

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: http-server
namespace: default
spec:
virtualHost:
domains:
- gloo-http.keda
routes:
- matchers:
- prefix: /
routeAction:
single:
kube:
ref:
name: http-server
namespace: default
port: 8080

Kedify also supports VirtualService routes that delegate to a RouteTable:

apiVersion: gateway.solo.io/v1
kind: RouteTable
metadata:
name: http-server-routes
namespace: default
spec:
routes:
- matchers:
- prefix: /
routeAction:
single:
kube:
ref:
name: http-server
namespace: default
port: 8080

And routes that point to a Gloo Upstream:

apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: http-server-upstream
namespace: default
spec:
kube:
serviceName: http-server
serviceNamespace: default
servicePort: 8080

For Gloo Mesh/Gateway v2 native resources, Kedify supports RouteTable destinations that point directly to a Kubernetes SERVICE:

apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: http-server
namespace: default
spec:
hosts:
- gloo-http.keda
virtualGateways:
- name: ingress
namespace: global
http:
- name: http-server
matchers:
- uri:
prefix: /
forwardTo:
destinations:
- kind: SERVICE
ref:
name: http-server
namespace: default
port:
number: 8080

Kedify also supports v2 RouteTable destinations that point to a VIRTUAL_DESTINATION backed by the scaled Kubernetes Service:

apiVersion: networking.gloo.solo.io/v2
kind: VirtualDestination
metadata:
name: http-server
namespace: default
spec:
services:
- name: http-server
namespace: default
ports:
- name: http
number: 80
targetPort:
number: 8080
---
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: http-server
namespace: default
spec:
hosts:
- gloo-http.keda
virtualGateways:
- name: ingress
namespace: global
http:
- name: http-server
matchers:
- uri:
prefix: /
forwardTo:
destinations:
- kind: VIRTUAL_DESTINATION
ref:
name: http-server
namespace: default
port:
number: 80

ExternalService destinations are intentionally not rewritten because they do not identify the Kubernetes Service that Kedify scales. They can still exist in the same Gloo configuration for traffic that is not backed by the scaled workload.

Create a KEDA ScaledObject with the kedify-http trigger and Gloo traffic autowiring:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: http-server
namespace: default
spec:
maxReplicaCount: 5
minReplicaCount: 0
idleReplicaCount: 0
cooldownPeriod: 5
pollingInterval: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: http-server
triggers:
- metadata:
hosts: gloo-http.keda
pathPrefixes: /
port: "8080"
scalingMetric: requestRate
service: http-server
targetValue: "1"
trafficAutowire: gloo
window: "15s"
metricType: AverageValue
type: kedify-http
  • hosts (gloo-http.keda): The hostname configured on the Gloo VirtualService.
  • service (http-server): The Kubernetes Service associated with the application deployment.
  • port (8080): The service port to route to.
  • trafficAutowire (gloo): Enables Gloo Gateway autowiring.

Apply the resources:

Terminal window
kubectl apply -f scaling.yaml

After reconciliation, Kedify rewrites the matching Gloo route destination to kedify-proxy.

If you apply or change the Gloo route after the generated HTTPScaledObject already exists, touch the HTTPScaledObject so Kedify reconciles the new route:

Terminal window
kubectl annotate httpscaledobject http-server \
kedify.io/reconcile="$(date +%s)" --overwrite

From inside the cluster, call the Gloo gateway proxy:

Terminal window
kubectl run curl --image=curlimages/curl:8.10.1 --restart=Never -- sleep 3600
kubectl wait --for=condition=Ready pod/curl --timeout=120s
kubectl exec curl -- curl -i -H "host: gloo-http.keda" \
http://gateway-proxy.gloo-system.svc.cluster.local/

From outside the cluster, use the external address published on the Gloo gateway service:

Terminal window
GLOO_GATEWAY=$(kubectl -n gloo-system get svc gateway-proxy \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}')
curl -i -H "Host: gloo-http.keda" "http://$GLOO_GATEWAY/"

For local k3d clusters, publish the load balancer port when creating the cluster, for example:

Terminal window
k3d cluster create --port "9080:80@loadbalancer"

Then call through localhost:

Terminal window
curl -i -H "Host: gloo-http.keda" http://localhost:9080/

For existing k3d clusters with a host port mapped to a node port, expose the Gloo gateway as NodePort. For example, with 8181:31198@loadbalancer published:

Terminal window
kubectl -n gloo-system patch svc gateway-proxy --type=json \
-p='[{"op":"replace","path":"/spec/type","value":"NodePort"},{"op":"add","path":"/spec/ports/0/nodePort","value":31198}]'
curl -i -H "Host: gloo-http.keda" http://localhost:8181/

If your local cluster does not publish a load balancer port, use kubectl port-forward as a fallback:

Terminal window
kubectl -n gloo-system port-forward svc/gateway-proxy 9080:80
curl -i -H "Host: gloo-http.keda" http://localhost:9080/

The request should cold-start the application and then return an HTTP response. Verify that the deployment scaled out:

Terminal window
kubectl get deployment http-server

When traffic stops, Kedify scales the deployment back to zero after the configured cooldown period.

Explore the complete HTTP Scaler documentation for more advanced configuration, including header and path based routing, waiting pages, and proxy tuning.