Todos os produtos
Search
Central de documentação

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

Última atualização: Jun 28, 2026

A limitação de taxa global utiliza um serviço centralizado apoiado pelo Redis para aplicar limites de requisições em todas as instâncias do gateway. Diferentemente da limitação local, em que cada proxy sidecar rastreia seus próprios contadores, a limitação global mantém um único contador compartilhado. Isso a torna eficaz contra picos de tráfego, sobrecarga e abusos que abrangem múltiplos pods.

Este tópico aborda quatro cenários de limitação de taxa para gateways de entrada, evoluindo de limites básicos no nível de rota até regras refinadas baseadas em cabeçalhos, parâmetros de consulta ou endereços ip de clientes.

Como funciona

  1. Implante o serviço Envoy ratelimit e um backend Redis no seu cluster ACK.

  2. Defina as regras de limitação em um recurso personalizado ASMGlobalRateLimiter.

  3. O ASM gera a configuração de limite de taxa e a grava no campo status do recurso.

  4. Copie a configuração gerada para o ConfigMap ratelimit-config para que o serviço de limite de taxa possa carregá-la.

  5. A cada requisição de entrada, o gateway de entrada consulta o serviço de limite de taxa e retorna o código http 429 Too Many Requests quando um limite é excedido.

Pré-requisitos

Etapa 1: Implantar o serviço de limite de taxa

O serviço de limite de taxa possui dois componentes: uma instância Redis para armazenamento de contadores e o servidor Envoy ratelimit, que verifica as requisições conforme as regras configuradas.

  1. Salve o conteúdo a seguir como ratelimit-svc.yaml:

    Show 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. Conecte-se ao cluster ACK com kubectl e implante ambos os serviços. Para obter detalhes sobre como se conectar ao seu cluster, consulte Obter o arquivo kubeconfig de um cluster e usar kubectl para conectar-se ao cluster.

        kubectl apply -f ratelimit-svc.yaml

Etapa 2: Implantar a aplicação de exemplo

Os exemplos neste tópico utilizam a aplicação Istio Bookinfo.

  1. Baixe o arquivo bookinfo.yaml do repositório do Istio no GitHub e implante-o no seu cluster ACK:

        kubectl apply -f bookinfo.yaml
  2. Salve o conteúdo a seguir como bookinfo-gateway.yaml. Este arquivo define um Gateway e um VirtualService que roteiam o tráfego de bf2.example.com através do gateway de entrada para a aplicação Bookinfo. O VirtualService define uma rota chamada productpage-route-name1 que corresponde a requisições para /productpage, /static, /login, /logout e /api/v1/products, encaminhando-as para o serviço productpage na porta 9080.

    Show 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
  3. Conecte-se à instância do ASM com kubectl e aplique as regras de roteamento. Para obter detalhes sobre como se conectar à sua instância do ASM, consulte Usar kubectl no plano de controle para acessar recursos do Istio.

        kubectl apply -f bookinfo-gateway.yaml

Fluxo de trabalho comum para todos os cenários

Cada cenário abaixo segue o mesmo fluxo de trabalho de três fases. Apenas o yaml do ASMGlobalRateLimiter difere entre os cenários.

Fase 1 -- Criar a regra de limitação

Aplique o recurso ASMGlobalRateLimiter na instância do ASM:

kubectl apply -f global-ratelimit-gw.yaml

Fase 2 -- Sincronizar a configuração gerada com o serviço de limite de taxa

  1. Recupere a configuração gerada:

        kubectl get asmglobalratelimiter global-test -n istio-system -o yaml
  2. Copie o conteúdo de config.yaml da seção status e cole-o — sem modificações — no campo data.config.yaml de um ConfigMap chamado ratelimit-config. Por exemplo:

        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: ratelimit-config
        data:
          config.yaml: |
            # Paste the config.yaml content from the status section here
  3. Aplique o ConfigMap no cluster ACK:

        kubectl apply -f ratelimit-config.yaml
