- A+
简介
调用频率限制这个功能其实也是比较常见的东西了。这里就不多做介绍了。下面简单粗暴的介绍一下测试要完 成的目标。
测试中我们将使用两个服务,服务叫 workload,客户端叫 sleep,workload 服务正常返回群众喜闻乐见 的 “Hello World”,而 sleep 仅用来做 Shell 方便测试。
测试过程将为 workload 建立规则:
- 对于任意访问,十秒钟之内仅能访问两次;
- 对于来自 sleep 的访问,十秒钟之内仅能访问一次
下面所有内容都在 default 命名空间进行
建立测试环境
编辑 workload.yaml 以及 sleep.yaml 之后, 我们使用如下命令运行(这两部分源码,只有些乌七八糟的标签和命名有点问题,其他很普通。 见最后页)
istioctl kube-inject -f workload.yaml | kubectl apply -f - istioctl kube-inject -f sleep.yaml | kubectl apply -f -
kubectl get pods 确定 Pod 成功启动,也可以使用 curl 测试 NodePort,会得到 40x 的错误 页面。
建立规则
quota.yaml
这部分内容规则来自:https://istio.io/docs/reference/config/mixer/template/quota.html
这个对象用于设置检测服务来源、目标的标准维度,下面我们设置的是利用服务名称来检测。
这部分可能存在 bug,官方介绍的 source 定义是 `source.labels["app"] | source.service | "unknown"` 我的理解是说首先获取服务 Pod 的 app 标签内容,如果没有,再获取服务名称。但是后面我们会看到, 删除`source.labels["app"]`的定义之后,最终生效的依旧是 app 标签,这也是为什么给 workload 加上这么多奇怪标签的原因。
apiVersion: config.istio.io/v1alpha2 kind: quota metadata: name: requestcount spec: dimensions: source: source.service | "unknown" sourceVersion: source.labels["version"] | "unknown" destination: destination.service | "unknown"
handler.yaml
这一对象的定义来自:https://istio.io/docs/reference/config/mixer/adapters/memquota.html
下面的代码对应我们之前的目的,任意访问都是每 10 秒钟两次,而特定源和目标的访问则是每 10 秒钟一 次。
其中 quotas 部分,name 字段的来源是上面的 quota.yaml
这个不知道是不是 bug,必须写上半个 fqdn。
dimentions 字段则需要使用 quota.yaml 定义的维度。这里的维度可以比 quota.yaml 中定义的 维度宽松(也就是少,例如定义三个,只使用其中的两个),可以理解,这也符合匹配的规则。
apiVersion: config.istio.io/v1alpha2 kind: memquota metadata: name: handler spec: quotas: - name: requestcount.quota.default maxAmount: 2 validDuration: 10s overrides: - dimensions: destination: workload-pod.default.svc.cluster.local source: sleep.default.svc.cluster.local maxAmount: 1 validDuration: 10s
rule.yaml
这部分的定义参考:https://istio.io/docs/reference/config/mixer/policy-and-telemetry-rules.html#istio.mixer.v1.config.Rule
这个对象的作用就是,对于符合筛选条件的服务调用,使用对应的 handler 进行处理。
这里的 handler 和 requestcount 两个字段的内容,也需要是 实力名称.对象类型的方式。
apiVersion: config.istio.io/v1alpha2 kind: rule metadata: name: quota spec: actions: - handler: handler.memquota instances: - requestcount.quota
测试运行
集群外
使用 curl 重复访问 NodePort 三次,会发现第三次出现:RESOURCE_EXHAUSTED:Quota is exhausted for: RequestCount#
这说明我们设置的通用规则生效了。
集群内
在 sleep pod 中同样执行 curl 三次,发现第二次就开始出现超限说明。
上面两种情况,在超过时间窗口限制之后,都会自动恢复。
幕后
定义 quota 对象,在系统中会展现为一系列的计数器,计数器的维度就是quota 中的维度的笛卡尔积。 如果在 validDuration 的时间窗口过期之前调用次数超过了 maxAmount 规定,Mixer 就会返回 RESOURCE_EXHAUSTED 给 Envoy,Envoy 则会反馈 429 代码给调用方。
结论
文档不完善的开源系统。。坑真大啊!
源码
Workload 的 Deployment 和 Service:
apiVersion: extensions/v1beta1 kind: Deployment metadata: labels: app: workload-app version: http200 name: workload-200 spec: replicas: 1 selector: matchLabels: app: workload-pod version: http200 template: metadata: creationTimestamp: null labels: app: workload-pod version: http200 spec: containers: - image: php:7.0-apache imagePullPolicy: IfNotPresent name: http200 ports: - containerPort: 80 name: http protocol: TCP dnsPolicy: ClusterFirst restartPolicy: Always --- apiVersion: v1 kind: Service metadata: labels: app: workload-service version: http200 name: workload-200 spec: ports: - name: http port: 80 protocol: TCP targetPort: 80 nodePort: 30200 selector: app: workload-pod version: http200 sessionAffinity: None type: NodePort
Sleep 的定义
apiVersion: v1 kind: Service metadata: name: sleep labels: app: sleep spec: ports: - port: 80 name: http selector: app: sleep --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: sleep spec: replicas: 1 template: metadata: labels: app: sleep spec: containers: - name: sleep image: tutum/curl command: ["/bin/sleep","infinity"] imagePullPolicy: IfNotPresent
- 安卓客户端下载
- 微信扫一扫
- 微信公众号
- 微信公众号扫一扫