Isito - Rate Limits(请求限速)

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)相关联;
  • Mixer 端
    • 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)

Isito - Rate Limits(请求限速)_第1张图片

dimension维度限制访问(request.header[vin]=LUOHENGQUAN123456) 

Isito - Rate Limits(请求限速)_第2张图片

 

rateLimits会将非法请求返回429 - Too Many Requests,综上可以看出正常访问时成功率为72.42%,而在使用request.header[vin]=LUOHENGQUAN123456时则成功率为2.81%(明显下降),可以看出rateLimits配置生效;

关于rateLimits相关配置不在赘述,具体可参照官网;另外rateLimits还处在alpha阶段,官方不建议在生产环境中使用;

在实际测试rateLimits相关配置时,生效逻辑有时会有些混乱,仅作为学习与测试,待日后官方公布相关功能为stable时再考虑在生产环境使用,之后会持续关注社区进度;

你可能感兴趣的:(k8s,istio)