为入口网关配置全局限流

在面临高流量冲击、服务过载、资源耗尽或恶意攻击的情况下,通过对入口网关的特定路由配置全局限流,可以实现对流量的精准控制,从而保护后端服务的稳定性,降低成本并提升用户体验。

前提条件

  • 已添加Kubernetes托管版集群到ASM实例,且ASM实例为1.18.0.131及以上。具体操作,请参见添加集群到ASM实例

  • 已为Kubernetes集群中的default命名空间开启自动注入。具体操作,请参见启用自动注入

  • 已创建名为ingressgateway的入口网关,并开启80端口。具体操作,请参见创建入口网关

准备工作

一、部署限流服务

  1. 使用以下内容,创建ratelimit-svc.yaml。

    展开查看ratelimit-svc.yaml

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: redis
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: redis
      labels:
        app: redis
    spec:
      ports:
      - name: redis
        port: 6379
      selector:
        app: redis
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: redis
      template:
       metadata:
          labels:
            app: redis
            sidecar.istio.io/inject: "false"
       spec:
          containers:
          - image: redis:alpine
            imagePullPolicy: Always
            name: redis
            ports:
            - name: redis
              containerPort: 6379
          restartPolicy: Always
          serviceAccountName: redis
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ratelimit-config
    data:
      config.yaml: |
        {}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ratelimit
      labels:
        app: ratelimit
    spec:
      ports:
      - name: http-port
        port: 8080
        targetPort: 8080
        protocol: TCP
      - name: grpc-port
        port: 8081
        targetPort: 8081
        protocol: TCP
      - name: http-debug
        port: 6070
        targetPort: 6070
        protocol: TCP
      selector:
        app: ratelimit
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ratelimit
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ratelimit
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            app: ratelimit
            sidecar.istio.io/inject: "false"
        spec:
          containers:
            # Latest image from https://hub.docker.com/r/envoyproxy/ratelimit/tags
          - image: envoyproxy/ratelimit:e059638d 
            imagePullPolicy: Always
            name: ratelimit
            command: ["/bin/ratelimit"]
            env:
            - name: LOG_LEVEL
              value: debug
            - name: REDIS_SOCKET_TYPE
              value: tcp
            - name: REDIS_URL
              value: redis.default.svc.cluster.local:6379
            - name: USE_STATSD
              value: "false"
            - name: RUNTIME_ROOT
              value: /data
            - name: RUNTIME_SUBDIRECTORY
              value: ratelimit
            - name: RUNTIME_WATCH_ROOT
              value: "false"
            - name: RUNTIME_IGNOREDOTFILES
              value: "true"
            ports:
            - containerPort: 8080
            - containerPort: 8081
            - containerPort: 6070
            volumeMounts:
            - name: config-volume
              # $RUNTIME_ROOT/$RUNTIME_SUBDIRECTORY/$RUNTIME_APPDIRECTORY/config.yaml
              mountPath: /data/ratelimit/config
          volumes:
          - name: config-volume
            configMap:
              name: ratelimit-config
  2. 在ACK集群对应的KubeConfig环境下,执行以下命令,在集群中创建限流服务和限流服务依赖的Redis服务。

    关于如何通过kubectl连接集群,请参考获取集群KubeConfig并通过kubectl工具连接集群

    kubectl apply -f ratelimit-svc.yaml

二、部署bookinfo示例应用

  1. Github的Istio项目库中下载bookinfo应用的YAML文件bookinfo.yaml。

  2. 在ACK集群对应的KubeConfig环境下,执行以下命令,将bookinfo应用部署到ASM实例的集群中。

    kubectl apply -f bookinfo.yaml
  3. 使用以下内容,创建bookinfo-gateway.yaml。

    展开查看bookinfo-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
    ---
    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
  4. 在ASM实例对应的KubeConfig环境下,执行以下命令,创建入口网关ingressgateway对bookinfo应用的路由规则。

    该路由规则的名称为productpage-route-name1,匹配请求域名bf2.example.com。关于如何通过kubectl连接ASM实例,请参考通过控制面kubectl访问Istio资源

    kubectl apply -f bookinfo-gateway.yaml

