为入口网关配置本地限流

在大促等场景下,瞬间洪峰流量会使系统超出最大负载,调用大量堆积,导致整个调用链路卡死。ASM提供了本地限流功能,支持对网关进行流量限制,达到保护系统的目的。本文介绍如何为入口网关配置本地限流。

前提条件

  • 已创建ASM实例,且ASM实例要符合以下要求:

    • ASM商业版(专业版或旗舰版):版本需为1.11.5.30及以上。关于升级ASM实例的具体操作,请参见升级ASM实例

    • ASM标准版:仅支持Istio原生方式配置本地限流功能,且版本需为1.9及以上。不同Istio版本需参考相应版本文档,关于最新的Istio版本配置本地限流功能的具体操作,请参见Enabling Rate Limits using Envoy

  • 已添加集群到ASM实例。具体操作,请参见添加集群到ASM实例

  • 已部署入口网关。具体操作,请参见创建入口网关

  • 已创建bookinfo和nginx服务。本文将bookinfo部署在default命名空间,将nginx部署在foo命名空间。创建bookinfo的具体操作,请参见在ASM实例关联的集群中部署应用

    展开查看如何创建nginx服务

    1. 使用以下内容,创建nginx.yaml。

      apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
      kind: Deployment
      metadata:
        name: nginx
      spec:
        selector:
          matchLabels:
            app: nginx
        replicas: 1
        template:
          metadata:
            labels:
              app: nginx
              sidecarset-injected: "true"
          spec:
            containers:
            - name: nginx
              image: nginx:1.14.2
              ports:
              - containerPort: 80
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: nginx
      spec:
        ports:
          - name: http
            port: 80
            protocol: TCP
            targetPort: 80
        selector:
          app: nginx
        type: ClusterIP
    2. 执行以下命令,在foo命名空间部署Nginx。

      kubectl apply -f nginx.yaml -n foo 
  • 已创建网关规则和虚拟服务。具体操作,请参见管理网关规则管理虚拟服务

    展开查看Gateway YAML

    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: bookinfo-gateway
      namespace: default
    spec:
      selector:
        istio: ingressgateway
      servers:
      - hosts:
        - bf2.example.com
        port:
          name: http
          number: 80
          protocol: http

    展开查看VirtualService YAML

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: bookinfo
      namespace: default
    spec:
      gateways:
      - bookinfo-gateway
      hosts:
      - bf2.example.com
      http:
      - match:
        - uri:
            exact: /productpage
        - uri:
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
        name: productpage-route-name1
        route:
        - destination:
            host: productpage
            port:
              number: 9080
      - match:
        - uri:
            prefix: /nginx
        name: nginx-route-name1
        rewrite:
          uri: /
        route:
        - destination:
            host: nginx.foo.svc.cluster.local
            port:
              number: 80
  • 已安装流量加压工具。具体操作,请参见hey

适用对象

ASM本地限流功能适用于ASM网关和应用服务(注入了Sidecar)。

场景示例说明

本文以Bookinfo和Nginx为例介绍网关和服务限流的具体使用场景。Nginx将单独部署在foo命名空间,用于验证限流的开启范围。场景示例

场景一:对单个虚拟服务路由配置限流规则

