mirror of https://github.com/istio/istio.io.git
Update ratelimit docs (#1390)
* update ratelimit docs to include QuotaSpec and QuotaSpecBinding * fix rebase issues * add inline yaml and fix destination wording * fix missing ' * Update syntax for Hugo * Fix spacing and punctuation * Fix spelling
This commit is contained in:
parent
1467145811
commit
cccf5077b6
|
@ -6,17 +6,19 @@ aliases:
|
||||||
- /docs/tasks/rate-limiting.html
|
- /docs/tasks/rate-limiting.html
|
||||||
---
|
---
|
||||||
|
|
||||||
This task shows you how to use Istio to dynamically limit the traffic to a service.
|
This task shows you how to use Istio to dynamically limit the traffic to a
|
||||||
|
service.
|
||||||
|
|
||||||
## Before you begin
|
## Before you begin
|
||||||
|
|
||||||
* Setup Istio in a Kubernetes cluster by following the quick start instructions in the
|
* Setup Istio in a Kubernetes cluster by following the quick start instructions
|
||||||
[Installation guide](/docs/setup/kubernetes/quick-start/).
|
in the [Installation guide](/docs/setup/kubernetes/quick-start/).
|
||||||
|
|
||||||
* Deploy the [Bookinfo](/docs/guides/bookinfo/) sample application.
|
* Deploy the [Bookinfo](/docs/guides/bookinfo/) sample application.
|
||||||
|
|
||||||
* Initialize the application version routing to direct `reviews` service requests from
|
* Initialize the application version routing to direct `reviews` service
|
||||||
test user "jason" to version v2 and requests from any other user to v3.
|
requests from test user "jason" to version v2 and requests from any other
|
||||||
|
user to v3.
|
||||||
|
|
||||||
```command
|
```command
|
||||||
$ istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml
|
$ istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml
|
||||||
|
@ -30,110 +32,189 @@ use `istioctl replace` instead of `istioctl create`.
|
||||||
|
|
||||||
Istio enables users to rate limit traffic to a service.
|
Istio enables users to rate limit traffic to a service.
|
||||||
|
|
||||||
Consider `ratings` as an external paid service like Rotten Tomatoes® with `1qps` free quota.
|
Consider `ratings` as an external paid service like Rotten Tomatoes® with
|
||||||
Using Istio we can ensure that `1qps` is not breached.
|
`1qps` free quota. Using Istio we can ensure that `1qps` is not breached.
|
||||||
|
|
||||||
1. Point your browser at the Bookinfo `productpage` (http://$GATEWAY_URL/productpage).
|
1. Point your browser at the Bookinfo `productpage`
|
||||||
|
(http://$GATEWAY_URL/productpage).
|
||||||
|
|
||||||
If you log in as user "jason", you should see black ratings stars with each review,
|
If you log in as user "jason", you should see black ratings stars with
|
||||||
indicating that the `ratings` service is being called by the "v2" version of the `reviews` service.
|
each review, indicating that the `ratings` service is being called by the
|
||||||
|
"v2" version of the `reviews` service.
|
||||||
|
|
||||||
If you log in as any other user (or logout) you should see red ratings stars with each review,
|
If you log in as any other user (or logout) you should see red ratings
|
||||||
indicating that the `ratings` service is being called by the "v3" version of the `reviews` service.
|
stars with each review, indicating that the `ratings` service is being
|
||||||
|
called by the "v3" version of the `reviews` service.
|
||||||
|
|
||||||
1. Configure a `memquota` adapter with rate limits.
|
1. Configure `memquota`, `quota`, `rule`, `QuotaSpec`, `QuotaSpecBinding` to
|
||||||
|
enable rate limiting.
|
||||||
Save the following YAML snippet as `ratelimit-handler.yaml`.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: config.istio.io/v1alpha2
|
|
||||||
kind: memquota
|
|
||||||
metadata:
|
|
||||||
name: handler
|
|
||||||
namespace: istio-system
|
|
||||||
spec:
|
|
||||||
quotas:
|
|
||||||
- name: requestcount.quota.istio-system
|
|
||||||
# default rate limit is 5000qps
|
|
||||||
maxAmount: 5000
|
|
||||||
validDuration: 1s
|
|
||||||
# The first matching override is applied.
|
|
||||||
# A requestcount instance is checked against override dimensions.
|
|
||||||
overrides:
|
|
||||||
# The following override applies to traffic from 'rewiews' version v2,
|
|
||||||
# destined for the ratings service. The destinationVersion dimension is ignored.
|
|
||||||
- dimensions:
|
|
||||||
destination: ratings
|
|
||||||
source: reviews
|
|
||||||
sourceVersion: v2
|
|
||||||
maxAmount: 1
|
|
||||||
validDuration: 1s
|
|
||||||
```
|
|
||||||
|
|
||||||
and then run the following command:
|
|
||||||
|
|
||||||
```command
|
```command
|
||||||
$ istioctl create -f ratelimit-handler.yaml
|
$ istioctl create -f samples/bookinfo/kube/mixer-rule-ratings-ratelimit.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
This configuration specifies a default 5000 qps rate limit. Traffic reaching the ratings service via
|
The file looks like:
|
||||||
reviews-v2 is subject to a 1qps rate limit. In our example user "jason" is routed via reviews-v2 and is therefore subject
|
{{< file_content url="https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/kube/mixer-rule-ratings-ratelimit.yaml" >}}
|
||||||
to the 1qps rate limit.
|
|
||||||
|
|
||||||
1. Configure rate limit instance and rule
|
1. Confirm the `memquota` was created:
|
||||||
|
|
||||||
Create a quota instance named `requestcount` that maps incoming attributes to quota dimensions,
|
|
||||||
and create a rule that uses it with the memquota handler.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: config.istio.io/v1alpha2
|
|
||||||
kind: quota
|
|
||||||
metadata:
|
|
||||||
name: requestcount
|
|
||||||
namespace: istio-system
|
|
||||||
spec:
|
|
||||||
dimensions:
|
|
||||||
source: source.labels["app"] | source.service | "unknown"
|
|
||||||
sourceVersion: source.labels["version"] | "unknown"
|
|
||||||
destination: destination.labels["app"] | destination.service | "unknown"
|
|
||||||
destinationVersion: destination.labels["version"] | "unknown"
|
|
||||||
---
|
|
||||||
apiVersion: config.istio.io/v1alpha2
|
|
||||||
kind: rule
|
|
||||||
metadata:
|
|
||||||
name: quota
|
|
||||||
namespace: istio-system
|
|
||||||
spec:
|
|
||||||
actions:
|
|
||||||
- handler: handler.memquota
|
|
||||||
instances:
|
|
||||||
- requestcount.quota
|
|
||||||
```
|
|
||||||
|
|
||||||
Save the configuration as `ratelimit-rule.yaml` and run the following command:
|
|
||||||
|
|
||||||
```command
|
```command
|
||||||
$ istioctl create -f ratelimit-rule.yaml
|
$ kubectl -n istio-system get memquota handler -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Generate load on the `productpage` with the following command:
|
```yaml
|
||||||
|
apiVersion: config.istio.io/v1alpha2
|
||||||
|
kind: memquota
|
||||||
|
metadata:
|
||||||
|
name: handler
|
||||||
|
namespace: istio-system
|
||||||
|
spec:
|
||||||
|
quotas:
|
||||||
|
- name: requestcount.quota.istio-system
|
||||||
|
maxAmount: 5000
|
||||||
|
validDuration: 1s
|
||||||
|
overrides:
|
||||||
|
- dimensions:
|
||||||
|
destination: ratings
|
||||||
|
source: reviews
|
||||||
|
sourceVersion: v3
|
||||||
|
maxAmount: 1
|
||||||
|
validDuration: 5s
|
||||||
|
- dimensions:
|
||||||
|
destination: ratings
|
||||||
|
maxAmount: 5
|
||||||
|
validDuration: 10s
|
||||||
|
```
|
||||||
|
|
||||||
|
The `memquota` defines 3 different rate limit schemes. The default, if no
|
||||||
|
overrides match, is `5000` requests per `1s`. Two overrides are also
|
||||||
|
defined. The first is `1` request every `5s` if the `destination` is
|
||||||
|
`ratings`, the source is `reviews`, and the `sourceVersion` is `v3`. The
|
||||||
|
second is `5` request every `10s` if the `destination` is `ratings`. The
|
||||||
|
first matching override is picked (reading from top to bottom).
|
||||||
|
|
||||||
|
1. Confirm the `quota` was created:
|
||||||
|
|
||||||
```command
|
```command
|
||||||
$ while true; do curl -s -o /dev/null http://$GATEWAY_URL/productpage; done
|
$ kubectl -n istio-system get quotas requestcount -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Refresh the `productpage` in your browser.
|
```yaml
|
||||||
|
apiVersion: config.istio.io/v1alpha2
|
||||||
|
kind: quota
|
||||||
|
metadata:
|
||||||
|
name: requestcount
|
||||||
|
namespace: istio-system
|
||||||
|
spec:
|
||||||
|
dimensions:
|
||||||
|
source: source.labels["app"] | source.service | "unknown"
|
||||||
|
sourceVersion: source.labels["version"] | "unknown"
|
||||||
|
destination: destination.labels["app"] | destination.service | "unknown"
|
||||||
|
destinationVersion: destination.labels["version"] | "unknown"
|
||||||
|
```
|
||||||
|
|
||||||
If you log in as user "jason" while the load generator is running (i.e., generating more than 1 req/s),
|
The `quota` template defines 4 `dimensions` that are used by `memquota` to
|
||||||
the traffic generated by your browser will be rate limited to 1qps.
|
set overrides on request that match certain attributes. `destination` will
|
||||||
The reviews-v2 service is unable to access the ratings service and you stop seeing stars.
|
be set to the first non-empty value in `destination.labels["app"]`,
|
||||||
For all other users the default 5000qps rate limit will apply and you will continue seeing red stars.
|
`destination.service`, or `"unknown"`. More info on expressions can be
|
||||||
|
found
|
||||||
|
[here](/docs/reference/config/policy-and-telemetry/expression-language/).
|
||||||
|
|
||||||
|
1. Confirm the `rule` was created:
|
||||||
|
|
||||||
|
```command
|
||||||
|
$ kubectl -n istio-system get rules quota -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: config.istio.io/v1alpha2
|
||||||
|
kind: rule
|
||||||
|
metadata:
|
||||||
|
name: quota
|
||||||
|
namespace: istio-system
|
||||||
|
spec:
|
||||||
|
actions:
|
||||||
|
- handler: handler.memquota
|
||||||
|
instances:
|
||||||
|
- requestcount.quota
|
||||||
|
```
|
||||||
|
|
||||||
|
The `rule` tells mixer to invoke `handler.memquota` handler (created
|
||||||
|
above) and pass it the object constructed using the instance
|
||||||
|
`requestcount.quota` (also created above). This effectively maps the
|
||||||
|
dimensions from the `quota` template to `memquota` handler.
|
||||||
|
|
||||||
|
1. Confirm the `QuotaSpec` was created:
|
||||||
|
|
||||||
|
```command
|
||||||
|
$ kubectl -n istio-system get QuotaSpec request-count -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: config.istio.io/v1alpha2
|
||||||
|
kind: QuotaSpec
|
||||||
|
metadata:
|
||||||
|
name: request-count
|
||||||
|
namespace: istio-system
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- quotas:
|
||||||
|
- charge: "1"
|
||||||
|
quota: requestcount
|
||||||
|
```
|
||||||
|
|
||||||
|
This `QuotaSpec` defines the requestcount `quota` we created above with a
|
||||||
|
charge of `1`.
|
||||||
|
|
||||||
|
1. Confirm the `QuotaSpecBinding` was created:
|
||||||
|
|
||||||
|
```command
|
||||||
|
$ kubectl -n istio-system get QuotaSpecBinding request-count -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
kind: QuotaSpecBinding
|
||||||
|
metadata:
|
||||||
|
name: request-count
|
||||||
|
namespace: istio-system
|
||||||
|
spec:
|
||||||
|
quotaSpecs:
|
||||||
|
- name: request-count
|
||||||
|
namespace: istio-system
|
||||||
|
services:
|
||||||
|
- name: ratings
|
||||||
|
namespace: default
|
||||||
|
- name: reviews
|
||||||
|
namespace: default
|
||||||
|
- name: details
|
||||||
|
namespace: default
|
||||||
|
- name: productpage
|
||||||
|
namespace: default
|
||||||
|
```
|
||||||
|
|
||||||
|
This `QuotaSpecBinding` binds the `QuotaSpec` we created above to the
|
||||||
|
services we want to apply it to. Note we have to define the namespace for
|
||||||
|
each service since it is not in the same namespace this `QuotaSpecBinding`
|
||||||
|
resource was deployed into.
|
||||||
|
|
||||||
|
1. Refresh the `productpage` in your browser.
|
||||||
|
|
||||||
|
If you are logged out, reviews-v3 service is rate limited to 1 request
|
||||||
|
every 5 seconds. If you keep refreshing the page the stars should only
|
||||||
|
load around once every 5 seconds.
|
||||||
|
|
||||||
|
If you log in as user "jason", reviews-v2 service is rate limited to 5
|
||||||
|
requests every 10 seconds. If you keep refreshing the page the stars
|
||||||
|
should only load 5 times every 10 seconds.
|
||||||
|
|
||||||
|
For all other services the default 5000qps rate limit will apply.
|
||||||
|
|
||||||
## Conditional rate limits
|
## Conditional rate limits
|
||||||
|
|
||||||
In the previous example we applied a rate limit to the `ratings` service without regard
|
In the previous example we applied a rate limit to the `ratings` service
|
||||||
to non-dimension attributes. It is possible to conditionally apply rate limits based on arbitrary
|
without regard to non-dimension attributes. It is possible to conditionally
|
||||||
attributes using a match condition in the quota rule.
|
apply rate limits based on arbitrary attributes using a match condition in
|
||||||
|
the quota rule.
|
||||||
|
|
||||||
For example, consider the following configuration:
|
For example, consider the following configuration:
|
||||||
|
|
||||||
|
@ -151,36 +232,43 @@ spec:
|
||||||
- requestcount.quota
|
- requestcount.quota
|
||||||
```
|
```
|
||||||
|
|
||||||
This configuration applies the quota rule to requests whose source and destination namespaces are different.
|
This configuration applies the quota rule to requests whose source and
|
||||||
|
destination namespaces are different.
|
||||||
|
|
||||||
## Understanding rate limits
|
## Understanding rate limits
|
||||||
|
|
||||||
In the preceding examples we saw how Mixer applies rate limits to requests that match certain conditions.
|
In the preceding examples we saw how Mixer applies rate limits to requests
|
||||||
|
that match certain conditions.
|
||||||
|
|
||||||
Every named quota instance like `requestcount` represents a set of counters.
|
Every named quota instance like `requestcount` represents a set of counters.
|
||||||
The set is defined by a Cartesian product of all quota dimensions.
|
The set is defined by a Cartesian product of all quota dimensions. If the
|
||||||
If the number of requests in the last `expiration` duration exceed `maxAmount`, Mixer returns a `RESOURCE_EXHAUSTED`
|
number of requests in the last `expiration` duration exceed `maxAmount`,
|
||||||
message to the proxy. The proxy in turn returns status `HTTP 429` to the caller.
|
Mixer returns a `RESOURCE_EXHAUSTED` message to the proxy. The proxy in turn
|
||||||
|
returns status `HTTP 429` to the caller.
|
||||||
|
|
||||||
The `memquota` adapter uses a sliding window of sub second resolution to enforce rate limits.
|
The `memquota` adapter uses a sliding window of sub second resolution to
|
||||||
|
enforce rate limits.
|
||||||
|
|
||||||
The `maxAmount` in the adapter configuration sets the default limit for all counters associated with a quota instance.
|
The `maxAmount` in the adapter configuration sets the default limit for all
|
||||||
This default limit applies if a quota override does not match the request. Memquota selects the first override that matches a request.
|
counters associated with a quota instance. This default limit applies if a
|
||||||
An override need not specify all quota dimensions. In the ratelimit-handler.yaml example, the `1qps` override is
|
quota override does not match the request. Memquota selects the first
|
||||||
selected by matching only three out of four quota dimensions.
|
override that matches a request. An override need not specify all quota
|
||||||
|
dimensions. In the example, the `0.2qps` override is selected by matching
|
||||||
|
only three out of four quota dimensions.
|
||||||
|
|
||||||
If you would like the above policies enforced for a given namespace instead of the entire Istio mesh, you can replace all occurrences of istio-system with the given namespace.
|
If you would like the above policies enforced for a given namespace instead
|
||||||
|
of the entire Istio mesh, you can replace all occurrences of istio-system
|
||||||
|
with the given namespace.
|
||||||
|
|
||||||
## Cleanup
|
## Cleanup
|
||||||
|
|
||||||
* Remove the rate limit configuration:
|
* Remove the rate limit configuration:
|
||||||
|
|
||||||
```command
|
```command
|
||||||
$ istioctl delete -f ratelimit-handler.yaml
|
$ istioctl delete -f samples/bookinfo/kube/mixer-rule-ratings-ratelimit.yaml
|
||||||
$ istioctl delete -f ratelimit-rule.yaml
|
|
||||||
```
|
```
|
||||||
|
|
||||||
* Remove the application routing rules:
|
* Remove the application routing rules:
|
||||||
|
|
||||||
```command
|
```command
|
||||||
$ istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml
|
$ istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml
|
||||||
|
@ -193,6 +281,8 @@ If you would like the above policies enforced for a given namespace instead of t
|
||||||
|
|
||||||
## What's next
|
## What's next
|
||||||
|
|
||||||
* Learn more about [Mixer](/docs/concepts/policies-and-telemetry/overview/) and [Mixer Config](/docs/concepts/policies-and-telemetry/config/).
|
* Learn more about [Mixer](/docs/concepts/policies-and-telemetry/overview/) and
|
||||||
|
[Mixer Config](/docs/concepts/policies-and-telemetry/config/).
|
||||||
|
|
||||||
* Discover the full [Attribute Vocabulary](/docs/reference/config/policy-and-telemetry/attribute-vocabulary/).
|
* Discover the full
|
||||||
|
[Attribute Vocabulary](/docs/reference/config/policy-and-telemetry/attribute-vocabulary/).
|
||||||
|
|
Loading…
Reference in New Issue