场景一:对入口网关的特定路由配置全局限流

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

  1. 使用以下内容,创建global-ratelimit-gw.yaml。

    展开查看global-ratelimit-gw.yaml

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      workloadSelector:
        labels:
          istio: ingressgateway
      rateLimitService: # 准备工作中部署的限流服务的配置。
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      isGateway: true
      configs:
      - name: productpage
        limit:
          unit: MINUTE
          quota: 1
        match:
          vhost:
            name: bf2.example.com # 该名称需要和VirtualService下的域名一致。
            port: 80 # 该端口号需要和ASM网关端口匹配。
            route:
              name_match: productpage-route-name1  # 该名称需要和VirtualService下的路由规则一致。

    部分字段说明如下。关于字段的更多信息,请参见ASMGlobalRateLimiter CRD说明

    字段

    说明

    workloadSelector

    用于匹配限流生效的工作负载。本示例全局限流生效于ingressgateway入口网关,设置为istio: ingressgateway

    isGateway

    是否作用于网关。本示例中设定为true

    rateLimitService

    限流服务的域名、端口和连接超时设置。根据准备工作中部署的限流服务,配置如下:

       host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5

    limit

    需要生效的限流配置参数。其中unit表示限流检测的时间单位,quota表示单位时间内允许的请求总量。

    本示例配置unitMINUTEquota1,表示匹配路由上每分钟只能发送一个请求,超出的请求将被限流。

    vhost

    限流匹配的域名和路由项配置。其中nameport需要分别和应用于网关的虚拟服务中的域名以及入口网关端口匹配,route.name_match中填写的路由名称需要与虚拟服务中路由项的名称一致。

  2. 在ASM实例对应的KubeConfig环境下,执行以下命令,创建生效于网关上productpage-route-name1路由项的全局限流规则。

    kubectl apply -f global-ratelimit-gw.yaml
  3. 执行以下命令,获取调谐完成的全局限流规则配置内容。

    kubectl get asmglobalratelimiter global-test -n istio-system -o yaml

    展开查看预期输出

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      configs:
      - limit:
          quota: 1
          unit: MINUTE
        match:
          vhost:
            name: bf2.example.com
            port: 80
            route:
              name_match: productpage-route-name1
        name: productpage
      isGateway: true
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      workloadSelector:
        labels:
          app: istio-ingressgateway
    status:
      config.yaml: |
        descriptors:
        - key: generic_key
          rate_limit:
            requests_per_unit: 1
            unit: MINUTE
          value: RateLimit[global-test.istio-system]-Id[597770312]
        domain: ratelimit.default.svc.cluster.local
      message: ok
      status: successful
  4. 将上一步预期输出的ASMGlobalRateLimiter资源中status字段的config.yaml内容,粘贴至ratelimit-config.yaml,生成全局限流服务配置。

    ASMGlobalRateLimiter中status字段下的config.yaml字段中的字符串内容,需原样粘贴至ConfigMap中data中的同名config.yaml字段中。

    展开查看ratelimit-config.yaml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ratelimit-config
    data:
      config.yaml: |
        descriptors:
        - key: generic_key
          rate_limit:
            requests_per_unit: 1
            unit: MINUTE
          value: RateLimit[global-test.istio-system]-Id[597770312]
        domain: ratelimit.default.svc.cluster.local
  5. 在ACK集群对应的KubeConfig环境下,执行以下命令,在集群中更新全局限流服务配置。

    kubectl apply -f ratelimit-config.yaml
  6. 执行以下命令,连续访问bookinfo应用两次。

    请将<ASM网关IP>替换为实际网关IP。关于如何获取网关IP,请参见获取入口网关地址

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

    第二次访问bookinfo应用的预期输出如下:

    < HTTP/1.1 429 Too Many Requests
    < x-envoy-ratelimited: true
    < x-ratelimit-limit: 1, 1;w=60
    < x-ratelimit-remaining: 0
    < x-ratelimit-reset: 48
    < date: Thu, 26 Oct 2023 04:10:11 GMT
    < server: istio-envoy
    < content-length: 0
    < 
    * Connection #0 to host 116.62.XXX.XXX left intact

    在全局限流配置中,限制1分钟之内只能有一次访问bookinfo应用的请求。当连续两次访问bookinfo应用时,可以看到第一条请求成功,第二条请求被限流,表明对入口网关的特定路由配置全局限流成功。

场景二:对入口网关的域名和端口组合配置全局限流

