The best today, the least tomorrow!
To limit traffic for microservices, follow the istio tutorial and change the following code to your own service name.
Open the current limit
- Istio is enabled by default. False indicates that istio is enabled.
kubectl -n istio-system get cm istio -o jsonpath="{@.data.mesh}" | grep disablePolicyChecks
Copy the code
- If it’s not started, just modify it
istioctl manifest apply --set values.global.disablePolicyChecks=false
Copy the code
A component of current limiting
The rate limiting configuration consists of two parts
client Side
- QuotaSpec: defines the name and number of quotas that clients should request (specify quota)
- QuotaSpecBinding: bind QuotaSpec conditionally to one or more services (bind the quota spec to the service you want to bind to). If it is service:’*’, bind all services to QuotaSpec)
Mixer Side
- Quota Instance: Define how the Mixer determines the quota (by which fields)
- Memquota Handler: Defines the memquota adapter (Adapter) configuration
- Quota rule: Defines when quota instances are scheduled to the memquota adapter (specify the corresponding instance for the handler)
- Redisquota is recommended for production systems. Both configurations are the same.
- Redis allows you to modify the redisServerUrl and rateLimitAlgorithm fields.
- Redis Quota relies on Redis Server to store quota values as a shared data store
Code sample
- Defines the above five objects:
apiVersion: config.istio.io/v1alpha2
kind: memquota
metadata:
name: handler
namespace: istio-system
spec:
quotas:
- name: requestcount.quota.istio-system
maxAmount: 500
validDuration: 1s
# The first matching override is applied.
# A requestcount instance is checked against override dimensions.
overrides:
# The following override applies to 'reviews' regardless
# of the source.
- dimensions:
destination: reviews
maxAmount: 1
validDuration: 5s
# The following override applies to 'productpage' when
# the source is a specific ip address.
- dimensions:
destination: productpage
source: "10.28.11.20"
maxAmount: 500
validDuration: 1s
# The following override applies to 'productpage' regardless
# of the source.
- dimensions:
destination: productpage
maxAmount: 2
validDuration: 5s
---
apiVersion: config.istio.io/v1alpha2
kind: quota
metadata:
name: requestcount
namespace: istio-system
spec:
dimensions:
source: request.headers["x-forwarded-for"] | "unknown"
destination: destination.labels["app"] | destination.service.name | "unknown"
destinationVersion: destination.labels["version"] | "unknown"
---
apiVersion: config.istio.io/v1alpha2
kind: QuotaSpec
metadata:
name: request-count
namespace: istio-system
spec:
rules:
- quotas:
- charge: 1
quota: requestcount
---
apiVersion: config.istio.io/v1alpha2
kind: QuotaSpecBinding
metadata:
name: request-count
namespace: istio-system
spec:
quotaSpecs:
- name: request-count
namespace: istio-system
services:
- name: productpage
namespace: default
# - service: '*' # Uncomment this to bind *all* services to request-count
---
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: quota
namespace: istio-system
spec:
# quota only applies if you are not logged in.
# match: match(request.headers["cookie"], "user=*") == false
actions:
- handler: handler.memquota
instances:
- requestcount.quota
Copy the code
Code content Interpretation
- There are 4 different speed limiting schemes in memquota:
- If none of the following matches, the default maximum is 500 requests per second
- If the target service is Reviews, a maximum of 1 request every 5s
- If the target service is ProductPage and source is 10.28.11.20, 500 requests per second
- If the target service is ProductPage, maximum 2 requests per 5s
Code run result
After the deployment is complete, refresh the productPage and display RESOURCE_EXHAUSTED:Quota is exhausted for: requestcount.
Deploy and validate the creation
The service needs to use VirtualService
kubectl apply -f mixer-ratelimit.yaml
Verify that the quota instance is created
This query is not available, but the speed limit test is also in effect
kubectl get instance requestcountquota -o yaml -n istio-system
kubectl get instance -n istio-system
Copy the code
Verify that the quota rule is created
kubectl get rule quota -o yaml -n istio-system
kubectl get rule -n istio-system
Copy the code
Verify that quotaSpec is created
kubectl get QuotaSpec request-count -o yaml -n istio-system
Copy the code
Verify that quotaSpecBinding is created
kubectl -n istio-system get QuotaSpecBinding request-count -o yaml
Copy the code
clean up
You can clean it up when you’re done testing it
kubectl delete -f mixer-ratelimit-crd.yaml
Copy the code
other
Limit the rate according to the conditions
- For example, based on cookies, ensure that logged-in users are not affected by rate limits
kubectl -n istio-system edit rules quota
...
spec:
match: match(request.headers["cookie"]."session=*") = =false
actions:
...
Copy the code
Understanding of rate limits
From the previous example, we understood how Mixer could rate limit requests based on matching conditions
- When the number of requests exceeds maxAmount within the last validDuration, the Mixer will return a RESOURCE_EXHAUSTED message to the Envoy proxy, and the Envoy will return HTTP 429 to the caller
- Memquota uses the sliding window protocol for rate limiting and can be configured as ROLLING_WINDOW or FIXED_WINDOW
- FIXED_WINDOW allows twice the peak specified rate, while scrolling Windows do not
- The ROLLING_WINDOW accuracy has been improved at the expense of Redis resource usage
The reference material
- Istio website