bf2.example.com:80这个域名和端口组合下的productpage-route-name1路由配置限流规则。productpage-route-name1是前提条件中创建的虚拟服务bookinfo中的一条路由项,匹配了请求的/productpage/static/login/logout等路径并将匹配的请求转发到productpage服务。配置限流规则后,发往上述路径的请求都将受到流量速率的限制。

  1. 创建本地限流规则。

    1. 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理

    2. 网格管理页面,单击目标实例名称,然后在左侧导航栏,选择流量管理中心 > 限流防护,然后单击创建

    3. 创建页面,按需进行以下配置,然后单击确定

      关于配置项的详情,请参见ASMLocalRateLimiter CRD说明

      配置区域

      配置项

      说明

      限流基本信息

      命名空间

      本地限流配置的命名空间,需要配置为限流生效的工作负载的所在命名空间。本示例必须选择istio-system,因为所有ASM网关都部署在istio-system命名空间。

      名称

      本地限流配置的自定义名称。本示例填写ingressgateway

      生效工作负载类型

      限流生效的工作负载类型,支持应用服务生效网关生效。本示例选择网关生效

      关联工作负载

      在生效工作负载类型为网关生效的情况下,可以通过选择网关规则的方式关联工作负载,本地限流配置将与选中的网关规则关联相同的网关工作负载。本示例选择bookinfo-gateway

      限流规则列表

      网关域名

      选择网关规则中声明的域名,限流规则将在指定的端口和域名组合下生效。本示例选择bf2.example.com

      网关端口

      选择网关规则中声明的端口,限流规则将在指定的端口和域名组合下生效。本示例选择80

      匹配虚拟服务路由项

      选择与网关规则关联的虚拟服务中声明的路由项。限流规则将在指定的虚拟服务路由项之下生效。本示例选择productpage-route-name1

      限流配置

      指定本地限流令牌桶算法的检测时间窗口长度与时间窗口内允许的请求数量。在时间窗口内发送的请求数量超过该允许的数量则会对请求进行限流。本示例配置如下:

      • 限流检测时间窗口填写1秒

      • 时间窗口内允许请求数量填写10

      以上配置表示发往此服务的工作负载的请求不得在1秒内连续发送10个以上。

      高级选项

      单击展开高级选项,可以指定限流发生时的部分高级行为。您可按需对高级选项进行配置。本示例自定义限流响应体填写{"ret_code": xxx,"message": "Your request be limited"}

      image.png

      以上配置对应的本地限流配置YAML如下。

      • 如果您没有配置高级选项,限流时将返回默认响应信息。

        展开查看未配置高级选项的本地限流YAML

        apiVersion: istio.alibabacloud.com/v1beta1
        kind: ASMLocalRateLimiter
        metadata:
          name: ingressgateway
          namespace: istio-system
        spec:
          configs:
            - limit:
                fill_interval:
                  seconds: 1
                quota: 10
              match:
                vhost:
                  name: bf2.example.com
                  port: 80
                  route:
                    name_match: productpage-route-name1
          isGateway: true
          workloadSelector:
            labels:
              istio: ingressgateway
      • 如果您配置了高级选项,限流时将返回自定义响应信息。

        展开查看配置高级选项的本地限流YAML

        apiVersion: istio.alibabacloud.com/v1beta1
        kind: ASMLocalRateLimiter
        metadata:
          name: ingressgateway
          namespace: istio-system
        spec:
          configs:
            - limit:
                custom_response_body: '{"ret_code": xxx, "message": "Your request be limited" }'
                fill_interval:
                  seconds: 1
                quota: 10
              match:
                vhost:
                  name: bf2.example.com
                  port: 80
                  route:
                    name_match: productpage-route-name1
          isGateway: true
          workloadSelector:
            labels:
              istio: ingressgateway
  2. 在hey工具中执行以下命令,持续产生压力流量。

    hey -host bf2.example.com -c 10 -n 100000 http://<ASM网关IP>/productpage
    hey -host bf2.example.com -c 10 -n 100000 http://<ASM网关IP>/nginx
  3. 执行以下命令,访问网关的/productpage路径。

    curl -H 'host: bf2.example.com'  http://<ASM网关IP>/productpage -v

    预期输出:

    < HTTP/1.1 429 Too Many Requests
    < Content-Length: 18
    < Content-Type: text/plain
    < Date: Thu, 13 Jan 2022 03:03:09 GMT
    < Server: istio-envoy
    <
    local_rate_limited

    可以看到访问bookinfo服务受到限流。

  4. 执行以下命令,访问网关的/nginx路径。

    curl -H 'host: bf2.example.com'  http://${ASM_GATEWAY_IP}/nginx  -v

    返回结果中没有429,说明访问未限流。

