这个task展示如何使用Istio动态控制一个服务的流量。
Before you begin
- 在k8s集群上安装Istio
- 部署 Bookinfo
- 初始化应用版本,路由来自 reviews 服务v2版本的测试用户 “jason”的请求直接以及v3版本的其他用户请求。
istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml
istioctl create -f samples/bookinfo/kube/route-rule-reviews-v3.yaml
注意: 如果你在之前task中有冲突的规则,使用 istioctl replace
而不是 istioctl create
。
Rate limits
Istio允许用户对一个服务按速率控制流量。
考虑一下 ratings
有一个带有 1qps
自由配额的外部支付服务,比如Rotten Tomatoes®。使用Istio我们能够确保不会超过 1qps
。
1.将你的浏览器指向 Bookinfo productpage
的页面 (http://$GATEWAY_URL/productpage).
如果你以 “jason”用户登陆,你应该看到每条书评都是黑星,说明ratings
服务被reviews
服务的“v2”版本调用。
如果你以其他用户登陆(或登出),你将会看到每条书评是红星,说明ratings
服务被reviews
服务的“v3”版本调用。
2.配置一个带速率限制的 memquota
适配器。
保存如下YAML片段到文件 ratelimit-handler.yaml
:
apiVersion: config.istio.io/v1alpha2
kind: memquota
metadata:
name: handler
namespace: istio-system
spec:
quotas:
- name: requestcount.quota.istio-system
# default rate limit is 5000qps
maxAmount: 5000
validDuration: 1s
# The first matching override is applied.
# A requestcount instance is checked against override dimensions.
overrides:
# The following override applies to traffic from 'rewiews' version v2,
# destined for the ratings service. The destinationVersion dimension is ignored.
- dimensions:
destination: ratings
source: reviews
sourceVersion: v2
maxAmount: 1
validDuration: 1s
然后运行
istioctl create -f ratelimit-handler.yaml
这个配置指定默认 5000 qps 速率限制。通过 reviews-v2 到达 ratings 服务的流量速率被限制在 1qps。我们的例子中,用户 “jason”通过reviews-v2路由,因此受到 1qps 的速率限制。
3.配置速率限制示例和规则
创建一个叫做 requestcount
的配额实例,将传入属性映射到配额维度,并创造一个与 memquota 处理器一起使用的规则。
apiVersion: config.istio.io/v1alpha2
kind: quota
metadata:
name: requestcount
namespace: istio-system
spec:
dimensions:
source: source.labels["app"] | source.service | "unknown"
sourceVersion: source.labels["version"] | "unknown"
destination: destination.labels["app"] | destination.service | "unknown"
destinationVersion: destination.labels["version"] | "unknown"
---
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: quota
namespace: istio-system
spec:
actions:
- handler: handler.memquota
instances:
- requestcount.quota
保存配置为 ratelimit-rule.yaml
并运行:
istioctl create -f ratelimit-rule.yaml
4.生成 productpage
上的负载:
while true; do curl -s -o /dev/null http://$GATEWAY_URL/productpage; done
5.在你的浏览器上重复刷新 productpage
如果你以用户“jason”登陆时,负载发生器正在运行(就是说,生成超过1 req/s),通过你的浏览器生成的流量将被限制到1qps。 reviews-v2 服务不能访问ratings 服务,你就无法看到星。对于其他所有用户来说,采用默认的5000qps速率限制,你将继续看到红星。
Conditional rate limits
在之前的例子中,我们将速率限制应用到ratings
服务,而不考虑非维度属性。可以使用配额规则中的匹配条件,根据任意属性条件应用速率限制。
例如,考虑如下配置:
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: quota
namespace: istio-system
spec:
match: source.namespace != destination.namespace
actions:
- handler: handler.memquota
instances:
- requestcount.quota
配置将配额规则应用到源和目标的命名空间是不同的请求。
Understanding rate limits
在之前的例子中我们看到Mixer如何对匹配某一情况的请求进行速率限制。
每个指定的配额实例(如requestcount
)代表一组计数器。该集合由所有配额 维度的笛卡尔积定义。如果上次expiration
持续时间请求数超过maxAmount
,Mixer返回给proxy一个 RESOURCE_EXHAUSTED
信息。proxy再返回给调用者一个 HTTP 429
状态码。
memquota
适配器使用一个亚秒分辨率的滑动窗口来强制执行速率限制。
适配器配置中的 maxAmount
对于所有计数器的默认限制与一个配额实例有关。当配额覆盖与请求不匹配,则此默认限制适用。Memquota 需要第一个匹配请求的覆盖。一个覆盖不需要指定所有配额维度。在ratelimit-handler.yaml
示例中, 通过仅匹配四个配额维度中的三个来选择1qps
的覆盖。
如果你希望为给定命名空间而不是整个Istio网格强制执行上述策略,则可以将所有出现的 istio-system
替换为给定的命名空间。
Cleanup
- 移除速率限制配置:
istioctl delete -f ratelimit-handler.yaml
istioctl delete -f ratelimit-rule.yaml
- 移除应用路由规则:
istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml
istioctl delete -f samples/bookinfo/kube/route-rule-reviews-v3.yaml
- 如果你不打算探索接下来地任何课题,参考 Bookinfo cleanup 指南来关闭应用。