East-West Rate Limiting

Overview

You can use Gloo Mesh Enterprise East-West rate limiting features with Envoy's rate limit API to prevent internal traffic from overwhelming your microservices across your registered clusters. This guide makes use of the Bookinfo sample application. You can install the application by following the steps in the Bookinfo deployment section.

Gloo Mesh Enterprise includes a rate limit server based on this implementation, when you install Gloo Mesh Enterprise with meshctl or Helm. To try out Gloo Mesh Enterprise, request a trial license.

Descriptors and Actions

Rate limiting envoy descriptors define an ordered tuple of required key, optional value, and optional rate_limit fields that must be matched by the client request for the associated rate limit to be applied to the client request. You can use the Envoy rate limiting actions that are associated with the Traffic Policy destination to rate limit parts of a request that match the rate limiting descriptor keys that you define in the RateLimitServerConfig CRD.

Gloo Mesh uses these actions to rate limit parts of the request, such as the requests from a destination cluster or remote address. If you specify more than one rate limit action, the request is throttled if any of those rate limiting actions is met.

The following examples show how you configure rate limit descriptors in the RateLimitServerConfig CRD and rate limit actions in the TrafficPolicy CRD. For more information, check out the Gloo Mesh docs for envoy descriptors and actions.

Basic rate limiting examples

Let's go through a series of simple East-West rate limiting examples to understand the basic options for defining rate limiting descriptors and actions.

Setup

  1. Install Gloo Mesh Enterprise with a minimum version of 1.2 and with the rate limit feature enabled.

  2. Install the Istio Bookinfo sample application.

Generic Key

The following RateLimitServerConfig example sets up a generic_key that is used to match a corresponding generic_key action to the descriptor.

In your own setup, if using the generic_key action you can use any literal string for the value field instead of counter.

cat << EOF | kubectl apply -f -
apiVersion: networking.enterprise.mesh.gloo.solo.io/v1beta1
kind: RateLimitServerConfig
metadata:
  labels:
    app: bookinfo-policies
    app.kubernetes.io/name: bookinfo-policies
  name: rl-config
  namespace: bookinfo
spec:
  raw:
    descriptors:
      - key: generic_key
        value: counter
        rateLimit:
          requestsPerUnit: 2
          unit: MINUTE
EOF

This example defines a limit of 2 requests per minute for any request that triggers an action on the generic key called counter. Note that the namespace specified in the RateLimitServerConfig is required to be on the remote cluster for the descriptors to be applied to the remote cluster's rate limit server.

We could define that action in the following TrafficPolicy CRD to apply the previously defined rate limit to requests that call the productpage destination:

apiVersion: networking.mesh.gloo.solo.io/v1
kind: TrafficPolicy
metadata:
  labels:
    app: bookinfo-policies
    app.kubernetes.io/name: bookinfo-policies
  name: tp-ratelimit
  namespace: bookinfo
spec:
  destinationSelector:
  - kubeServiceRefs:
      services:
      - clusterName: mgmt-cluster
        name: reviews
        namespace: bookinfo
  policy:
    rateLimit:
      ratelimitServerConfigSelector:
        namespaces:
        - bookinfo
      raw:
        rateLimits:
        - actions:
          - genericKey:
              descriptorValue: counter
    rateLimitSettings: {}

In Envoy, the rate limit configuration is typically written with snake case keys (“generic_key”) in YAML. However, you must use camel case (“genericKey”) for Gloo Mesh YAML resources.

To test this rate limit, curl the productpage destination from the ratings app.

kubectl exec $(kubectl get pod -l app=ratings -A  -o jsonpath='{.items[0].metadata.name}') --namespace=bookinfo -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"

Repeat the command two more times. The first two requests succeed, but the third request meets the rate limit and returns a failure message, 429 Too Many Requests.