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关系

  • 28
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值