Importante

O conteúdo de config.yaml deve ser copiado exatamente como foi gerado. Qualquer alteração na formatação pode fazer com que o serviço de limite de taxa rejeite a configuração.

Fase 3 -- Verificar

Envie duas requisições dentro da janela de limitação. Substitua <ingress-gateway-ip> pelo endereço ip do seu gateway de entrada. Para encontrá-lo, consulte a subetapa 1 da Etapa 3 em Usar recursos do Istio para rotear tráfego para diferentes versões de um serviço.

for i in 1 2; do
  curl -s -o /dev/null -w "Request $i: %{http_code}\n" \
    -H 'host: bf2.example.com' \
    http://<ingress-gateway-ip>/productpage
done

Saída esperada:

Request 1: 200
Request 2: 429

A primeira requisição é bem-sucedida. A segunda retorna 429 Too Many Requests com os seguintes cabeçalhos de resposta:

x-envoy-ratelimited: true
x-ratelimit-limit: 1, 1;w=60
x-ratelimit-remaining: 0
x-ratelimit-reset: 48

Referência de campos do ASMGlobalRateLimiter

A tabela a seguir resume os principais campos na definição de recurso personalizado (CRD) do ASMGlobalRateLimiter. Para a referência completa, consulte Descrição dos campos do ASMGlobalRateLimiter.

Campo

Descrição

workloadSelector

Rótulos que selecionam a carga de trabalho alvo. Defina como istio: ingressgateway para ter como alvo o gateway de entrada.

isGateway

Defina como true quando o alvo for um gateway em vez de um sidecar.

rateLimitService

Configurações de conexão para o serviço de limite de taxa: host, port e timeout.

configs[].limit

Limiar padrão de limitação. unit aceita SECOND, MINUTE, HOUR ou DAY. quota é o número máximo de requisições permitidas por unidade.

configs[].match.vhost

Seleciona um host virtual por name (domínio) e port. Opcionalmente, restrinja a uma rota específica com route.name_match.

configs[].limit_overrides

Substitui o limite padrão para requisições que correspondem a critérios específicos. Requer ASM 1.19.0 ou posterior.

limit_overrides[].request_match.header_match

Corresponde a requisições por nome e valor de cabeçalho http.

limit_overrides[].request_match.query_match

Corresponde a requisições por nome e valor de parâmetro de consulta.

limit_overrides[].request_match.remote_address

Corresponde a requisições por ip do cliente. Especifique address para o ip e v4_prefix_mask_len (opcional) para correspondência CIDR.

Cenário 1: Limitar uma rota específica

Limite o tráfego na rota productpage-route-name1 de bf2.example.com:80 para 1 requisição por minuto.

Salve o seguinte conteúdo como 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    # Must match the domain in the VirtualService
        port: 80                  # Must match the ingress gateway port
        route:
          name_match: productpage-route-name1  # Must match the route name in the VirtualService

Em seguida, siga o fluxo de trabalho comum: aplique o recurso, sincronize o ConfigMap e verifique.

Expected status output

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

Corresponding ratelimit-config ConfigMap

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

Após a verificação, a segunda requisição retorna 429, confirmando que a limitação está ativa na rota especificada.

Cenário 2: Limitar um domínio e porta específicos

Limite todo o tráfego para bf2.example.com:80 para 1 requisição por minuto, independentemente da rota.

A única diferença em relação ao Cenário 1 é a remoção do campo route de vhost:

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
        port: 80
        # No route field -- throttling applies to all routes on this domain:port

Siga o fluxo de trabalho comum para aplicar, sincronizar e verificar.

Expected status output

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

Corresponding ratelimit-config ConfigMap

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

Após a verificação, a segunda requisição retorna 429, confirmando que a limitação está ativa em toda a combinação de domínio e porta.

Cenário 3: Limitar requisições por cabeçalho e parâmetro de consulta

