Istio中的全局限流方案

Istio中的全局限流方案

在k8s网格(istio)环境中, 可以通过创建Envfoyfilter的方式来配置限流。

在istio官方文档中,提供了两种限流方式:

  • 本地限流
  • 全局限流

本地限流的细节这里不再赘述, 主要讲解全局限流的配置方式。

基本原理

istio通过向pod中注入sidecar,并通过envoy来代理流量,完成对流量的控制。
在这里插入图片描述

sidecar中的envoy, 由polit-agent管理。通过监听k8s中资源的变化,并由XDS协议下发配置到envoy中。
在这里插入图片描述

本地限流之所以称之为本地,是因为它只能为单个pod限流。 它通过hash桶算法进行流量分配。优点是可以平滑流量。
在这里插入图片描述

全局限流解决的是一个服务有多个pod的情况下,如何进行统一的限流。全局限流是通过sidecar中的envoy调用ratelimit服务来实现的。

全局限流

全局限流通过外部服务ratelimit来进行流量的统一控制。
在这里插入图片描述

ratelimit服务是一个独立的服务,它通过gRPC协议提供限流服务。envoy通过gRPC协议调用ratelimit服务,来获取限流的配置。

ratelimit中的配置管理支持configmapXDS两种方式。我们开发了单独的ratelimit-configserver服务,用于管理、下发配置到ratelimit服务中。
在这里插入图片描述

这里不赘述ratelimit-configserver的实现, 主要讲解如何在istio中配置全局限流。

使用ConfigMap的架构是这样的
在这里插入图片描述

ratelimit服务部署

具体的部署方式以及示例使用, 在istio的官方文档中有详细的介绍。这里不再赘述。文档地址https://istio.io/latest/zh/docs/tasks/policy-enforcement/rate-limit/#global-rate-limit-advanced-case

这里需要提的是, 官方文档中使用的镜像版本较老,不支持XDS的方式获取配置, 建议自行拉取最新代码并打包镜像。

配置说明

配置的方式比较生涩, 难以理解, 这里会着重说明一下。

基础配置说明

  • domain 限流策略的唯一标识,与EnvoyFilter中的domain字段对应
  • descriptors 用于声明详细的规则, 是一个数组, 可以配置多个规则
  • descriptors.key 规则的标识, 可以简单理解为http请求中某个header的代号(这并不准确,暂时先这样理解)
  • descriptors.value 规则的值, 用于匹配请求中的某个header的值。 不指定时则匹配所有请求
  • descriptors.rate_limit.unit 限流的单位, 可以是second, minute, hour, day
  • descriptors.rate_limit.requests_per_unit 每个单位时间内的请求数
domain: ratelimit
    descriptors:
        - key: PATH
        value: "/productpage"
        rate_limit:
            unit: minute
            requests_per_unit: 1
        - key: PATH
        value: "api"
        rate_limit:
            unit: minute
            requests_per_unit: 2
        - key: PATH
        rate_limit:
            unit: minute
            requests_per_unit: 100

上面的配置表示:
对于/productpage路径的请求, 每分钟限流1次; 对于api路径的请求, 每分钟限流2次; 对于其他请求, 每分钟限流100次。

注意: /productpage 和 api 的请求次数会计入到100次的限流中。

官方文档示例中, 除了创建configmap外, 还有两个envoyfilter。 一个是用于配置ratelimit服务的地址(filter-ratelimit), 另一个是用于配置策略与请求之间的关系(filter-ratelimit-svc), 如KeyA对应的是请求头中的哪一个。

filter-ratelimit中我们主要关注typed_config这一项。

# type 声明当前使用的API版本
"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
# domain与configmap中的配置匹配
domain: ratelimit
# failure_mode_deny 表示当ratelimit服务不可用时,是否拒绝请求。 
# 建议设为false, 这样即使我们的限流服务出现问题也不会影响业务服务的正常运行
failure_mode_deny: true
# timeout 速率限制服务RPC的超时(以毫秒为单位)。如果没有设置,则默认为20毫秒。
# 超时时间建议设的短一些, 这样可以快速失败,不会影响业务服务的正常运行
timeout: 10s
rate_limit_service:
    grpc_service:
        envoy_grpc:
            # 用于设置上游的ratelimit服务的端口号及地址
            # 这里测试时用ip会有问题 
            cluster_name: outbound|8081||ratelimit.default.svc.cluster.local
            # 会设置到authority标头中
            authority: ratelimit.default.svc.cluster.local
        # 用于设置请求携带的metadata
        initial_metadata: {}
    transport_api_version: V3

filter-ratelimit-svc中我们主要关注rate_limits这一项。

rate_limits:
- actions: 
    - request_headers:
        // 这里说明PATH这个key,会从:path这个header中读取数据匹配value
        header_name: ":path"
        descriptor_key: "PATH"
    - request_headers:
        // 可以有多个, 也可通过其他方式匹配请求。如参数、正则等,具体查看istio文档
        header_name: "x-header-key"
        descriptor_key: "KeyA"
// action也可以有多个

高级配置

着重于ratelimit中的配置, 参考ratelimit官方文档

  1. 对database为user和database为default的请求分别限制
    domain: mongo_cps
     descriptors:
     - key: database
         value: users
         rate_limit:
         unit: second
         requests_per_unit: 500
    
     - key: database
         value: default
         rate_limit:
         unit: second
         requests_per_unit: 500
    
  2. 每个号码每天只允许100条信息; 且对message_type为marketing的信息, 每天每个号码只允许5条(算上5条,共在100条)
domain: messaging
descriptors:
  - key: message_type
    value: marketing
    descriptors:
      - key: to_number
        rate_limit:
          unit: day
          requests_per_unit: 5
  - key: to_number
    rate_limit:
      unit: day
      requests_per_unit: 100
  1. 每个原地址(客户)允许10qps,"50.0.0.5"加入黑名单拒绝访问
domain: edge_proxy_per_ip
descriptors:
  - key: remote_address
    rate_limit:
      unit: second
      requests_per_unit: 10
  - key: remote_address
    value: 50.0.0.5
    rate_limit:
      unit: second
      requests_per_unit: 0

总之, descriptors字段中, 多个规则平级为and关系, 多个规则嵌套为or关系

相关推荐

  1. Istio在微服务释放服务网格力量

    2024-05-10 20:52:09       29 阅读
  2. C++

    2024-05-10 20:52:09       39 阅读
  3. Stream方法详解

    2024-05-10 20:52:09       32 阅读
  4. C# 局部静态函数,封闭方法最佳选择

    2024-05-10 20:52:09       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-10 20:52:09       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-10 20:52:09       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-10 20:52:09       87 阅读
  4. Python语言-面向对象

    2024-05-10 20:52:09       96 阅读

热门阅读

  1. Vue3实战笔记(05)--- 跨域前后端解决方案

    2024-05-10 20:52:09       28 阅读
  2. 【Leetcode】55- 跳跃游戏

    2024-05-10 20:52:09       38 阅读
  3. LeetCode //C - 81. Search in Rotated Sorted Array II

    2024-05-10 20:52:09       28 阅读
  4. 苹果免签封装的优势和安全风险

    2024-05-10 20:52:09       26 阅读
  5. latex编译参考文献是问号解决办法

    2024-05-10 20:52:09       29 阅读
  6. mybatis 多表查询

    2024-05-10 20:52:09       32 阅读
  7. 华为热题总结(1)

    2024-05-10 20:52:09       36 阅读
  8. MySQL变量的定义与使用

    2024-05-10 20:52:09       31 阅读
  9. mysql 按字段查询重复的数据

    2024-05-10 20:52:09       33 阅读