All Products
Search
Document Center

Alibaba Cloud Service Mesh:Configure global throttling on an ingress gateway

Last Updated:Mar 05, 2024

You can configure global throttling for a specific route of an ingress gateway to implement precise control over traffic to cope with issues such as traffic bursts, service overload, resource exhaustion, and malicious attacks. This protects the stability of backend services, reduces costs, and improves user experience.

Prerequisites

  • A Container Service for Kubernetes (ACK) managed cluster is added to your ASM instance. The version of the ASM instance is 1.18.0.131 or later. For more information, see Add a cluster to an ASM instance.

  • Automatic sidecar proxy injection is enabled for the default namespace in the ACK cluster. For more information, see the "Enable automatic sidecar proxy injection" section of the Manage global namespaces topic.

  • An ingress gateway named ingressgateway is created and port 80 is enabled. For more information, see Create an ingress gateway.

Preparations

1. Deploy a throttling service

  1. Create a ratelimit-svc.yaml file that contains the following content:

    Show the ratelimit-svc.yaml file

    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. Use kubectl to connect to the ACK cluster based on the information in the kubeconfig file, and then run the following command to create a throttling service and the Redis service on which the throttling service depends.

    For more information about how to use kubectl to connect to an ACK cluster, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.

    kubectl apply -f ratelimit-svc.yaml

2. Deploy a sample application, Bookinfo

  1. Download the bookinfo.yaml file of the Bookinfo application from the Istio repository on GitHub.

  2. Use kubectl to connect to the ACK cluster based on the information in the kubeconfig file, and then run the following command to deploy the Bookinfo application in the ACK cluster that is added to your ASM instance:

    kubectl apply -f bookinfo.yaml
  3. Create a bookinfo-gateway.yaml that contains the following content:

    Show the bookinfo-gateway.yaml file

    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. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create a routing rule for the Bookinfo application on the ingressgateway ingress gateway.

    The name of the routing rule is productpage-route-name1 and the rule matches requests with the bf2.example.com domain name. For more information about how to use kubectl to connect to an ASM instance, see Use kubectl on the control plane to access Istio resources.

    kubectl apply -f bookinfo-gateway.yaml

Scenario 1: Configure a global throttling rule for a specific ingress gateway route

Configure a throttling rule for the productpage-route-name1 route of the domain:port combination bf2.example.com:80. productpage-route-name1 is a route of the virtual service created for the Bookinfo service mentioned in the Prerequisites section. The productpage-route-name1 route is matched when a request is destined for one of the following paths: /productpage, /static, /login, and /logout. The request is then forwarded to the productpage service. After you configure the global throttling rule, requests destined for the preceding paths are subject to throttling.

  1. Create a global-ratelimit-gw.yaml file that contains the following content:

    Show the global-ratelimit-gw.yaml file

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      workloadSelector:
        labels:
          istio: ingressgateway
      rateLimitService: # The throttling service that you deployed. 
        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 # The name must be the same as the domain name in the virtual service. 
            port: 80 # The port number must be the same as the port of the ingress gateway. 
            route:
              name_match: productpage-route-name1 # The name must be the same as the name of the routing rule in the virtual service.

    The following table describes some of the fields. For more information, see Description of ASMGlobalRateLimiter fields.

    Field

    Description

    workloadSelector

    The workload on which the global throttling rule takes effect. In this example, global throttling needs to take effect on the ingressgateway ingress gateway. Configure istio: ingressgateway in this field.

    isGateway

    Specifies whether the global throttling rule takes effect on the gateway. In this example, the value is set to true.

    rateLimitService

    The domain name, port, and connection timeout settings of the throttling service. The following code block shows the settings of the throttling service deployed in Preparations:

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

    limit

    The throttling parameters to take effect. unit indicates the unit of time for throttling detection. quota indicates the total number of requests allowed per unit time.

    In this example, unit is set to MINUTE and quota is set to 1. This indicates that only one request can be sent per minute on the matching route. If the number of requests exceeds one, throttling is triggered.

    vhost

    The configurations of the domain name and route on which throttling takes effect. The values of name and port must be consistent with the domain name and port in the virtual service for the ingress gateway. The name of the route specified by route.name_match must be the same as the name of the route in the virtual service.

  2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create a global throttling rule that takes effect on the productpage-route-name1 route of the ingress gateway:

    kubectl apply -f global-ratelimit-gw.yaml
  3. Run the following command to obtain the configuration of the global throttling rule:

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

    Show the expected output

    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. Copy and paste the content of the config.yaml field in the status section in ASMGlobalRateLimiter that is generated in the previous step to the ratelimit-config.yaml file to generate the global throttling service configurations.

    The string content in the config.yaml field in the status section in ASMGlobalRateLimiter must be pasted to the config.yaml field in the data section in ConfigMap without changes.

    Show the ratelimit-config.yaml file

    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. Use kubectl to connect to the ACK cluster based on the information in the kubeconfig file, and then run the following command to update the global throttling service configuration in the ACK cluster:

    kubectl apply -f ratelimit-config.yaml
  6. Run the following commands to access the Bookinfo application twice.

    Replace <IP address of the ingress gateway> with the IP address of the desired ingress gateway. For more information about how to obtain the IP address of the ingress gateway, see substep 1 of Step 3 in the Use Istio resources to route traffic to different versions of a service topic.

    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v
    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v

    The following code block shows the expected output for the second access to the Bookinfo application:

    < 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

    In the global throttling configuration, only one request is allowed to access the Bookinfo application within one minute. When you access the Bookinfo application twice within one minute, you can see that the first request is successful and throttling is triggered on the second request. This indicates that global throttling takes effect on the specific ingress gateway route.