É necessário ASM versão 1.19.0 ou posterior. Para instruções de atualização, consulte Atualizar uma instância do ASM .

Aplique um limite mais restritivo apenas a requisições que contenham um cabeçalho http específico (ratelimit: "true") e um parâmetro de consulta (ratelimit=enabled) na rota productpage-route-name1. Todas as outras requisições na mesma rota permanecem sem limitação.

Esta configuração usa limit_overrides para impor um limite estrito por requisição (1 requisição/minuto), mantendo o limite base alto (100.000 requisições/segundo) para que requisições não correspondentes passem livremente:

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         # High base limit -- effectively no throttling for non-matching requests
    match:
      vhost:
        name: bf2.example.com
        port: 80
        route:
          name_match: productpage-route-name1
    limit_overrides:
    - request_match:
        header_match:
        - name: ratelimit
          exact_match: "true"
        query_match:
        - name: ratelimit
          exact_match: "enabled"
      limit:
        unit: MINUTE
        quota: 1             # Strict limit for matching requests only

Siga o fluxo de trabalho comum para aplicar, sincronizar e verificar.

Verificar limitação seletiva

Envie duas requisições com o cabeçalho e o parâmetro de consulta correspondentes:

for i in 1 2; do
  curl -s -o /dev/null -w "Request $i: %{http_code}\n" \
    -H 'host: bf2.example.com' \
    -H 'ratelimit: true' \
    "http://<ingress-gateway-ip>/productpage?ratelimit=enabled"
done

Saída esperada:

Request 1: 200
Request 2: 429

Em seguida, envie uma requisição sem o cabeçalho ou parâmetro de consulta:

curl -s -o /dev/null -w "No-header request: %{http_code}\n" \
  -H 'host: bf2.example.com' \
  http://<ingress-gateway-ip>/productpage

Saída esperada:

No-header request: 200

A requisição é bem-sucedida, confirmando que apenas as requisições correspondentes ao cabeçalho e parâmetro de consulta especificados são limitadas.

Expected status output

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

Corresponding ratelimit-config ConfigMap

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

Cenário 4: Limitar requisições de um endereço ip de cliente específico

É necessário ASM versão 1.19.0 ou posterior. Para instruções de atualização, consulte Atualizar uma instância do ASM .
Importante

Defina a External Traffic Policy do gateway de entrada como Local para preservar o ip original do cliente. Para mais informações, consulte Criar um gateway de entrada.

Dica: Encontre o endereço ip do cliente no campo downstream_remote_address do log de acesso do gateway de entrada.

Aplique um limite mais restritivo apenas a requisições provenientes de um ip de cliente específico (ou bloco CIDR) na rota productpage-route-name1. Todos os outros ips de clientes permanecem sem limitação.

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
    limit_overrides:
    - request_match:
        remote_address:
          address: <client-ip>              # IP address to throttle
          v4_prefix_mask_len: <mask-length>  # Optional. Subnet mask length for CIDR matching
      limit:
        unit: MINUTE
        quota: 1

Substitua os seguintes espaços reservados pelos seus valores:

Espaço reservado

Descrição

Exemplo

<client-ip>

Endereço ip do cliente a ser limitado

106.11.XX.XX

<mask-length>

Comprimento da máscara de sub-rede IPv4 (opcional)

24

Siga o fluxo de trabalho comum para aplicar, sincronizar e verificar.

Verificar limitação baseada em ip

Envie duas requisições a partir do ip limitado:

for i in 1 2; do
  curl -s -o /dev/null -w "Request $i: %{http_code}\n" \
    -H 'host: bf2.example.com' \
    http://<ingress-gateway-ip>/productpage
done

Saída esperada:

Request 1: 200
Request 2: 429

Em seguida, envie uma requisição de um endereço ip diferente. A requisição é bem-sucedida com 200, confirmando que apenas o ip especificado foi limitado.

Expected status output

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

Corresponding ratelimit-config ConfigMap

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

Veja também