场景二:对网关上域名和端口的组合限流规则

bf2.example.com:80这个域名和端口组合设定限流配置,使该域名和端口组合下的所有路径都受到流量限制。

  1. 配置限流规则。

    1. 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理

    2. 网格管理页面,单击目标实例名称,然后在左侧导航栏,选择流量管理中心 > 限流防护,然后单击创建

    3. 创建页面,按需进行以下配置,然后单击确定

      关于配置项的详情,请参见ASMLocalRateLimiter CRD说明

      配置区域

      配置项

      说明

      限流基本信息

      命名空间

      本地限流配置的命名空间,需要配置为限流生效的工作负载的所在命名空间。本示例必须选择istio-system,因为所有ASM网关都部署在istio-system命名空间。

      名称

      本地限流配置的自定义名称。本示例填写ingressgateway

      生效工作负载类型

      限流生效的工作负载类型,支持应用服务生效网关生效。本示例选择网关生效

      关联工作负载

      在生效工作负载类型为网关生效的情况下,可以通过选择网关规则的方式关联工作负载,本地限流配置将与选中的网关规则关联相同的网关工作负载。本示例选择bookinfo-gateway

      限流规则列表

      网关域名

      选择网关规则中声明的域名,限流规则将在指定的端口和域名组合下生效。本示例选择bf2.example.com

      网关端口

      选择网关规则中声明的端口,限流规则将在指定的端口和域名组合下生效。本示例选择80

      匹配虚拟服务路由项

      选择与网关规则关联的虚拟服务中声明的路由项。限流规则将在指定的虚拟服务路由项之下生效。本示例不进行选择,表示在域名和端口下的所有路由项上都生效限流规则。

      限流配置

      指定本地限流令牌桶算法的检测时间窗口长度与时间窗口内允许的请求数量。在时间窗口内发送的请求数量超过该允许的数量则会对请求进行限流。本示例配置如下:

      • 限流检测时间窗口填写1秒

      • 时间窗口内允许请求数量填写10

      以上配置表示发往此服务的工作负载的请求不得在1秒内连续发送10个以上。

      image.png

      以上配置对应的本地限流配置YAML如下。

      展开查看本地限流YAML

      apiVersion: istio.alibabacloud.com/v1beta1
      kind: ASMLocalRateLimiter
      metadata:
        name: ingressgateway
        namespace: istio-system
      spec:
        configs:
          - limit:
              fill_interval:
                seconds: 1
              quota: 10
            match:
              vhost:
                name: bf2.example.com
                port: 80
                route: {}
        isGateway: true
        workloadSelector:
          labels:
            istio: ingressgateway
  2. 在hey工具中执行以下命令,持续产生压力流量。

    hey -host bf2.example.com -c 10 -n 100000 http://${ASM_GATEWAY_IP}/nginx
  3. 执行以下命令,访问网关的/nginx路径。

    curl -H 'host: bf2.example.com'  http://${ASM_GATEWAY_IP}/nginx -v

    可以看到,返回HTTP/1.1 429 Too Many Requests,说明访问网关上的/nginx路径受到限流。

场景三:在单个虚拟服务路由上,针对包含特定请求头的请求配置限流规则