Scenario 2: Configure a global throttling rule for a specific domain name and a specific port on an ingress gateway

Configure a global throttling rule for the domain:port combination bf2.example.com:80. After you configure the global throttling rule, requests destined for the domain name and port are subject to throttling.

  1. Create a global-ratelimit-gw.yaml file that contains the following content:

    Show the global-ratelimit-gw.yaml file

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-test
      namespace: istio-system
    spec:
      workloadSelector:
        labels:
          istio: ingressgateway
      rateLimitService: # The throttling service that you deployed. 
        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 # The name must be the same as the domain name in the virtual service. 
            port: 80 # The port number must be the same as the port of the ingress gateway.

    The following table describes some of the fields. For more information, see Description of ASMGlobalRateLimiter fields.

    Field

    Description

    workloadSelector

    The workload on which the global throttling rule takes effect. In this example, global throttling needs to take effect on the ingressgateway ingress gateway. Configure istio: ingressgateway in this field.

    isGateway

    Specifies whether the global throttling rule takes effect on the gateway. In this example, the value is set to true.

    rateLimitService

    The domain name, port, and connection timeout settings of the throttling service. The following code block shows the settings of the throttling service deployed in Preparations:

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

    limit

    The throttling parameters to take effect. unit indicates the unit of time for throttling detection. quota indicates the total number of requests allowed per unit time.

    In this example, unit is set to MINUTE and quota is set to 1. This indicates that only one request can be sent per minute on the matching route. If the number of requests exceeds one, throttling is triggered.

    vhost

    The configurations of the domain name and route on which throttling takes effect. The values of name and port must be consistent with the domain name and port in the virtual service for the ingress gateway.

  2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create a global throttling rule that takes effect on the productpage-route-name1 route of the ingress gateway:

    kubectl apply -f global-ratelimit-gw.yaml
  3. Run the following command to obtain the configuration of the global throttling rule:

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

    Show the expected output

    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. Copy and paste the content of the config.yaml field in the status section in ASMGlobalRateLimiter that is generated in the previous step to the ratelimit-config.yaml file to generate the global throttling service configurations.

    The string content in the config.yaml field in the status section in ASMGlobalRateLimiter must be pasted to the config.yaml field in the data section in ConfigMap without changes.

    Show the ratelimit-config.yaml file

    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. Use kubectl to connect to the ACK cluster based on the information in the kubeconfig file, and then run the following command to update the global throttling service configuration in the ACK cluster:

    kubectl apply -f ratelimit-config.yaml
  6. Run the following commands to access the Bookinfo application twice.

    Replace <IP address of the ingress gateway> with the IP address of the desired ingress gateway. For more information about how to obtain the IP address of the ingress gateway, see substep 1 of Step 3 in the Use Istio resources to route traffic to different versions of a service topic.

    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v
    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v

    The following code block shows the expected output for the second access to the Bookinfo application:

    < 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

    In the global throttling configuration, only one request is allowed to access bf2.example.com:80 within one minute. When you access bf2.example.com:80 twice within one minute, you can see that the first request is successful and throttling is triggered on the second request. This indicates that global throttling takes effect on the specific domain name and port.

Scenario 3: Configure a global throttling rule for requests that contain specific headers and query parameters on a specific route in the virtual service for the ingress gateway

Note

In this scenario, the version of the ASM instance must be 1.19.0 or later. For more information about how to upgrade an ASM instance, see Update an ASM instance.

