All Products
Search
Document Center

Alibaba Cloud Service Mesh:Use ASMGlobalRateLimiter to configure global rate limiting for inbound traffic to application services

Last Updated:Aug 28, 2026

Rate limiting caps the number of requests a client can send to a server in a given period, such as 300 per minute or 10 per second. Use ASMGlobalRateLimiter in Alibaba Cloud Service Mesh (ASM) to apply global rate limits to inbound traffic of application services with injected sidecars.

Envoy proxies implement rate limiting in two ways: global rate limiting and local rate limiting. This topic covers global rate limiting only. For rate limiting concepts and instructions for local rate limiting, see Configure local rate limiting in the Traffic Management Center.

Two scenarios in this topic show the granularities that a global rate limit can apply to an application service: all requests on a service port (Scenario 1), or only the requests that access a specific path on that port (Scenario 2). Both scenarios use the same ASMGlobalRateLimiter resource name (global-svc-test) and the same ConfigMap (ratelimit-config).

Prerequisites

Note

ASM supports configuring global rate limiting for inbound traffic to ingress gateways and to application services with injected sidecars in version 1.18.0.131 and later. The limit_overrides field, which Scenario 2 uses to rate-limit a specific path, is supported only by ASM instances of version 1.19.0 or later.

Deploy the rate-limiting service

Global rate limiting takes effect only after the rate-limiting service runs in the cluster on the data plane. Deploy the rate-limiting service and the Redis service that it depends on before you configure a rate limiting rule.

  1. Create a file named ratelimit-svc.yaml with the following content.

    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: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. In the kubeconfig context of the ACK cluster, run the following command to create the rate-limiting service and the Redis service that it depends on in the cluster.

    kubectl apply -f ratelimit-svc.yaml

Use the ASM-managed rate-limiting service (optional)

Note

This feature is supported only by ASM instances of version 1.25 or later. If your ASM instance is of a version earlier than 1.25, continue to deploy the rate-limiting service as described earlier and manually update the ConfigMap used by the rate-limiting service.

In ASM 1.25 and later, you can use ASMMeshConfig to enable the ASM-managed rate-limiting service. When you use this method, you do not need to configure rateLimitService when you create an ASMGlobalRateLimiter. ASM automatically uses the rate-limiting service delivered to the clusters on the data plane and automatically updates the ConfigMap used by the rate-limiting service based on the global rate limiting rules.

  1. Prepare the Redis on which the rate-limiting service depends. ASM deploys the rate-limiting service but does not deploy Redis. You can continue to use the Redis deployed earlier or use an existing Redis instance. To continue using ratelimit-svc.yaml from the preceding steps, deploy only the ServiceAccount, Service, and Deployment of Redis in it. Do not deploy the ratelimit-config ConfigMap, the ratelimit Service, or the ratelimit Deployment.

  2. In the kubeconfig context of the ASM instance, run the following command to verify that ASMMeshConfig/default exists.

    kubectl get asmmeshconfig default

    Create a file named ratelimit-service-patch.yaml. The following example uses the Redis deployed in the default namespace in the preceding steps.

    spec:
      rateLimitService:
        enabled: true
        replicas: 1
        redis:
          type: single
          url: redis.default.svc.cluster.local:6379

    Run the following command to enable the rate-limiting service with a merge patch to avoid overwriting other settings in ASMMeshConfig/default.

    kubectl patch asmmeshconfig default \
      --type=merge \
      --patch-file ratelimit-service-patch.yaml

    In this configuration, enabled must be set to true. replicas specifies the number of replicas of the rate-limiting service. redis.type supports single, cluster, and sentinel. redis.url must be a Redis address that is accessible from the rate-limiting service in the cluster on the data plane.

  3. When you create an ASMGlobalRateLimiter in the scenarios that follow, remove the spec.rateLimitService field entirely. Do not configure an empty object such as rateLimitService: {}. Keep the other rate limiting rule settings unchanged.

    If you omit spec.rateLimitService, ASM uses ratelimit.istio-system.svc.cluster.local:8081 by default and automatically creates or updates the istio-system/ratelimit-service-config ConfigMap in the ACK cluster. This ConfigMap is managed by ASM. Do not modify it manually.

    In the kubeconfig context of the ACK cluster, run the following command to view the automatically generated rate limiting configuration.

    kubectl -n istio-system get configmap ratelimit-service-config -o yaml