bf2.example.com:80这个域名和端口组合配置全局限流规则。配置限流规则后,发往该域名和端口组合的请求都将受到流量速率的限制。

  1. 使用以下内容,创建global-ratelimit-gw.yaml。

    展开查看global-ratelimit-gw.yaml

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      workloadSelector:
        labels:
          istio: ingressgateway
      rateLimitService: # 准备工作中部署的限流服务的配置。
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      isGateway: true
      configs:
      - name: productpage
        limit:
          unit: MINUTE
          quota: 1
        match:
          vhost:
            name: bf2.example.com # 该名称需要和VirtualService下的域名一致。
            port: 80 # 该端口号需要和ASM网关端口匹配。

    部分字段说明如下。关于字段的更多信息,请参见ASMGlobalRateLimiter CRD说明

    字段

    说明

    workloadSelector

    用于匹配限流生效的工作负载。本示例全局限流生效于ingressgateway入口网关,设置为istio: ingressgateway

    isGateway

    是否作用于网关。本示例中设定为true

    rateLimitService

    限流服务的域名、端口和连接超时设置。根据准备工作中部署的限流服务,配置如下:

        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5

    limit

    需要生效的限流配置参数。其中unit表示限流检测的时间单位,quota表示单位时间内允许的请求总量。

    本示例配置unitMINUTEquota1,表示匹配路由上每分钟只能发送一个请求,超出的请求将被限流。

    vhost

    限流匹配的域名和路由项配置。其中nameport需要分别和应用于网关的虚拟服务中的域名以及入口网关端口匹配。

  2. 在ASM实例对应的KubeConfig环境下,执行以下命令,创建生效于网关上productpage-route-name1路由项的全局限流规则。

    kubectl apply -f global-ratelimit-gw.yaml
  3. 执行以下命令,获取调谐完成的全局限流规则配置内容。

    kubectl get asmglobalratelimiter global-test -n istio-system -o yaml

    展开查看预期输出

    apiVersion: istio.alibabacloud.com/v1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      configs:
      - limit:
          quota: 1
          unit: MINUTE
        match:
          vhost:
            name: bf2.example.com
            port: 80
        name: productpage
      isGateway: true
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      workloadSelector:
        labels:
          istio: ingressgateway
    status:
      config.yaml: |
        descriptors:
        - key: generic_key
          rate_limit:
            requests_per_unit: 1
            unit: MINUTE
          value: RateLimit[global-test.istio-system]-Id[2100900480]
        domain: ratelimit.default.svc.cluster.local
      message: ok
      status: successful
  4. 将上一步预期输出的ASMGlobalRateLimiter资源中status字段的config.yaml内容,粘贴至ratelimit-config.yaml,生成全局限流服务配置。

    ASMGlobalRateLimiter中status字段下的config.yaml字段中的字符串内容,需原样粘贴至ConfigMap中data中的同名config.yaml字段中。

    展开查看ratelimit-config.yaml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ratelimit-config
    data:
      config.yaml: |
        descriptors:
        - key: generic_key
          rate_limit:
            requests_per_unit: 1
            unit: MINUTE
          value: RateLimit[global-test.istio-system]-Id[2100900480]
        domain: ratelimit.default.svc.cluster.local
  5. 在ACK集群对应的KubeConfig环境下,执行以下命令,在集群中更新全局限流服务配置。

    kubectl apply -f ratelimit-config.yaml
  6. 执行以下命令,连续访问bookinfo应用两次。

    请将<ASM网关IP>替换为实际网关IP。关于如何获取网关IP,请参见获取入口网关地址

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

    第二次访问bookinfo应用的预期输出如下:

    < HTTP/1.1 429 Too Many Requests
    < x-envoy-ratelimited: true
    < x-ratelimit-limit: 1, 1;w=60
    < x-ratelimit-remaining: 0
    < x-ratelimit-reset: 48
    < date: Thu, 26 Oct 2023 04:10:11 GMT
    < server: istio-envoy
    < content-length: 0
    < 
    * Connection #0 to host 116.62.XXX.XXX left intact

    在全局限流配置中,对于bf2.example.com:80这一域名端口组合,限制1分钟之内只能有一次请求访问。当连续两次访问该域名端口组合时,可以看到第一条请求成功,第二条请求被限流,表明对入口网关域名端口组合的全局限流配置成功。

场景三:在入口网关特定虚拟服务路由上,针对包含特定请求头和查询参数的请求配置限流规则

说明

此场景需要ASM实例版本为1.19.0及以上。关于升级版本的具体操作,请参见升级ASM实例