Configure a throttling rule for the productpage-route-name1 route of the domain:port combination bf2.example.com:80 and specify that the throttling rule takes effect on only requests with the ratelimit: "true" header and the ratelimit=enabled query parameter. Other requests on the route are not subject to the throttling rule. The productpage-route-name1 route is matched when a request is destined for one of the following paths: /productpage, /static, /login, and /logout. The request is then forwarded to the productpage service. After you configure the global throttling rule, requests destined for the preceding paths are subject to throttling.

  1. Create a global-ratelimit-gw.yaml file that contains the following content:

    Show the global-ratelimit-gw.yaml file

    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 # The name must be the same as the name of the routing rule in the virtual service. 
        limit_overrides:
        - request_match:
            header_match:
            - name: ratelimit
              exact_match: "true"
            query_match:
            - name: ratelimit
              exact_match: "enabled"
          limit:
            unit: MINUTE
            quota: 1

    The following table describes some of the fields. For more information, see Description of ASMGlobalRateLimiter fields.

    Field

    Description

    workloadSelector

    The workload on which the global throttling rule takes effect. In this example, global throttling needs to take effect on the ingressgateway ingress gateway. Configure istio: ingressgateway in this field.

    isGateway

    Specifies whether the global throttling rule takes effect on the gateway. In this example, the value is set to true.

    rateLimitService

    The domain name, port, and connection timeout settings of the throttling service. The following code block shows the settings of the throttling service deployed in Preparations:

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

    limit

    The throttling parameters to take effect on the route specified in the virtual service. unit indicates the unit of time for throttling detection. quota indicates the total number of requests allowed per unit time. In this example, unit is set to SECOND and quota is set to 100000. This indicates that 100,000 requests are allowed to be sent per second on the matching route. In this case, throttling is triggered only on requests that meet the specified requirements.

    vhost

    The configurations of the domain name and route on which throttling takes effect. The values of name and port must be consistent with the domain name and port in the virtual service for the ingress gateway. The name of the route specified by route.name_match must be the same as the name of the route in the virtual service.

    limit_overrides

    Specifies whether to override the configured throttling threshold. You can use this field to specify a throttling threshold individually for specific requests. In this example:

    • The request_match field in the limit_overrides section specifies that requests must match the following criteria: Requests must contain the ratelimit: "true" header and have the ratelimit=enabled query parameter on the request path.

    • In the limit field in the limit_overrides section, unit is set to MINUTE and quota is set to 1. This indicates that you can send only one request that matches the criteria specified by the request_match field per minute.

  2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create a global throttling rule that takes effect on the productpage-route-name1 route of the ingress gateway:

    kubectl apply -f global-ratelimit-gw.yaml
  3. Run the following command to obtain the configuration of the global throttling rule:

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

    Show the expected output

    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. Copy and paste the content of the config.yaml field in the status section in ASMGlobalRateLimiter that is generated in the previous step to the ratelimit-config.yaml file to generate the global throttling service configurations.

    The string content in the config.yaml field in the status section in ASMGlobalRateLimiter must be pasted to the config.yaml field in the data section in ConfigMap without changes.

    Show the ratelimit-config.yaml file

    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. Use kubectl to connect to the ACK cluster based on the information in the kubeconfig file, and then run the following command to update the global throttling service configuration in the ACK cluster:

    kubectl apply -f ratelimit-config.yaml
  6. Run the following commands to access the Bookinfo application twice.

    Replace <IP address of the ingress gateway> with the IP address of the desired ingress gateway. For more information about how to obtain the IP address of the ingress gateway, see substep 1 of Step 3 in the Use Istio resources to route traffic to different versions of a service topic.

    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v
    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v

    The following code block shows the expected output for the second access to the Bookinfo application:

    < 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

    In the global throttling configuration, only one request is allowed to access the Bookinfo application within one minute. The request must contain the ratelimit: "true" header and have the ratelimit=enabled query parameter on the request path. When you access the Bookinfo application twice within one minute, you can see that the first request is successful and throttling is triggered on the second request. This indicates that global throttling takes effect on the requests that contain specific headers and query parameters on a specific route in the virtual service for the ingress gateway.

  7. Run the following command to access the Bookinfo application again by sending a request that does not contain the ratelimit: "true" header or the ratelimit=enabled query parameter:

    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v

    The output indicates that no 429 status code is found and the Bookinfo application is successfully accessed. This indicates that other requests on the route are not subject to the global throttling rule.

Scenario 4: Configure a global throttling rule for a specific client IP address on a specific route in the virtual service for the ingress gateway