Note

The scenarios that follow still demonstrate the manual deployment method that is compatible with all ASM versions. If you use the ASM-managed rate-limiting service, omit rateLimitService as described in this section and skip the steps that copy the configuration from the status field and manually update the ConfigMap. All other rate limiting rule settings and verification methods remain unchanged.

Scenario 1: Configure global rate limiting for a service port

Apply a rate limit to port 8000 of the httpbin service. After you create the rate limiting rule, the rate limit applies to all requests that are sent to port 8000 of the httpbin service.

  1. Create a file named global-ratelimit-svc.yaml with the following content.

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-svc-test
      namespace: default
    spec:
      workloadSelector:
        labels:
          app: httpbin
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      isGateway: false
      configs:
      - name: httpbin
        limit:
          unit: MINUTE
          quota: 1
        match:
          vhost:
            name: '*'
            port: 8000

    The following table describes some of the fields. For a description of all fields, see ASMGlobalRateLimiter fields.

    Parameter

    Description

    workloadSelector

    Matches the workload on which the rate limit takes effect. In this scenario, global rate limiting takes effect on the workload of the httpbin service, so the value is set to app: httpbin.

    isGateway

    Specifies whether the configuration applies to a gateway. In this example, the value is set to false.

    rateLimitService

    The domain name, port, and connection timeout settings of the rate-limiting service. For the rate-limiting service deployed in Deploy the rate-limiting service, use the configuration that follows this table.

    limit

    The rate limiting parameters to take effect. unit specifies the time unit of rate limit detection, and quota specifies the total number of requests allowed within one unit of time. This example sets unit to MINUTE and quota to 1, which means that only one request per minute can be sent on the matched route. Excess requests are rate-limited.

    vhost

    The domain name and route settings that the rate limit matches. When the configuration takes effect on an application service, set name to '*' and set port to the Service port of the service.

    Use the following rateLimitService configuration:

    host: ratelimit.default.svc.cluster.local
    port: 8081
    timeout:
      seconds: 5
  2. In the kubeconfig context of the ASM instance, run the following command to create a global rate limiting rule that takes effect on inbound traffic to the httpbin application service.

    kubectl apply -f global-ratelimit-svc.yaml
  3. Run the following command to obtain the reconciled configuration of the global rate limiting rule.

    kubectl get asmglobalratelimiter global-svc-test -o yaml
    apiVersion: istio.alibabacloud.com/v1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-svc-test
      namespace: default
    spec:
      configs:
      - limit:
          quota: 1
          unit: MINUTE
        match:
          vhost:
            name: '*'
            port: 8000
        name: httpbin
      isGateway: false
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      workloadSelector:
        labels:
          app: httpbin
    status:
      config.yaml: |
        descriptors:
        - key: generic_key
          rate_limit:
            requests_per_unit: 1
            unit: MINUTE
          value: RateLimit[global-svc-test.default]-Id[3833670472]
        domain: ratelimit.default.svc.cluster.local
      message: ok
      status: successful
  4. Create a file named ratelimit-config.yaml to hold the configuration of the global rate-limiting service. Paste the string in the config.yaml field under the status field of the ASMGlobalRateLimiter resource, as it is, into the config.yaml field of the same name under data in the ConfigMap. This ConfigMap has the same name as the ratelimit-config ConfigMap in ratelimit-svc.yaml, so the pasted string replaces the initial empty configuration ({}).

    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-svc-test.default]-Id[3833670472]
        domain: ratelimit.default.svc.cluster.local

    The values in this sample come from the expected output in the previous step. Use the values returned for your own ASMGlobalRateLimiter resource, including the Id value in value.

  5. In the kubeconfig context of the ACK cluster, run the following command to update the configuration of the global rate-limiting service in the cluster.

    kubectl apply -f ratelimit-config.yaml
  6. Run the following command to start a bash session in the sleep application.

    kubectl exec -it deploy/sleep -- sh
  7. Run the following command to access the httpbin service twice in a row.

    curl httpbin:8000/get -v
    curl httpbin:8000/get -v

    The first request is allowed. The following output is returned for the second request:

    < HTTP/1.1 429
    < x-envoy-ratelimited: true
    < x-ratelimit-limit: 1, 1;w=60
    < x-ratelimit-remaining: 0
    < x-ratelimit-reset: 5
    < date: Thu, 26 Oct 2023 04:23:54 GMT
    < server: envoy
    < content-length: 0
    < x-envoy-upstream-service-time: 2
    < 
    * Connection #0 to host httpbin left intact

    The global rate limiting configuration allows only one request to the httpbin service within one minute, so the second request is rate-limited. Global rate limiting now takes effect on inbound traffic to the httpbin service port.

