Istio官方文档:
https://istio.io/docs/tasks/policy-enforcement/rate-limiting/
https://istio.io/docs/tasks/policy-enforcement/enabling-policy/
在进行rateLimits测试开始之前,需要先确保 Enabling Policy Enforcement(开启Mixer策略检查),官方文档提供两种方法:
(1)在初始安装Istio(helm):
使用选项
helm template install/kubernetes/helm/istio --name istio --namespace istio-system --set global.disablePolicyChecks=false| kubectl apply -f -
(2)Istio网格已经存在:
执行如下命令
helm template install/kubernetes/helm/istio --namespace=istio-system -x templates/configmap.yaml --set global.disablePolicyChecks=false | kubectl -n istio-system replace -f -
由于之前Istio已经安装完成,故使用了方法(2),执行完上述命令后,与官方描述效果一样,如下图:
但是之后在测试rateLimits相关测试时,发现限流一直没有生效,最后在查看istio-system命名空间下istio-policy-xxx-xxx容器日志时发现如下报错:
warn 'requestcountquota': warn Requested quota 'requestcountquota' is not configured
说明quota配置没有生效,之后又去查看了istio安装包下的配置文件(istio-1.1.7/install/kubernetes/helm/istio
/values.yaml)说明:
官方安装选项说明:https://istio.io/docs/reference/config/installation-options/
在values.yaml中disablePolicyChecks上方的注释中,强调了修改disablePolicyChecks的值需要重启pilot,故又去重启了istio-pilot(副本数先设置为0,之后再恢复到1),重启后仍是报之前的“ 'requestcountquota': warn Requested quota 'requestcountquota' is not configured”的错误,既然policy总是报错,莫不如把istio-policy也进行重启,在istio-policy重启过后,最终发现rateLimits相关配置终于生效。
综上,在Enabling Policy Enforcement进行方法(2)时,除了按照官方文档上设置global.disablePolicyChecks=false,还要对istio-pilot, istio-policy进行重启后才能最终生效(官网上并没有明确说明);
rateLimits官方模板(1.1.7):
---
#instance -> quota配置:定义mixer(attributes)统计维度
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
name: requestcountquota
namespace: istio-system
spec:
compiledTemplate: quota
params:
dimensions:
source: request.headers["x-forwarded-for"] | "unknown"
destination: destination.labels["app"] | destination.workload.name | "unknown"
destinationVersion: destination.labels["version"] | "unknown"
---
#handler -> redisquota | memquota:定义具体的quota限速处理逻辑
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
name: redishandler
namespace: istio-system
spec:
compiledAdapter: redisquota
params:
redisServerUrl: redis-release-master:6379
connectionPoolSize: 10
quotas:
- name: requestcountquota.instance.istio-system
maxAmount: 500
validDuration: 1s
bucketDuration: 500ms
rateLimitAlgorithm: ROLLING_WINDOW
# 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
# The following override applies to 'productpage' when
# the source is a specific ip address.
- dimensions:
destination: productpage
source: "10.28.11.20"
maxAmount: 500
# The following override applies to 'productpage' regardless
# of the source.
- dimensions:
destination: productpage
maxAmount: 2
---
#rule配置:绑定instance和handler,即定义哪个quota被转发到那个redisquota来处理,可指定match条件(参照官方api文档)
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"], "session=*") == false
actions:
- handler: redishandler
instances:
- requestcountquota
---
#quotaspec配置:定义quota的具体请求数量(实际请求*倍数charge),可指定match条件(类似virtualServic中match,参照官方api文档)
apiVersion: config.istio.io/v1alpha2
kind: QuotaSpec
metadata:
name: request-count
namespace: istio-system
spec:
rules:
- quotas:
- charge: 1
quota: requestcountquota
---
#quotaSpecBinding配置:绑定quotaSpec和具体服务(一个或多个)
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
---
官方github模板:https://github.com/istio/istio/tree/master/samples/bookinfo/policy
速率限制配置分为两部分:
QuotaSpec
定义客户端应该请求的配额名称(quota)和大小(倍数,charge);QuotaSpecBinding
有条件地将 QuotaSpec
与一个或多个服务(service)相关联;quota instance
定义了 Mixer 如何选定配额(quota)的维度(dimensions);memquota|redisquota handler
定义了 memquota
|redisquota适配器的具体限速处理逻辑;quota rule
定义何时将配额实例(quota instance)分派给 memquota
|redisquota适配器(memquota|redisquota handler
);rateLimits实际测试模板:
#instance -> quota配置:定义mixer(attributes)统计维度
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
name: requestcountquota
namespace: cq
spec:
compiledTemplate: quota
params:
dimensions:
sourceVin: request.headers["vin"] | "unknown"
destination: destination.labels["app"] | destination.workload.name | "unknown"
destinationVersion: destination.labels["version"] | "unknown"
---
#handler -> redisquota | memquota:定义具体的quota限速处理逻辑
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
name: redishandler
namespace: cq
spec:
compiledAdapter: redisquota
params:
redisServerUrl: 192.168.xxx.xxx:6379
connectionPoolSize: 10
quotas:
- name: requestcountquota.instance.cq
maxAmount: 10000000
validDuration: 10s
bucketDuration: 5000ms
rateLimitAlgorithm: ROLLING_WINDOW
# The first matching override is applied.
# A requestcount instance is checked against override dimensions.
overrides:
- dimensions:
destination: luohq-springboot
sourceVin: LUOHENGQUAN123456
maxAmount: 10
- dimensions:
destination: luohq-springboot
maxAmount: 10000000
---
#rule配置:绑定instance和handler,即定义哪个quota被转发到那个redisquota来处理,可指定match条件(参照官方api文档)
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: quota
namespace: cq
spec:
# quota only applies if you are not logged in.
# match: match(request.headers["cookie"], "session=*") == false
actions:
- handler: redishandler
instances:
- requestcountquota
---
#quotaspec配置:定义quota的具体请求数量(实际请求*倍数charge),可指定match条件(类似virtualServic中match,参照官方api文档)
apiVersion: config.istio.io/v1alpha2
kind: QuotaSpec
metadata:
name: request-count
namespace: cq
spec:
rules:
- quotas:
- charge: 1
quota: requestcountquota
---
#quotaSpecBinding配置:绑定quotaSpec和具体服务(一个或多个)
apiVersion: config.istio.io/v1alpha2
kind: QuotaSpecBinding
metadata:
name: request-count
namespace: cq
spec:
quotaSpecs:
- name: request-count
namespace: cq
services:
- name: luohq-springboot
namespace: cq
- name: mx-vehicle-parts-management
namespace: cq---
运行效果截图(使用wrk进行测试):
正常访问(request.header[vin]=LUOHENGQUANXXXXXX)
dimension维度限制访问(request.header[vin]=LUOHENGQUAN123456)
rateLimits会将非法请求返回429 - Too Many Requests,综上可以看出正常访问时成功率为72.42%,而在使用request.header[vin]=LUOHENGQUAN123456时则成功率为2.81%(明显下降),可以看出rateLimits配置生效;
关于rateLimits相关配置不在赘述,具体可参照官网;另外rateLimits还处在alpha阶段,官方不建议在生产环境中使用;
在实际测试rateLimits相关配置时,生效逻辑有时会有些混乱,仅作为学习与测试,待日后官方公布相关功能为stable时再考虑在生产环境使用,之后会持续关注社区进度;