bf2.example.com:80这个域名和端口组合下的nginx-route-name1路由配置限流规则,同时指定限流规则只生效在带有ratelimit: "true"请求头的请求上,该路由上的其他请求不受限流规则影响。nginx-route-name1是前提条件中创建的虚拟服务bookinfo中的一条路由项,匹配了请求的/nginx路径并将匹配的请求转发到nginx服务。

  1. 配置限流规则。

    1. 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理

    2. 网格管理页面,单击目标实例名称,然后在左侧导航栏,选择流量管理中心 > 限流防护,然后单击创建

    3. 创建页面,按需进行以下配置,然后单击确定

      关于配置项的详情,请参见ASMLocalRateLimiter CRD说明

      配置区域

      配置项

      说明

      限流基本信息

      命名空间

      本地限流配置的命名空间,需要配置为限流生效的工作负载的所在命名空间。本示例必须选择istio-system,因为所有ASM网关都部署在istio-system命名空间。

      名称

      本地限流配置的自定义名称。本示例填写ingressgateway

      生效工作负载类型

      限流生效的工作负载类型,支持应用服务生效网关生效。本示例选择网关生效

      关联工作负载

      在生效工作负载类型为网关生效的情况下,可以通过选择网关规则的方式关联工作负载,本地限流配置将与选中的网关规则关联相同的网关工作负载。本示例选择bookinfo-gateway

      限流规则列表

      网关域名

      选择网关规则中声明的域名,限流规则将在指定的端口和域名组合下生效。本示例选择bf2.example.com

      网关端口

      选择网关规则中声明的端口,限流规则将在指定的端口和域名组合下生效。本示例选择80

      匹配虚拟服务路由项

      选择与网关规则关联的虚拟服务中声明的路由项。限流规则将在指定的虚拟服务路由项之下生效。本示例选择路由项nginx-route-name1

      匹配请求属性

      填写生效限流配置的具体请求匹配规则。本示例配置如下:

      • 匹配属性选择具体请求头

      • 请求头名称填写ratelimit

      • 匹配方法选择精确匹配

      • 匹配内容填写true

      限流配置

      指定本地限流令牌桶算法的检测时间窗口长度与时间窗口内允许的请求数量。在时间窗口内发送的请求数量超过该允许的数量则会对请求进行限流。本示例配置如下:

      • 限流检测时间窗口填写1秒

      • 时间窗口内允许请求数量填写10

      以上配置表示发往此服务的工作负载的请求不得在1秒内连续发送10个以上。

      image.png

      以上配置对应的本地限流配置YAML如下。

      展开查看本地限流YAML

      apiVersion: istio.alibabacloud.com/v1
      kind: ASMLocalRateLimiter
      metadata:
        name: ingressgateway
        namespace: istio-system
      spec:
        configs:
          - limit:
              fill_interval:
                seconds: 1
              quota: 10
            match:
              vhost:
                name: bf2.example.com
                port: 80
                route:
                  header_match:
                    - exact_match: 'true'
                      invert_match: false
                      name: ratelimit
                  name_match: nginx-route-name1
        isGateway: true
        workloadSelector:
          labels:
            istio: ingressgateway
  2. 在hey工具中执行以下命令,持续产生压力流量,请求都携带ratelimit: true的请求头以触发限流。

    hey -host bf2.example.com -H 'ratelimit: true' -c 10 -n 10000 http://${ASM_GATEWAY_IP}/nginx
  3. 执行以下命令,访问网关的/nginx路径。

    curl -H 'host: bf2.example.com' -H 'ratelimit: true'  http://${ASM_GATEWAY_IP}/nginx -v

    可以看到返回HTTP/1.1 429 Too Many Requests,说明访问网关/nginx路径、并携带ratelimit: true请求头的请求受到了限流。

  4. 执行以下命令,访问网关的/nginx路径,但请求不携带ratelimit: true请求头。

    curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/nginx -v

    可以看到返回结果中没有429,说明未携带ratelimit: true请求头的请求未受限流影响。

相关操作

删除限流配置,恢复访问

  1. 删除限流规则。

    1. 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理

    2. 网格管理页面,单击目标实例名称,然后在左侧导航栏,选择流量管理中心 > 限流防护

    3. 限流防护页面的操作列,单击目标限流规则对应的删除,在确认对话框,单击确定

  2. 执行以下命令,访问网关的/nginx路径。

    curl -H 'host: bf2.example.com'  http://${ASM_GATEWAY_IP}/nginx -v

    返回结果中没有429,说明访问未限流。

相关文档