bf2.example.com:80这个域名和端口组合下的productpage-route-name1路由配置限流规则,同时指定限流规则只生效在带有ratelimit: "true"请求头、且请求路径上带有查询参数ratelimit=enabled的请求上,该路由上的其他请求不受限流规则影响。匹配请求的/productpage/static/login/logout等路径并将匹配的请求转发到productpage服务。配置限流规则后,发往上述路径的请求都将收到流量速率的限制。

  1. 使用以下内容,创建global-ratelimit-gw.yaml。

    展开查看global-ratelimit-gw.yaml

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      workloadSelector:
        labels:
          app: istio-ingressgateway
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      isGateway: true
      configs:
      - name: productpage
        limit:
          unit: SECOND
          quota: 100000
        match:
          vhost:
            name: bf2.example.com
            port: 80
            route:
              name_match: productpage-route-name1  # 该名称需要和virtualservice下的route name一致。
        limit_overrides:
        - request_match:
            header_match:
            - name: ratelimit
              exact_match: "true"
            query_match:
            - name: ratelimit
              exact_match: "enabled"
          limit:
            unit: MINUTE
            quota: 1

    部分字段说明如下。关于字段的更多信息,请参见ASMGlobalRateLimiter CRD说明

    字段

    说明

    workloadSelector

    用于匹配限流生效的工作负载。本示例全局限流生效于ingressgateway入口网关,设置为istio: ingressgateway

    isGateway

    是否作用于网关。本示例中设定为true

    rateLimitService

    限流服务的域名、端口和连接超时设置。根据准备工作中部署的限流服务,配置如下:

        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5

    limit

    在虚拟服务路由上生效的限流配置参数。其中unit表示限流检测的时间单位,quota表示单位时间内允许的请求总量。本示例配置unitSECONDquota100000,表示匹配路由上每秒允许发送100000个请求。此设定约等于没有配置限流,只希望满足指定条件的请求被限流,其余请求不需要触发限流。

    vhost

    限流匹配的域名和路由项配置。其中nameport需要分别和应用于网关的虚拟服务中的域名以及入口网关端口匹配,route.name_match中填写的路由名称需要与虚拟服务中路由项的名称一致。

    limit_overrides

    限流阈值覆盖配置。可通过该字段针对特定的请求指定单独的限流阈值。在本示例中:

    • limit_overrides中的request_match字段被设定为精确匹配含有ratelimit: "true"请求头、且请求路径上带有查询参数ratelimit=enabled的请求。

    • limit_overrides中的limit字段配置unitMINUTEquota1,表示对于满足request_match指定的条件的请求,每分钟只允许发送一个。

  2. 在ASM实例对应的KubeConfig环境下,执行以下命令,创建生效于网关上productpage-route-name1路由项的全局限流规则。

    kubectl apply -f global-ratelimit-gw.yaml
  3. 执行以下命令,获取调谐完成的全局限流规则配置内容。

    kubectl get asmglobalratelimiter global-test -n istio-system -o yaml

    展开查看预期输出

    apiVersion: istio.alibabacloud.com/v1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      configs:
      - limit:
          quota: 100000
          unit: SECOND
        limit_overrides:
        - limit:
            quota: 1
            unit: MINUTE
          request_match:
            header_match:
            - exact_match: "true"
              name: ratelimit
            query_match:
            - exact_match: enabled
              name: ratelimit
        match:
          vhost:
            name: bf2.example.com
            port: 80
            route:
              name_match: productpage-route-name1
        name: productpage
      isGateway: true
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      workloadSelector:
        labels:
          app: istio-ingressgateway
    status:
      config.yaml: |
        descriptors:
        - descriptors:
          - descriptors:
            - key: query_match
              rate_limit:
                requests_per_unit: 1
                unit: MINUTE
              value: RateLimit[global-test.istio-system]-Id[1102463266]
            key: header_match
            value: RateLimit[global-test.istio-system]-Id[1102463266]
          key: generic_key
          rate_limit:
            requests_per_unit: 100000
            unit: SECOND
          value: RateLimit[global-test.istio-system]-Id[1102463266]
        domain: ratelimit.default.svc.cluster.local
      message: ok
      status: successful
  4. 将上一步预期输出的ASMGlobalRateLimiter资源中status字段的config.yaml内容,粘贴至ratelimit-config.yaml,生成全局限流服务配置。

    ASMGlobalRateLimiter中status字段下的config.yaml字段中的字符串内容,需原样粘贴至ConfigMap中data中的同名config.yaml字段中。

    展开查看ratelimit-config.yaml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ratelimit-config
    data:
      config.yaml: |
        descriptors:
        - descriptors:
          - descriptors:
            - key: query_match
              rate_limit:
                requests_per_unit: 1
                unit: MINUTE
              value: RateLimit[global-test.istio-system]-Id[1102463266]
            key: header_match
            value: RateLimit[global-test.istio-system]-Id[1102463266]
          key: generic_key
          rate_limit:
            requests_per_unit: 100000
            unit: SECOND
          value: RateLimit[global-test.istio-system]-Id[1102463266]
        domain: ratelimit.default.svc.cluster.local
  5. 在ACK集群对应的KubeConfig环境下,执行以下命令,在集群中更新全局限流服务配置。

    kubectl apply -f ratelimit-config.yaml
  6. 执行以下命令,连续访问bookinfo应用两次。

    请将<ASM网关IP>替换为实际网关IP。关于如何获取网关IP,请参见获取入口网关地址

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

    第二次访问bookinfo应用的预期输出如下:

    < HTTP/1.1 429 Too Many Requests
    < x-envoy-ratelimited: true
    < x-ratelimit-limit: 1, 1;w=60
    < x-ratelimit-remaining: 0
    < x-ratelimit-reset: 48
    < date: Thu, 26 Oct 2023 04:10:11 GMT
    < server: istio-envoy
    < content-length: 0
    < 
    * Connection #0 to host 116.62.XXX.XXX left intact

    在全局限流配置中,限制对于含有ratelimit: "true"请求头、且请求路径上带有查询参数ratelimit=enabled的请求,1分钟之内只能有一次访问bookinfo应用的请求。当携带上述的请求头和请求查询参数连续两次访问bookinfo应用时,可以看到第一条请求成功,第二条请求被限流,表明对入口网关的匹配特定请求的全局限流配置成功。

  7. 执行以下命令,请求中不携带ratelimit: "true"请求头和查询参数ratelimit=enabled,再次访问bookinfo应用。

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

    可以看到bookinfo应用正常访问,没有出现429状态码,说明路由上的其他请求没有受到全局限流影响。

