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 每个单位时间内的请求数
yaml 复制代码
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这一项。

yaml 复制代码
# 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这一项。

yaml 复制代码
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的请求分别限制

    yaml 复制代码
    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条)

yaml 复制代码
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"加入黑名单拒绝访问
yaml 复制代码
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关系

相关推荐
生活爱好者!3 小时前
哇!影视新玩法!docker部署NEOWATCH NAS
运维·docker·容器
cpolar技术支持6 小时前
Docker 容器启动失败怎么查?端口、日志、权限与网络排障完整教程
linux·docker·容器·cpolar·网络排障
Lsetea8 小时前
Kubernetes 1.37 Pod证书怎么签发:Signer与mTLS信任链排查
云原生·kubernetes·ssl证书·tls·mtls
新时代牛马9 小时前
docker run 起不来?从dockerd、containerd 到runc 一条线讲透
运维·docker·容器
努力努力再努力wz10 小时前
【Docker 入门系列】:从 Namespace、CGroup 到 LXC:理解容器运行时、rootfs 与 LXC 实战
运维·docker·容器
JavaPub-rodert11 小时前
Docker 多阶段构建:为什么生产环境镜像可以小 90%
运维·docker·容器
2601_9622184712 小时前
万象生鲜系统多账套隔离技术适配集团生鲜企业集团化数字化管控
大数据·运维·微服务·云原生·架构
@PHARAOH12 小时前
WHAT - 微服务统一入口配置原理
微服务·云原生·架构
PC2005-cloud13 小时前
Qdrant 连接失败排查:localhost 解析到 __1,而 Docker 只绑了 IPv4
运维·docker·容器
2601_9622184715 小时前
万象生鲜系统智能报表引擎技术为生鲜企业提供数字化经营分析能力
大数据·运维·微服务·云原生·架构