Kubernetes Istio Envoy - Rate Limiting by HTTP Method

1/4/2022

We are using Istio Envoy based Rate limiting (with Kubernetes & Docker) as specified in this documentation.

Although I was able to set it up for local and global rate limiting in the Kubernetes cluster, I am unable to achieve the following:

  1. Rate limit a Service only for POST requests, while GET requests should go through unencumbered.

  2. Rate limit a Service only for a certain time duration (e.g. 9 AM to 5 PM EST) and work normally at other times.

Is the above possible in current Istio functionalities?

-- Sid
istio
kubernetes
rate-limiting

1 Answer

1/11/2022

I will try to answer both of your questions below.

1. Rate limit a Service only for a specific request method

We can use the header_value_match rate limit actions.

I created a single rate_limits filter with one action that matches any request with method GET:
NOTE: For the sake of simplicity, I have only given an important part of the configuration.

Envoy rate_limits filter configuration:

...
        value:
          rate_limits:
            - actions:
              - header_value_match:
                  descriptor_value: get
                  headers:
                  - name: :method
                    prefix_match: GET
...

Next, I created a ratelimit service configuration that matches descriptors with key header_match and value get. It will provide a limit of 1 request per minute:

...
    descriptors:
      - key: header_match
        rate_limit:
          unit: minute
          requests_per_unit: 1
        value: get
...

After applying the above configuration, we can check whether it will be possible to use the GET method more than once within 1 minute:

$ curl "http://$GATEWAY_URL/productpage" -I -X GET
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 5179
server: istio-envoy
date: Tue, 11 Jan 2022 09:57:33 GMT
x-envoy-upstream-service-time: 120


$ curl "http://$GATEWAY_URL/productpage" -I -X GET
HTTP/1.1 429 Too Many Requests
x-envoy-ratelimited: true
date: Tue, 11 Jan 2022 09:57:35 GMT
server: istio-envoy
content-length: 0

As we can see, after the second request, we received the HTTP 429 Too Many Requests response status code which indicates that the user has sent too many requests in a given amount of time. It means that everything works as expected.

I recommend you to read the Understanding Envoy Rate Limits article which contains a lot of useful information.

2. Rate limit a Service only for a certain time duration (e.g. 9 AM to 5 PM EST) and work normally at other times.

Unfortunately, I cannot find any suitable option to configure this behavior. I think that CronJob can be used as a workaround, which will run periodically on a given schedule and will create/delete the appropriate configuration responsible for rate-limiting. In short, you can use a Bash script that creates/deletes a configuration responsible for rate-limiting and then you can mount that script in a volume to the CronJob Pod. I have already described a similar use of CronJob here and believe it can help you.

-- matt_j
Source: StackOverflow