Skip to content

Commit

Permalink
Next iteration over API proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
kolodziejczak committed Jul 16, 2024
1 parent 7563782 commit 7ce0419
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 54 deletions.
28 changes: 28 additions & 0 deletions docs/contributor/adr/0007-rate-limit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Rate Limit

## Status

Draft

## Context

It has been decided to indroduce rate limit functionality into Kyma platform to allow users to set rate limit functionality on the service mesh layer, therefore allowing to consume intended service mesh functionality which is abstracting away networking concerns outside applications inside the mesh.
Since Istio is an underlying service mesh responsible for the workloads networking across Kyma clusters, therefore it is the Istio which allows to configure such functionality.
Taking that into account Goat Team is responsible to introduce this feature.
At this moment it is not possible to introduce global rate limit provided by Istio service mesh because of technical or legal limitations related to the deployment of key-value stores in the cluster.

## Decision

Taking the context part into account, it was decided to implement local rate limit as the only rate limiting posibility for now.
It is not said that the rate limit functionality will not be extended also to global rate limit in the future, therefore implemented api consider future extension with global rate limit.
It has been decided that this functionality will be exposed with another CRD in the Istio module.
Since Istio CRD is responsible for the mesh configuration mostly residing in the Istio's `meshConfig`, good decision seemed to be a creation of the new CRD.
There is no 100% certainity about introduction of global rate limit in the future, so Istio Module teamdecided to use naming RateLimit not containing local in it to not to impose that there will be also global.
Local rate limit uses buckets concept to control rate limit. To enable users to use more simplified form, except exposing Envoy's native api structure allowing for the bucket configuration, simplified form is provided allowing to use simple time units and requests allowed per given time period.
Currently the possibilites for rate limit functionality are limited to restrict number of requests, without considering any other criterias like header presence or header value.
CRD is structured in a way that allows further extensions, allowing to configure different rate limit criterias.

## Consequences

Istio Module team has to introduce another CRD with a controller loop into the module.
User has possibility to configure local rate limit in much friendler way through Istio Module abstraction, avoiding complexity of Envoy Filter, and is not exposed to the Envoy internal details, that are prone for changes.
121 changes: 121 additions & 0 deletions docs/contributor/draft/rate-limit-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Rate Limit Proposal

## Spec

| field | type | description | required |
|--------------------------------------------------|-------------|-----------------------------------------------------------------|-------------------------------|
| wokloadSelector | object | in case of empty, it's applied for the whole namespace | no |
| workloadSelector.labels | object | allows to select given workload by a selector | no |
| localRateLimit | object | allows to describe local rate limit properties | yes |
| localRateLimit.by | object | container for criteria you can limit by (for the future) | yes |
| localRateLimit.by.requests | object | allows to set rate limit based on plain number of requests | yes |
| localRateLimit.by.requests.time | object | allows to describe local rate limiting using time periods | yes (if buckets not defined) |
| localRateLimit.by.requests.buckets | object | allows to describe local rate limiting using buckets | yes (if time not defined) |
| localRateLimit.by.requests.time.unit | string | describes unit of time for rate limit | yes |
| localRateLimit.by.requests.time.requestsLimit | int |describes requests limit for a declared time unit | yes |
| localRateLimit.by.requests.buckets.maxTokens | int |describes max amount of tokens that can stack up | yes |
| localRateLimit.by.requests.buckets.tokensPerFill | int | describes how many tokens to fill every defined period of time | yes |
| localRateLimit.by.requests.buckets.fillInterval | time | describes how often fill tokens | yes |

## Usage example

```yaml
apiVersion: operator.kyma-project.io/v1alpha1
kind: RateLimit
metadata:
name: httpbin-local-rate-limit
namespace: default
spec:
workloadSelector:
labels:
app: httpbin
localRateLimit:
by:
requests:
time: # exclusive with buckets, got to choose one
unit: "second"
requestsLimit: 30
buckets:
max_tokens: 1000
tokens_per_fill: 1000
fill_interval: 1s

---

# eventually we could extend it later into such direction

apiVersion: operator.kyma-project.io/v1alpha1
kind: RateLimit
metadata:
name: default
namespace: kyma-system
spec:
workloadSelector:
labels:
app: httpbin
localRateLimit: # separating it like this allows to extend fields with new use cases. Also every field can be extended with it's specifics
requests:
time:
unit: "second"
requestsLimit: 30
buckets:
max_tokens: 1000
tokens_per_fill: 1000
fill_interval: 1s
headerPresence:
time:
unit: "second"
requestsLimit: 30
buckets:
max_tokens: 1000
tokens_per_fill: 1000
fill_interval: 1s
headerName: "some-header"
vhost: "some.v.host"
route: "/some/path"
# plus any aditional fields specific for given use case
headerValue:
time:
unit: "second"
requestsLimit: 30
buckets:
max_tokens: 1000
tokens_per_fill: 1000
fill_interval: 1s
headerName: "some-header"
headerValue: "some-value"
vhost: "some.v.host"
route: "/some/path"
clientCert:
time:
unit: "second"
requestsLimit: 30
buckets:
max_tokens: 1000
tokens_per_fill: 1000
fill_interval: 1s
etc: "etc"
globalRateLimit:
requests:
time:
unit: "second"
requestsLimit: 30
buckets:
max_tokens: 1000
tokens_per_fill: 1000
fill_interval: 1s
headerPresence:
time:
unit: "second"
requestsLimit: 30
buckets:
max_tokens: 1000
tokens_per_fill: 1000
fill_interval: 1s
headerName: "some-header"
vhost: "some.v.host"
route: "/some/path"
# plus any aditional fields specific for given use case
etc:
etc:
```
54 changes: 0 additions & 54 deletions docs/contributor/draft/rate-limit-api.yaml

This file was deleted.

0 comments on commit 7ce0419

Please sign in to comment.