Envoy API
Use the Envoy API to configure your rate limiting rules.
Before you begin
Follow the Get started guide to install Gloo Gateway, set up a gateway resource, and deploy the httpbin sample app.
Get the external address of the gateway and save it in an environment variable.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n gloo-system gloo-proxy-http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESSkubectl port-forward deployment/gloo-proxy-http -n gloo-system 8080:8080
Generic key
A generic key is a specific string literal that is used to match an action to a descriptor.
Create a RateLimitConfig to define your rate limiting rules. In the following example, you create a policy that rate limits requests to one request per minute.
kubectl apply -f - <<EOF apiVersion: ratelimit.solo.io/v1alpha1 kind: RateLimitConfig metadata: name: ratelimit-config namespace: gloo-system spec: raw: descriptors: - key: generic_key value: counter rateLimit: requestsPerUnit: 1 unit: MINUTE rateLimits: - actions: - genericKey: descriptorValue: counter EOFCreate a RouteOption resource that references the RateLimitConfig that you created.
kubectl apply -f- <<EOF apiVersion: gateway.solo.io/v1 kind: RouteOption metadata: name: ratelimit namespace: httpbin spec: options: rateLimitConfigs: refs: - name: ratelimit-config namespace: gloo-system EOFCreate an HTTPRoute resource for the httpbin app that applies the RouteOption resources that you created and rate limits requests on the
ratelimit.exampledomain.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-ratelimit namespace: httpbin spec: parentRefs: - name: http namespace: gloo-system hostnames: - ratelimit.example rules: - filters: - type: ExtensionRef extensionRef: group: gateway.solo.io kind: RouteOption name: ratelimit backendRefs: - name: httpbin port: 8000 EOFSend a few requests to the httpbin app on the
ratelimit.exampledomain. Verify that your first request succeeds and you get back a 200 HTTP response code. Because you limited requests to one request per minute, subsequent requests within the same minute fail with a 429 HTTP response code.curl -v http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: ratelimit.example:8080"curl -v localhost:8080/status/200 -H "host: ratelimit.example"Example output for a successful response:
* Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < access-control-allow-credentials: true < access-control-allow-origin: * < date: Mon, 22 Apr 2024 18:36:31 GMT < content-length: 0 < x-envoy-upstream-service-time: 0 < server: envoyExample output when rate limited:
* Mark bundle as not supporting multiuse < HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true < date: Mon, 22 Apr 2024 18:33:09 GMT < server: envoy < content-length: 0Optional: Remove the resources that you created in this guide.
kubectl delete ratelimitconfig ratelimit-config -n gloo-system kubectl delete routeoption ratelimit -n httpbin kubectl delete httproute httpbin-ratelimit -n httpbin
Request headers
Limit requests based on a specific header that is present in your request.
Create a RateLimitConfig to define your rate limiting rules. In the following example, you create a policy that rate limits requests that include an
x-typerequest header to one request per minute.kubectl apply -f - <<EOF apiVersion: ratelimit.solo.io/v1alpha1 kind: RateLimitConfig metadata: name: ratelimit-config namespace: gloo-system spec: raw: descriptors: - key: type value: rateLimit: requestsPerUnit: 1 unit: MINUTE rateLimits: - actions: - requestHeaders: descriptorKey: type headerName: x-type EOFCreate a RouteOption resource that references the RateLimitConfig that you created.
kubectl apply -f- <<EOF apiVersion: gateway.solo.io/v1 kind: RouteOption metadata: name: ratelimit namespace: httpbin spec: options: rateLimitConfigs: refs: - name: ratelimit-config namespace: gloo-system EOFCreate an HTTPRoute resource for the httpbin app that applies the RouteOption resources that you created and rate limits requests on the
ratelimit.exampledomain.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-ratelimit namespace: httpbin spec: parentRefs: - name: http namespace: gloo-system hostnames: - ratelimit.example rules: - filters: - type: ExtensionRef extensionRef: group: gateway.solo.io kind: RouteOption name: ratelimit backendRefs: - name: httpbin port: 8000 EOFSend a few requests to the httpbin app on the
ratelimit.exampledomain. Verify that your first request succeeds and you get back a 200 HTTP response code. Because you limited requests with anx-typerequest header to one request per minute, subsequent requests within the same minute fail with a 429 HTTP response code.curl -v http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: ratelimit.example:8080" -H "x-type: mytype"curl -v localhost:8080/status/200 -H "host: ratelimit.example" -H "x-type: mytype"Example output for a successful response:
* Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < access-control-allow-credentials: true < access-control-allow-origin: * < date: Mon, 22 Apr 2024 18:36:31 GMT < content-length: 0 < x-envoy-upstream-service-time: 0 < server: envoyExample output when rate limited:
* Mark bundle as not supporting multiuse < HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true < date: Mon, 22 Apr 2024 18:33:09 GMT < server: envoy < content-length: 0Optional: Remove the resources that you created in this guide.
kubectl delete ratelimitconfig ratelimit-config -n gloo-system kubectl delete routeoption ratelimit -n httpbin kubectl delete httproute httpbin-ratelimit -n httpbin
Remote Address
Limit requests based on the remote address that sends the request. The remote address is populated from the x-forwarded-for request header.
Create a RateLimitConfig to define your rate limiting rules. In the following example, you create a policy that rate limits requests based on the remote address to one request per minute.
kubectl apply -f - <<EOF apiVersion: ratelimit.solo.io/v1alpha1 kind: RateLimitConfig metadata: name: ratelimit-config namespace: gloo-system spec: raw: descriptors: - key: remote_address value: rateLimit: requestsPerUnit: 1 unit: MINUTE rateLimits: - actions: - remoteAddress: {} EOFCreate a RouteOption resource that references the RateLimitConfig that you created.
kubectl apply -f- <<EOF apiVersion: gateway.solo.io/v1 kind: RouteOption metadata: name: ratelimit namespace: httpbin spec: options: rateLimitConfigs: refs: - name: ratelimit-config namespace: gloo-system EOFCreate an HTTPRoute resource for the httpbin app that applies the RouteOption resources that you created and rate limits requests on the
ratelimit.exampledomain.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-ratelimit namespace: httpbin spec: parentRefs: - name: http namespace: gloo-system hostnames: - ratelimit.example rules: - filters: - type: ExtensionRef extensionRef: group: gateway.solo.io kind: RouteOption name: ratelimit backendRefs: - name: httpbin port: 8000 EOFSend a few requests to the httpbin app on the
ratelimit.exampledomain and include thex-forwarded-forrequest header. Verify that your first request succeeds and you get back a 200 HTTP response code. Because you limited requests from a specific remote address to one request per minute, subsequent requests within the same minute fail with a 429 HTTP response code.curl -v http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: ratelimit.example:8080" -H "x-forwaded-for: my-remote-address.com"curl -v localhost:8080/status/200 -H "host: ratelimit.example" -H "x-forwaded-for: my-remote-address.com"Example output for a successful response:
* Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < access-control-allow-credentials: true < access-control-allow-origin: * < date: Mon, 22 Apr 2024 18:36:31 GMT < content-length: 0 < x-envoy-upstream-service-time: 0 < server: envoyExample output when rate limited:
* Mark bundle as not supporting multiuse < HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true < date: Mon, 22 Apr 2024 18:33:09 GMT < server: envoy < content-length: 0Optional: Remove the resources that you created in this guide.
kubectl delete ratelimitconfig ratelimit-config -n gloo-system kubectl delete routeoption ratelimit -n httpbin kubectl delete httproute httpbin-ratelimit -n httpbin