Note
  • In this scenario, the version of the ASM instance must be 1.19.0 or later. For more information about how to upgrade an ASM instance, see Update an ASM instance.

  • To configure throttling for a specific client IP address on the ingress gateway, you must ensure that External Traffic Policy of the ingress gateway is set to Local. For more information about how to create an ingress gateway and the description of the ingress gateway parameters, see Create an ingress gateway.

  • You can obtain the client IP address from which a request is sent to the ingress gateway from the downstream_remote_address field in the access log of the ingress gateway. In this example, set the client IP address to the one for which you want to apply the throttling rule.

Configure a throttling rule for the productpage-route-name1 route of the domain:port combination bf2.example.com:80 and specify that the throttling rule takes effect on only requests that are sent from the specific client IP address. Other requests on the route are not subject to the throttling rule.

  1. Create a global-ratelimit-gw.yaml file that contains the following content:

    Show the global-ratelimit-gw.yaml file

    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 # The name must be the same as the name of the routing rule in the virtual service. 
        limit_overrides:
        - request_match:
            remote_address:
              address: xxx.xxx.xxx.xxx # The IP address of the client. 
              v4_prefix_mask_len: xx # The subnet mask length of the IPv4 CIDR block in which the IP address of the client falls. 
          limit:
            unit: MINUTE
            quota: 1

    The following table describes some of the fields. For more information, see Description of ASMGlobalRateLimiter fields.

    Field

    Description

    workloadSelector

    The workload on which the global throttling rule takes effect. In this example, global throttling needs to take effect on the ingressgateway ingress gateway. Configure istio: ingressgateway in this field.

    isGateway

    Specifies whether the global throttling rule takes effect on the gateway. In this example, the value is set to true.

    rateLimitService

    The domain name, port, and connection timeout settings of the throttling service. The following code block shows the settings of the throttling service deployed in Preparations:

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

    limit

    The throttling parameters to take effect on the route specified in the virtual service. unit indicates the unit of time for throttling detection. quota indicates the total number of requests allowed per unit time.

    In this example, unit is set to SECOND and quota is set to 100000. This indicates that 100,000 requests are allowed to be sent per second on the matching route. In this case, throttling is triggered only on requests that meet the specified requirements.

    vhost

    The configurations of the domain name and route on which throttling takes effect. The values of name and port must be consistent with the domain name and port in the virtual service for the ingress gateway. The name of the route specified by route.name_match must be the same as the name of the route in the virtual service.

    limit_overrides

    Specifies whether to override the configured throttling threshold. You can use this field to specify a throttling threshold individually for specific requests. In this example:

    • The remote_address.address field in the request_match section is used to match the client IP address of a request. The remote_addess.v4_prefix_mask_len field is used to match the IPv4 CIDR block in which the IP address of the client falls. The remote_addess.v4_prefix_mask_len field is optional.

    • In the limit field in the limit_overrides section, unit is set to MINUTE and quota is set to 1. This indicates that you can send only one request that matches the criteria specified by the request_match field per minute.

  2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create a global throttling rule that takes effect on the productpage-route-name1 route of the ingress gateway:

    kubectl apply -f global-ratelimit-gw.yaml
  3. Run the following command to obtain the configuration of the global throttling rule:

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

    Show the expected output

    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. Copy and paste the content of the config.yaml field in the status section in ASMGlobalRateLimiter that is generated in the previous step to the ratelimit-config.yaml file to generate the global throttling service configurations.

    The string content in the config.yaml field in the status section in ASMGlobalRateLimiter must be pasted to the config.yaml field in the data section in ConfigMap without changes.

    Show the ratelimit-config.yaml file

    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. Use kubectl to connect to the ACK cluster based on the information in the kubeconfig file, and then run the following command to update the global throttling service configuration in the ACK cluster:

    kubectl apply -f ratelimit-config.yaml
  6. Run the following commands to access the Bookinfo application twice.

    Replace <IP address of the ingress gateway> with the IP address of the desired ingress gateway. For more information about how to obtain the IP address of the ingress gateway, see substep 1 of Step 3 in the Use Istio resources to route traffic to different versions of a service topic.

    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v
    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v

    The following code block shows the expected output for the second access to the Bookinfo application:

    < 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

    In the global throttling configuration, only one request is allowed to access the Bookinfo application within one minute. The request must be sent from specific IP addresses or CIDR blocks. When you use a client that uses a specific IP address to access the ingress gateway, the first request is successful and throttling is triggered on the second request. This indicates that global throttling takes effect on the requests that are sent from the specific IP address.

  7. Run the following command to access the Bookinfo application again by using a different IP address:

    curl -H 'host: bf2.example.com'  http://<IP address of the ingress gateway>/productpage -v

    The output indicates that no 429 status code is found and the Bookinfo application is successfully accessed. This indicates that other requests on the route are not subject to the global throttling rule.

References