场景四:在入口网关特定虚拟服务路由上,针对特定客户端的IP地址进行限流

说明
  • 此场景需要ASM实例版本为1.19.0及以上。关于升级版本的具体操作,请参见升级ASM实例

  • 要在ASM入口网关上配置针对特定客户端IP地址进行限流,需要首先保证ASM入口网关的外部流量策略设定为Local。关于创建入口网关的具体操作和配置项说明,请参见创建入口网关

  • 您可以在网关的访问日志中,通过downstream_remote_address字段获取发往网关的请求的客户端IP地址。在此示例中,请根据您需要限流的实际客户端IP地址进行配置。

bf2.example.com:80这个域名和端口组合下的productpage-route-name1虚拟服务路由配置限流规则,同时指定限流规则只生效在来自特定客户端IP地址的请求上,该路由上的其他请求不受限流规则影响。

  1. 使用以下内容,创建global-ratelimit-gw.yaml。

    展开查看global-ratelimit-gw.yaml

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      workloadSelector:
        labels:
          app: istio-ingressgateway
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      isGateway: true
      configs:
      - name: productpage
        limit:
          unit: SECOND
          quota: 100000
        match:
          vhost:
            name: bf2.example.com
            port: 80
            route:
              name_match: productpage-route-name1  # 该名称需要和virtualservice下的route name一致。
        limit_overrides:
        - request_match:
            remote_address:
              address: xxx.xxx.xxx.xxx #客户端IP地址。
              v4_prefix_mask_len: xx #客户端IP范围子网掩码。
          limit:
            unit: MINUTE
            quota: 1

    部分字段说明如下。关于字段的更多信息,请参见ASMGlobalRateLimiter CRD说明

    字段

    说明

    workloadSelector

    用于匹配限流生效的工作负载。本示例全局限流生效于ingressgateway入口网关,设置为istio: ingressgateway

    isGateway

    是否作用于网关。本示例中设定为true

    rateLimitService

    限流服务的域名、端口和连接超时设置。根据准备工作中部署的限流服务,配置如下:

        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5

    limit

    在虚拟服务路由上生效的限流配置参数。其中unit表示限流检测的时间单位,quota表示单位时间内允许的请求总量。

    本示例配置unitSECONDquota100000,表示匹配路由上每秒允许发送100000个请求。此设定约等于没有配置限流,只希望满足指定条件的请求被限流,其余请求不需要触发限流。

    vhost

    限流匹配的域名和路由项配置。其中nameport需要分别和应用于网关的虚拟服务中的域名以及入口网关端口匹配,route.name_match中填写的路由名称需要与虚拟服务中路由项的名称一致。

    limit_overrides

    限流阈值覆盖配置。可通过该字段针对特定的请求指定单独的限流阈值。在本示例中:

    • request_match字段中,通过remote_address.address匹配请求的客户端源IP,通过remote_addess.v4_prefix_mask_len匹配客户端源IP的地址范围子网掩码(可选)。

    • limit_overrides字段中的limit字段配置unitMINUTEquota1,表示对于满足request_match指定的条件的请求,每分钟只允许发送一个。

  2. 在ASM实例对应的KubeConfig环境下,执行以下命令,创建生效于网关上productpage-route-name1路由项的全局限流规则。

    kubectl apply -f global-ratelimit-gw.yaml
  3. 执行以下命令,获取调谐完成的全局限流规则配置内容。

    kubectl get asmglobalratelimiter global-test -n istio-system -o yaml

    展开查看预期输出

    apiVersion: istio.alibabacloud.com/v1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      configs:
      - limit:
          quota: 100000
          unit: SECOND
        limit_overrides:
        - limit:
            quota: 1
            unit: MINUTE
          request_match:
            remote_address:
              address: 106.11.XX.XX
              v4_prefix_mask_len: 24
        match:
          vhost:
            name: bf2.example.com
            port: 80
            route:
              name_match: productpage-route-name1
        name: productpage
      isGateway: true
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      workloadSelector:
        labels:
          app: istio-ingressgateway
    status:
      config.yaml: |
        descriptors:
        - descriptors:
          - key: masked_remote_address
            rate_limit:
              requests_per_unit: 1
              unit: MINUTE
            value: xxxxxx
          key: generic_key
          rate_limit:
            requests_per_unit: 100000
            unit: SECOND
          value: RateLimit[global-test.istio-system]-Id[1102463266]
        domain: ratelimit.default.svc.cluster.local
      message: ok
      status: successful
  4. 将上一步预期输出的ASMGlobalRateLimiter资源中status字段的config.yaml内容,粘贴至ratelimit-config.yaml,生成全局限流服务配置。

    ASMGlobalRateLimiter中status字段下的config.yaml字段中的字符串内容,需原样粘贴至ConfigMap中data中的同名config.yaml字段中。

    展开查看ratelimit-config.yaml

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ratelimit-config
    data:
      config.yaml: |
        descriptors:
        - descriptors:
          - key: masked_remote_address
            rate_limit:
              requests_per_unit: 1
              unit: MINUTE
            value: xxxxxx
          key: generic_key
          rate_limit:
            requests_per_unit: 100000
            unit: SECOND
          value: RateLimit[global-test.istio-system]-Id[1102463266]
        domain: ratelimit.default.svc.cluster.local
  5. 在ACK集群对应的KubeConfig环境下,执行以下命令,在集群中更新全局限流服务配置。

    kubectl apply -f ratelimit-config.yaml
  6. 执行以下命令,连续访问bookinfo应用两次。

    请将<ASM网关IP>替换为实际网关IP。关于如何获取网关IP,请参见获取入口网关地址

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

    第二次访问bookinfo应用的预期输出如下:

    < HTTP/1.1 429 Too Many Requests
    < x-envoy-ratelimited: true
    < x-ratelimit-limit: 1, 1;w=60
    < x-ratelimit-remaining: 0
    < x-ratelimit-reset: 48
    < date: Thu, 26 Oct 2023 04:10:11 GMT
    < server: istio-envoy
    < content-length: 0
    < 
    * Connection #0 to host 116.62.XXX.XXX left intact

    在全局限流配置中,限制来自特定IP地址(或地址范围)的请求,1分钟之内只能有一次访问bookinfo应用的请求。当使用特定IP地址的客户端访问网关时,可以看到第一条请求成功,第二条请求被限流,表明对入口网关的全局限流配置成功。

  7. 执行以下命令,使用不同IP地址的客户端,再次访问bookinfo应用。

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

    可以看到bookinfo应用正常访问,没有出现429状态码,说明路由上的其他请求没有受到全局限流影响。

相关文档