From 12dfd1713fffdc4394fb32a13246c5301bfccf7e Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Mon, 6 Feb 2023 13:37:49 -0800 Subject: [PATCH 1/6] user docs for global rate limit Signed-off-by: Arko Dasgupta --- docs/latest/user/rate-limit.md | 203 +++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 docs/latest/user/rate-limit.md diff --git a/docs/latest/user/rate-limit.md b/docs/latest/user/rate-limit.md new file mode 100644 index 0000000000..3c6b069894 --- /dev/null +++ b/docs/latest/user/rate-limit.md @@ -0,0 +1,203 @@ +# Rate limit + +Rate limit is a feature that allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. + +Here are some reasons why you may want to implements Rate limits + +* To prevent malicious activity such as DDoS attacks. +* To prevent applications and its resources (such as a database) from getting overloaded. +* To create API limits based on user entitlements. + +Envoy Gateway supports [Global rate limiting][], where the rate limit is common across all the instances of Envoy proxies where its applied +i.e. if the data plane has 2 replicas of Envoy running, and the rate limit is 10 requests/second, this limit is common and will be hit +if 5 requests pass through the first replica and 5 requests pass through the second replica within the same second. + +Envoy Gateway introduces a new CRD called [RateLimitFilter][] that allows the user to describe their rate limit intent. This instantiated resource +can be linked to a [HTTPRoute][] resource using an [ExtensionRef][] filter. + +## Prerequisites + +### Install Envoy Gateway + +* Follow the steps from the [Quickstart Guide](quickstart.md) to install Envoy Gateway and the example manifest. +Before proceeding, you should be able to query the example backend using HTTP. + +### Install Redis + +* The global rate limit feature is based on [Envoy Ratelimit][] which requires a Redis instance as its caching layer. +Lets install a Redis deployment in the `redis-system` namespce. + +```shell +cat < Date: Tue, 7 Feb 2023 17:51:28 -0800 Subject: [PATCH 2/6] lint Signed-off-by: Arko Dasgupta --- docs/latest/user/rate-limit.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/latest/user/rate-limit.md b/docs/latest/user/rate-limit.md index 3c6b069894..708625a8be 100644 --- a/docs/latest/user/rate-limit.md +++ b/docs/latest/user/rate-limit.md @@ -29,7 +29,6 @@ Lets install a Redis deployment in the `redis-system` namespce. ```shell cat < Date: Tue, 7 Feb 2023 18:00:19 -0800 Subject: [PATCH 3/6] more lint Signed-off-by: Arko Dasgupta --- docs/latest/user/rate-limit.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/latest/user/rate-limit.md b/docs/latest/user/rate-limit.md index 708625a8be..48dd5d576e 100644 --- a/docs/latest/user/rate-limit.md +++ b/docs/latest/user/rate-limit.md @@ -203,6 +203,3 @@ for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user- [EnvoyGateway]: https://github.com/envoyproxy/gateway/blob/main/api/config/v1alpha1/envoygateway_types.go [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/ [ExtensionRef]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io%2fv1beta1.HTTPRouteFilter -[HTTPRoute filters]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteFilter -[Gateway API documentation]: https://gateway-api.sigs.k8s.io/ -[req_filter]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPHeaderFilter From a397811509613ba978daff47ec95fccdd83093eb Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Tue, 7 Feb 2023 18:45:14 -0800 Subject: [PATCH 4/6] add another example Signed-off-by: Arko Dasgupta --- docs/latest/user/rate-limit.md | 201 +++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) diff --git a/docs/latest/user/rate-limit.md b/docs/latest/user/rate-limit.md index 48dd5d576e..44f91f27d2 100644 --- a/docs/latest/user/rate-limit.md +++ b/docs/latest/user/rate-limit.md @@ -191,12 +191,213 @@ and value `one`. for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: one" http://${GATEWAY_HOST}/get ; sleep 1; done ``` +```console +HTTP/1.1 200 OK +content-type: application/json +x-content-type-options: nosniff +date: Wed, 08 Feb 2023 02:33:31 GMT +content-length: 460 +x-envoy-upstream-service-time: 4 +server: envoy + +HTTP/1.1 200 OK +content-type: application/json +x-content-type-options: nosniff +date: Wed, 08 Feb 2023 02:33:32 GMT +content-length: 460 +x-envoy-upstream-service-time: 2 +server: envoy + +HTTP/1.1 200 OK +content-type: application/json +x-content-type-options: nosniff +date: Wed, 08 Feb 2023 02:33:33 GMT +content-length: 460 +x-envoy-upstream-service-time: 0 +server: envoy + +HTTP/1.1 429 Too Many Requests +x-envoy-ratelimited: true +date: Wed, 08 Feb 2023 02:33:34 GMT +server: envoy +transfer-encoding: chunked + +``` + You should be able to send requests with the `x-user-id` header and a different value and receive successful responses from the server. ```shell for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: two" http://${GATEWAY_HOST}/get ; sleep 1; done ``` +```console +HTTP/1.1 200 OK +content-type: application/json +x-content-type-options: nosniff +date: Wed, 08 Feb 2023 02:34:36 GMT +content-length: 460 +x-envoy-upstream-service-time: 0 +server: envoy + +HTTP/1.1 200 OK +content-type: application/json +x-content-type-options: nosniff +date: Wed, 08 Feb 2023 02:34:37 GMT +content-length: 460 +x-envoy-upstream-service-time: 0 +server: envoy + +HTTP/1.1 200 OK +content-type: application/json +x-content-type-options: nosniff +date: Wed, 08 Feb 2023 02:34:38 GMT +content-length: 460 +x-envoy-upstream-service-time: 0 +server: envoy + +HTTP/1.1 200 OK +content-type: application/json +x-content-type-options: nosniff +date: Wed, 08 Feb 2023 02:34:39 GMT +content-length: 460 +x-envoy-upstream-service-time: 0 +server: envoy + +``` + +## Rate limit distinct users + +Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differntiated based on the +value in the `x-user-id` header. Here, user `one` (recognised from the traffic flow using the header `x-user-id` and value `one`) will be rate limited at 3 requests/hour +and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`). + +```shell +cat < Date: Tue, 7 Feb 2023 19:00:19 -0800 Subject: [PATCH 5/6] lint Signed-off-by: Arko Dasgupta --- docs/latest/user/rate-limit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/latest/user/rate-limit.md b/docs/latest/user/rate-limit.md index 44f91f27d2..e8b637e6bb 100644 --- a/docs/latest/user/rate-limit.md +++ b/docs/latest/user/rate-limit.md @@ -267,7 +267,7 @@ server: envoy ## Rate limit distinct users -Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differntiated based on the +Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differentiated based on the value in the `x-user-id` header. Here, user `one` (recognised from the traffic flow using the header `x-user-id` and value `one`) will be rate limited at 3 requests/hour and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`). From c53549e4ccc62871f651236ed4bc9787bf3a77ef Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Tue, 7 Feb 2023 19:17:49 -0800 Subject: [PATCH 6/6] more examples Signed-off-by: Arko Dasgupta --- docs/latest/user/rate-limit.md | 83 ++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/docs/latest/user/rate-limit.md b/docs/latest/user/rate-limit.md index e8b637e6bb..7556425318 100644 --- a/docs/latest/user/rate-limit.md +++ b/docs/latest/user/rate-limit.md @@ -397,6 +397,89 @@ transfer-encoding: chunked ``` +## Rate limit all requests + +This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset. + +```shell +cat <