Scenario 2: Configure global rate limiting for a specific path on a service port

Apply a rate limit to port 8000 of the httpbin service, and restrict the rate limit so that it takes effect only on requests that access the /headers path. After you create the rate limiting rule, the rate limit applies to all requests that are sent to port 8000 of the httpbin service and that access the /headers path.

  1. Create a file named global-ratelimit-svc.yaml with the content that matches your ASM version.

    YAML for ASM versions earlier than 1.19.0

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-svc-test
      namespace: default
    spec:
      workloadSelector:
        labels:
          app: httpbin
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      isGateway: false
      configs:
      - name: httpbin
        limit:
          unit: MINUTE
          quota: 1
        match:
          vhost:
            name: '*'
            port: 8000
            route:
              header_match:
              - name: ":path"
                prefix_match: "/headers"

    YAML for ASM version 1.19.0 or later

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-svc-test
      namespace: default
    spec:
      workloadSelector:
        labels:
          app: httpbin
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      isGateway: false
      configs:
      - name: httpbin
        limit:
          unit: SECOND
          quota: 100000
        match:
          vhost:
            name: '*'
            port: 8000
        limit_overrides:
        - request_match:
            header_match:
            - name: ":path"
              prefix_match: "/headers"
          limit:
            unit: MINUTE
            quota: 1

    The following table describes some of the fields. For a description of all fields, see ASMGlobalRateLimiter fields.

    Parameter

    Description

    workloadSelector

    Matches the workload on which the rate limit takes effect. In this scenario, global rate limiting takes effect on the workload of the httpbin service, so the value is set to app: httpbin.

    isGateway

    Specifies whether the configuration applies to a gateway. In this example, the value is set to false.

    rateLimitService

    The domain name, port, and connection timeout settings of the rate-limiting service. For the rate-limiting service deployed in Deploy the rate-limiting service, use the configuration that follows this table.

    limit

    The rate limiting parameters to take effect. unit specifies the time unit of rate limit detection, and quota specifies the total number of requests allowed within one unit of time. For ASM instances of a version earlier than 1.19.0, this example sets unit to MINUTE and quota to 1, which means that only one request per minute can be sent on the matched route, and excess requests are rate-limited. For ASM instances of version 1.19.0 or later, the rate limiting parameters are set to 100,000 requests per second, which is roughly equivalent to no rate limiting, because the rate limit for requests that meet specific conditions takes effect in the limit_overrides field.

    vhost

    The domain name and route settings that the rate limit matches. When the configuration takes effect on an application service, set name to '*' and set port to the Service port of the service. For ASM instances of a version earlier than 1.19.0, you can also configure header matching rules for requests in route. This example matches the special header named :path, which matches the path of the request. In other words, the rule matches all requests whose path starts with /headers. For ASM instances of version 1.19.0 or later, the header matching rules for requests are moved from route to the limit_overrides field.

    limit_overrides

    The rate limit override configuration, which is supported only by ASM instances of version 1.19.0 or later. It supports matching different attributes of requests and applying a separate rate limiting configuration to the specific requests that are matched. In this example, the limit_overrides field specifies matching the special header :path, which matches the path of the request. In other words, the override matches all requests whose path starts with /headers.

    Use the following rateLimitService configuration:

    host: ratelimit.default.svc.cluster.local
    port: 8081
    timeout:
      seconds: 5
  2. In the kubeconfig context of the ASM instance, run the following command to create a global rate limiting rule that takes effect on inbound traffic to the httpbin application service.

    kubectl apply -f global-ratelimit-svc.yaml
  3. Run the following command to obtain the reconciled configuration of the global rate limiting rule.

    kubectl get asmglobalratelimiter global-svc-test -o yaml
    apiVersion: istio.alibabacloud.com/v1
    kind: ASMGlobalRateLimiter
    metadata:
      name: global-svc-test
      namespace: default
    spec:
      configs:
      - limit:
          quota: 100000
          unit: SECOND
        limit_overrides:
        - limit:
            quota: 1
            unit: MINUTE
          request_match:
            header_match:
            - name: :path
              prefix_match: /headers
        match:
          vhost:
            name: '*'
            port: 8000
        name: httpbin
      isGateway: false
      rateLimitService:
        host: ratelimit.default.svc.cluster.local
        port: 8081
        timeout:
          seconds: 5
      workloadSelector:
        labels:
          app: httpbin
    status:
      config.yaml: |
        descriptors:
        - descriptors:
          - key: header_match
            rate_limit:
              requests_per_unit: 1
              unit: MINUTE
            value: RateLimit[global-svc-test.default]-Id[2613586978]
          key: generic_key
          rate_limit:
            requests_per_unit: 100000
            unit: SECOND
          value: RateLimit[global-svc-test.default]-Id[2613586978]
        domain: ratelimit.default.svc.cluster.local
      message: ok
      status: successful
  4. Create a file named ratelimit-config.yaml to hold the configuration of the global rate-limiting service. Paste the string in the config.yaml field under the status field of the ASMGlobalRateLimiter resource, as it is, into the config.yaml field of the same name under data in the ConfigMap. This ConfigMap has the same name as the ratelimit-config ConfigMap in ratelimit-svc.yaml, so the pasted string replaces the initial empty configuration ({}).

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ratelimit-config
    data:
      config.yaml: |
        descriptors:
        - descriptors:
          - key: header_match
            rate_limit:
              requests_per_unit: 1
              unit: MINUTE
            value: RateLimit[global-svc-test.default]-Id[2613586978]
          key: generic_key
          rate_limit:
            requests_per_unit: 100000
            unit: SECOND
          value: RateLimit[global-svc-test.default]-Id[2613586978]
        domain: ratelimit.default.svc.cluster.local

    The values in this sample come from the expected output in the previous step. Use the values returned for your own ASMGlobalRateLimiter resource, including the Id value in value.

  5. In the kubeconfig context of the ACK cluster, run the following command to update the configuration of the global rate-limiting service in the cluster.

    kubectl apply -f ratelimit-config.yaml
  6. Run the following command to start a bash session in the sleep application.

    kubectl exec -it deploy/sleep -- sh
  7. Run the following command to access the /headers path of the httpbin service twice in a row.

    curl httpbin:8000/headers -v
    curl httpbin:8000/headers -v

    The first request is allowed. The following output is returned for the second request:

    < 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: 5
    < date: Thu, 26 Oct 2023 04:23:54 GMT
    < server: envoy
    < content-length: 0
    < x-envoy-upstream-service-time: 2
    < 
    * Connection #0 to host httpbin left intact

    The global rate limiting configuration allows only one request to the /headers path of the httpbin service within one minute, so the second request is rate-limited. Global rate limiting now takes effect on inbound traffic to the /headers path of the httpbin service.

  8. Run the following command to access the /get path of the httpbin service.

    curl httpbin:8000/get -v

    Expected output:

    *   Trying 192.168.243.21:8000...
    * Connected to httpbin (192.168.243.21) port 8000 (#0)
    > GET /get HTTP/1.1
    > Host: httpbin:8000
    > User-Agent: curl/8.1.2
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < server: envoy
    < date: Thu, 11 Jan 2024 06:25:09 GMT
    < content-type: application/json
    < content-length: 431
    < access-control-allow-origin: *
    < access-control-allow-credentials: true
    < x-envoy-upstream-service-time: 7
    <
    {
      "args": {},
      "headers": {
        "Accept": "*/*",
        "Host": "httpbin:8000",
        "User-Agent": "curl/8.1.2",
        "X-Envoy-Attempt-Count": "1",
        "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=be10819991ba1a354a89e68b3bed1553c12a4fba8b65fbe0f16299d552680b29;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
      },
      "origin": "127.0.0.6",
      "url": "http://httpbin:8000/get"
    }
    * Connection #0 to host httpbin left intact

    Requests sent to other paths of the httpbin service are not affected by the global rate limiting configuration and can still be accessed normally.

References