- Enabling Rate Limits
- Before you begin
- Rate limits
- Conditional rate limits
- Understanding rate limits
- Cleanup
- See also
Enabling Rate Limits
This task shows you how to use Istio to dynamically limit the traffic to aservice.
Before you begin
- Setup Istio in a Kubernetes cluster by following the instructions in theInstallation Guide.
Policy enforcement must be enabled in your cluster for this task. Follow the steps inEnabling Policy Enforcement to ensure that policy enforcement is enabled.
- Deploy the Bookinfo sample application.
The Bookinfo sample deploys 3 versions of the reviews
service:
- Version v1 doesn’t call the
ratings
service. - Version v2 calls the
ratings
service, and displays each rating as 1 to 5 black stars. - Version v3 calls the
ratings
service, and displays each rating as 1 to 5 red stars.You need to set a default route to one of the versions. Otherwise, when you send requests to thereviews
service, Istio routes requests to all available versions randomly, and sometimes the output contains star ratings and sometimes it doesn’t.
- Set the default version for all services to v1.
Zip
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
Rate limits
In this task, you configure Istio to rate limit traffic to productpage
based on the IP addressof the originating client. You will use X-Forwarded-For
request header as the clientIP address. You will also use a conditional rate limit that exempts logged in users.
For convenience, you configure thememory quota(memquota
) adapter to enable rate limiting. On a production system, however,you need Redis, and you configure the Redisquota(redisquota
) adapter. Both the memquota
and redisquota
adapters supportthe quota template,so the configuration to enable rate limiting on both adapters is the same.
Rate limit configuration is split into 2 parts.
- Client Side
QuotaSpec
defines quota name and amount that the client should request.QuotaSpecBinding
conditionally associatesQuotaSpec
with one or more services.
- Mixer Side
quota instance
defines how quota is dimensioned by Mixer.memquota handler
definesmemquota
adapter configuration.quota rule
defines when quota instance is dispatched to thememquota
adapter.Run the following command to enable rate limits usingmemquota
:
- Client Side
Zip
$ kubectl apply -f @samples/bookinfo/policy/mixer-rule-productpage-ratelimit.yaml@
If you use Istio 1.1.2 or prior, please use the following configuration instead:
Zip
$ kubectl apply -f @samples/bookinfo/policy/mixer-rule-productpage-ratelimit-crd.yaml@
The memquota
handler defines 4 different rate limit schemes. The default,if no overrides match, is 500
requests per one second (1s
). Twooverrides are also defined:
- The first is
1
request (themaxAmount
field) every5s
(thevalidDuration
field), if thedestination
isreviews
. - The second is
500
requests every1s
, if the destination isproductpage
and source is10.28.11.20
- The third is
2
requests every5s
, if thedestination
isproductpage
.When a request is processed, the first matching override is picked (reading from top to bottom).
Or
Run the following command to enable rate limits using redisquota
:
Zip
$ kubectl apply -f @samples/bookinfo/policy/mixer-rule-productpage-redis-quota-rolling-window.yaml@
Note: Replace rate_limit_algorithm,redis_server_url with values for your configuration.
The redisquota
handler defines 4 different rate limit schemes. The default,if no overrides match, is 500
requests per one second (1s
). It is using ROLLING_WINDOW
algorithm for quota check and thus define bucketDuration
of 500ms for ROLLING_WINDOW
algorithm. Three overrides are also defined:
- The first is
1
request (themaxAmount
field), if thedestination
isreviews
. - The second is
500
, if the destination isproductpage
and sourceis10.28.11.20
- The third is
2
, if thedestination
isproductpage
.When a request is processed, the first matching override is picked (reading from top to bottom).
- Confirm the
quota instance
was created:
$ kubectl -n istio-system get instance requestcountquota -o yaml
The quota
template defines three dimensions that are used by memquota
or redisquota
to set overrides on requests that match certain attributes. Thedestination
will be set to the first non-empty value indestination.labels["app"]
, destination.service.host
, or "unknown"
. Formore information on expressions, see ExpressionLanguage.
- Confirm the
quota rule
was created:
$ kubectl -n istio-system get rule quota -o yaml
The rule
tells Mixer to invoke the memquota
or redisquota
handler (createdabove) and pass it the object constructed using the instancerequestcountquota
(also created above). This maps thedimensions from the quota
template to memquota
or redisquota
handler.
- Confirm the
QuotaSpec
was created:
$ kubectl -n istio-system get QuotaSpec request-count -o yaml
This QuotaSpec
defines the requestcountquota
you created above with acharge of 1
.
- Confirm the
QuotaSpecBinding
was created:
$ kubectl -n istio-system get QuotaSpecBinding request-count -o yaml
This QuotaSpecBinding
binds the QuotaSpec
you created above to theservices you want to apply it to. productpage
is explicitly bound to request-count
, notethat you must define the namespace since it differs from the namespace of the QuotaSpecBinding
.If the last line is uncommented, service: '*'
binds all services to the QuotaSpec
making the first entry redundant.
- Refresh the product page in your browser.
request-count
quota applies to productpage
and it permits 2 requestsevery 5 seconds. If you keep refreshing the page you should seeRESOURCE_EXHAUSTED:Quota is exhausted for: requestcount
.
Conditional rate limits
In the above example we have effectively rate limited productpage
at 2 rps
per client IP.Consider a scenario where you would like to exempt clients from this rate limit if a user is logged in.In the bookinfo
example, we use cookie session=<sessionid>
to denote a logged in user.In a realistic scenario you may use a jwt
token for this purpose.
You can update the quota rule
by adding a match condition based on the cookie
.
$ kubectl -n istio-system edit rules quota
...
spec:
match: match(request.headers["cookie"], "session=*") == false
actions:
...
Don’t enable chrome preload as it canpreload cookies and fail this task.
memquota
or redisquota
adapter is now dispatched only if session=<sessionid>
cookie is absent from the request.This ensures that a logged in user is not subject to this quota.
- Verify that rate limit does not apply to a logged in user.
Log in as jason
and repeatedly refresh the productpage
. Now you should be able to do this without a problem.
- Verify that rate limit does apply when not logged in.
Logout as jason
and repeatedly refresh the productpage
.You should again see RESOURCE_EXHAUSTED:Quota is exhausted for: requestcount
.
Understanding rate limits
In the preceding examples you saw how Mixer applies rate limits to requeststhat match certain conditions.
Every named quota instance like requestcount
represents a set of counters.The set is defined by a Cartesian product of all quota dimensions. If thenumber of requests in the last expiration
duration exceed maxAmount
,Mixer returns a RESOURCE_EXHAUSTED
message to the Envoy proxy, and Envoyreturns status HTTP 429
to the caller.
The memquota
adapter uses a sliding window of sub-second resolution toenforce rate limits.
The redisquota
adapter can be configured to use either the ROLLING_WINDOW
or FIXED_WINDOW
algorithms to enforce rate limits.
The maxAmount
in the adapter configuration sets the default limit for allcounters associated with a quota instance. This default limit applies if a quotaoverride does not match the request. The memquota/redisquota
adapter selects the firstoverride that matches a request. An override need not specify all quotadimensions. In the example, the 0.2 qps override is selected by matching onlythree out of four quota dimensions.
If you want the policies enforced for a given namespace instead of the entireIstio mesh, you can replace all occurrences of istio-system
with the givennamespace.
Cleanup
- If using
memquota
, remove thememquota
rate limit configuration:
Zip
$ kubectl delete -f @samples/bookinfo/policy/mixer-rule-productpage-ratelimit.yaml@
If you are using Istio 1.1.2 or prior:
Zip
$ kubectl delete -f @samples/bookinfo/policy/mixer-rule-productpage-ratelimit-crd.yaml@
Or
If using redisquota
, remove the redisquota
rate limit configuration:
Zip
$ kubectl delete -f @samples/bookinfo/policy/mixer-rule-productpage-redis-quota-rolling-window.yaml@
- Remove the application routing rules:
Zip
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
- If you are not planning to explore any follow-on tasks, refer to theBookinfo cleanup instructionsto shutdown the application.
See also
App Identity and Access Adapter
Using Istio to secure multi-cloud Kubernetes applications with zero code changes.
Mixer and the SPOF Myth
Improving availability and reducing latency.
Mixer Adapter Model
Provides an overview of Mixer's plug-in architecture.
Control Headers and Routing
Shows how to modify request headers and routing using policy adapters.
Denials and White/Black Listing
Shows how to control access to a service using simple denials or white/black listing.
Enabling Policy Enforcement
This task shows you how to enable Istio policy enforcement.