使用 Envoy 启用速率限制

    1. 在Kubernetes集群中安装Istio 。

    2. 部署Bookinfo示例应用程序。

    Envoy支持两种速率限制:全局和本地。全局速率使用全局gRPC速率限制服务为整个网格提供速率限制。 本地速率限制用于限制每个服务实例的请求速率。局部速率限制可以与全局速率限制一起使用,以减少负载全局速率限制服务。

    在本任务中,您将配置Envoy以对服务的特定路径的流量进行速率限制同时使用全局和本地速率限制。

    Envoy可以用来为您的网格。 Envoy中的全局速率限制使用gRPC API从速率限制服务请求配额。在下面使用Redis写的后端参考实现的API。

    1. 使用下面的configmap来以1分钟一个请求的速度对路径/productpage的限制请求进行评估,其他所有请求以一分钟100个请求的速度评估。

      apiVersion: v1 kind: ConfigMap metadata: name: ratelimit-config data: config.yaml: | domain: productpage-ratelimit descriptors: - key: PATH value: "/productpage" rate_limit: unit: minute requests_per_unit: 1 - key: PATH rate_limit: unit: minute requests_per_unit: 100

    2. 创建一个全局速率限制服务,它实现Envoy的速率限制服务协议。作为参考,可以在找到一个演示配置,它是基于Envoy提供的参考实现

    3. ingressgateway应用EnvoyFilter以使Envoy的全球速率限制过滤器启用全球速率限制

    第一个patch插入envoy.filters.http.ratelimit的过滤器到HTTP_FILTERrate_limit_service字段指定外部速率限制服务,在本例中为rate_limit_cluster

    ``` $ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: filter-ratelimit namespace: istio-system spec: workloadSelector:

    configPatches:

    1. # The Envoy config you want to modify
    2. - applyTo: HTTP_FILTER
    3. match:
    4. context: GATEWAY
    5. listener:
    6. filterChain:
    7. filter:
    8. subFilter:
    9. name: "envoy.filters.http.router"
    10. patch:
    11. operation: INSERT_BEFORE
    12. # Adds the Envoy Rate Limit Filter in HTTP filter chain.
    13. value:
    14. name: envoy.filters.http.ratelimit
    15. typed_config:
    16. "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
    17. # domain can be anything! Match it to the ratelimter service config
    18. failure_mode_deny: true
    19. timeout: 10s
    20. rate_limit_service:
    21. grpc_service:
    22. envoy_grpc:
    23. cluster_name: rate_limit_cluster
    24. transport_api_version: V3
    25. - applyTo: CLUSTER
    26. cluster:
    27. service: ratelimit.default.svc.cluster.local
    28. patch:
    29. operation: ADD
    30. # Adds the rate limit service cluster for rate limit service defined in step 1.
    31. value:
    32. name: rate_limit_cluster
    33. type: STRICT_DNS
    34. connect_timeout: 10s
    35. lb_policy: ROUND_ROBIN
    36. http2_protocol_options: {}
    37. load_assignment:
    38. cluster_name: rate_limit_cluster
    39. endpoints:
    40. - lb_endpoints:
    41. - endpoint:
    42. address:
    43. socket_address:
    44. address: ratelimit.default.svc.cluster.local

    EOF `

    1. 对定义限速路由配置的应用另一个EnvoyFilter。这增加了速率限制动作对于来自名为*.80的虚拟主机的任何路由。

      $ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: filter-ratelimit-svc namespace: istio-system spec: workloadSelector: labels: istio: ingressgateway configPatches: - applyTo: VIRTUAL_HOST match: context: GATEWAY routeConfiguration: vhost: name: "" route: action: ANY patch: operation: MERGE # Applies the rate limit rules. value: rate_limits: - actions: # any actions in here - request_headers: header_name: ":path" descriptor_key: "PATH" EOF

    Envoy支持L4连接和HTTP请求的本地速率限制

    这允许您在代理本身的实例级应用速率限制,而无需调用任何其他服务。

    下面的EnvoyFilter为通过productpage服务的任何流量启用了本地速率限制。 HTTP_FILTERpatch会插入envoy.filters.httpLocal_ratelimit 进入HTTP连接管理器过滤器链。本地速率限制过滤器的令牌桶配置为允许10请求每分。该过滤器还配置为添加x-local-rate-limit。对被阻塞的请求的响应头。

    在中提到的统计数据默认是禁用的。您可以在部署期间使用以下注释启用它们:

    template: metadata: annotations: proxy.istio.io/config: |- proxyStatsMatcher: inclusionRegexps: - ".*http_local_rate_limit.*"

    上述配置对所有vhosts/routes都进行本地速率限制。或者,您可以将其限制为特定的路由。

    下面的EnvoyFilterproductpage服务的80端口的任何流量启用了本地速率限制。与前面的配置不同,HTTP_FILTERpatch中不包含token_buckettoken_bucket被定义在第二个(HTTP_ROUTE)patch中,其中包含envoy.filters.http.local_ratelimittyped_per_filter_config

    本地Envoy过滤器,用于路由到虚拟主机inbound|http|9080

    $ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: filter-local-ratelimit-svc namespace: istio-system spec: workloadSelector: labels: app: productpage configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND listener: filterChain: filter: name: "envoy.filters.network.http_connection_manager" patch: operation: INSERT_BEFORE value: name: envoy.filters.http.local_ratelimit typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit value: stat_prefix: http_local_rate_limiter - applyTo: HTTP_ROUTE match: context: SIDECAR_INBOUND routeConfiguration: vhost: name: "inbound|http|9080" route: action: ANY patch: operation: MERGE value: typed_per_filter_config: envoy.filters.http.local_ratelimit: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit value: stat_prefix: http_local_rate_limiter token_bucket: max_tokens: 10 tokens_per_fill: 10 fill_interval: 60s filter_enabled: runtime_key: local_rate_limit_enabled default_value: numerator: 100 denominator: HUNDRED filter_enforced: runtime_key: local_rate_limit_enforced default_value: numerator: 100 denominator: HUNDRED response_headers_to_add: - append: false header: key: x-local-rate-limit value: 'true' EOF

    向Bookinfo示例发送通信流。在你的网站上访问http://$GATEWAY_URL/productpage浏览器或发出以下命令:

    $ curl "http://$GATEWAY_URL/productpage"

    $GATEWAY_URL is the value set in the Bookinfo example.

    您将看到第一个请求通过,但随后的每个请求在一分钟内将得到429响应。

    虽然入口网关的全局速率限制将对productpage服务的请求限制在1请求每分,productpage实例的本地速率限制允许10请求每分。

    为了确认这一点,从ratingspod发送内部productpage请求,使用下面的curl命令:

    您应该看到每个实例的请求次数不超过10请求每分。