Skip to content
If you are interested in trying out Gloo Gateway with the Kubernetes Gateway API, check out Solo Enterprise for kgateway. This version adds enterprise functionality on top of the kgateway open source project.

Envoy API

Page as Markdown

Use the Envoy API to configure your rate limiting rules.

Before you begin

  1. Follow the Get started guide to install Gloo Gateway, set up a gateway resource, and deploy the httpbin sample app.

  2. 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_ADDRESS  
    kubectl 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.

  1. 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
    EOF
  2. Create 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
    EOF
  3. Create an HTTPRoute resource for the httpbin app that applies the RouteOption resources that you created and rate limits requests on the ratelimit.example domain.

    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
    EOF
  4. Send a few requests to the httpbin app on the ratelimit.example domain. 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: envoy

    Example 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: 0
  5. Optional: 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.

  1. 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-type request 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
    EOF
  2. Create 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
    EOF
  3. Create an HTTPRoute resource for the httpbin app that applies the RouteOption resources that you created and rate limits requests on the ratelimit.example domain.

    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
    EOF
  4. Send a few requests to the httpbin app on the ratelimit.example domain. Verify that your first request succeeds and you get back a 200 HTTP response code. Because you limited requests with an x-type request 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: envoy

    Example 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: 0
  5. Optional: 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.

  1. 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: {}
    EOF
  2. Create 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
    EOF
  3. Create an HTTPRoute resource for the httpbin app that applies the RouteOption resources that you created and rate limits requests on the ratelimit.example domain.

    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
    EOF
  4. Send a few requests to the httpbin app on the ratelimit.example domain and include the x-forwarded-for request 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: envoy

    Example 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: 0
  5. Optional: 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