Extensibilidade do plano de dados com EnvoyFilter

É possível usar a API EnvoyFilter para estender os recursos do plano de dados no Cloud Service Mesh que não podem ser alcançados usando outras APIs do Istio. Com a API EnvoyFilter, é possível personalizar a configuração do Envoy gerada por outras políticas aplicadas às cargas de trabalho, como adicionar filtros à cadeia de filtros HTTP.

Considerações importantes

  • A superfície da API está vinculada a detalhes de implementação internos. Portanto, é preciso ter cuidado ao usar esse recurso, já que configurações incorretas podem desestabilizar a malha. Use a API EnvoyFilter somente se outras APIs do Istio não atenderem às suas necessidades.
  • A API EnvoyFilter é compatível com restrições específicas sobre quais campos e extensões podem ser usados para fins de confiabilidade e capacidade de suporte. Para uma lista completa de recursos compatíveis com a API EnvoyFilter, consulte Recursos compatíveis com as APIs do Istio (plano de controle gerenciado).
  • O escopo do suporte oferecido pelo Google se limita à propagação da configuração fornecida pelo usuário para as cargas de trabalho com sidecars do Envoy e não se estende à correção da configuração especificada usando APIs por extensão.

Campos da API compatíveis

A API EnvoyFilter é compatível com a implementação do plano de controle TRAFFIC_DIRECTOR apenas com suporte limitado da seguinte maneira:

  • targetRefs: indisponível
  • configPatches[].applyTo : apenas HTTP_FILTER é compatível
  • configPatches[].patch.operation: somente INSERT_FIRST e INSERT_BEFORE são compatíveis quando usados com o filtro de rota.
  • configPatches[].patch.value.type_url: consulte Extensões compatíveis
  • configPatches[].patch.filterClass: indisponível
  • configPatches[].match.proxy: indisponível
  • configPatches[].match.routeConfiguration: indisponível
  • configPatches[].match.cluster: indisponível
  • Os campos a seguir são aceitos apenas para a operação INSERT_BEFORE:
    • configPatches[].match.listener: apenas filter é aceito.
    • configPatches[].match.listener.filter.name: apenas envoy.filters.network.http_connection_manager é aceito.
    • configPatches[].match.listener.filter.subFilter.name: apenas envoy.filters.http.router é aceito.

Extensões compatíveis

A seguir, confira a lista de extensões compatíveis e os campos de API compatíveis em vários canais de lançamento. A definição da API e a semântica dela podem ser encontradas na documentação oficial do Envoy.

type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit

Campo Rápido Normal Estável
stat_prefix
status
token_bucket
filter_enabled
filter_enforced
response_headers_to_add
request_headers_to_add_when_not_enforced
local_rate_limit_per_downstream_connection
enable_x_ratelimit_headers

type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb

Campo Rápido Normal Estável
(Nenhum campo)

Exemplo de uso

Neste tutorial, você vai aprender a usar a limitação de taxa local integrada do Envoy para limitar dinamicamente o tráfego a um serviço usando a API EnvoyFilter.

Custos

Neste tutorial, usamos os seguintes componentes faturáveis do Google Cloud:

Ao concluir este tutorial, exclua os recursos criados para evitar custos contínuos. Para mais informações, consulte Limpeza.

Antes de começar

Implantar um gateway de entrada

  1. Defina o contexto atual de kubectl para o cluster:

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  2. Crie um namespace para seu gateway de entrada:

    kubectl create namespace asm-ingress
    
  3. Ativar o namespace para injeção. As etapas dependem da sua implementação do plano de controle.

    Aplique o rótulo de injeção padrão ao namespace:

    kubectl label namespace asm-ingress \
        istio.io/rev- istio-injection=enabled --overwrite
    
  4. Implante o gateway de exemplo no repositório anthos-service-mesh-samples:

    kubectl apply -n asm-ingress \
        -f docs/shared/asm-ingress-gateway
    

    Saída esperada:

    serviceaccount/asm-ingressgateway configured
    service/asm-ingressgateway configured
    deployment.apps/asm-ingressgateway configured
    gateway.networking.istio.io/asm-ingressgateway configured
    

Implantar o aplicativo de amostra Online Boutique

  1. Caso contrário, defina o contexto atual de kubectl para o cluster:

    gcloud container clusters get-credentials CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    
  2. Crie o namespace do aplicativo de amostra:

    kubectl create namespace onlineboutique
    
  3. Rotule o namespace onlineboutique para injetar automaticamente proxies do Envoy:

    kubectl label namespace onlineboutique \
       istio.io/rev- istio-injection=enabled --overwrite
    
  4. Implante o aplicativo de amostra, o VirtualService para o front-end e as contas de serviço para as cargas de trabalho. Neste tutorial, você vai implantar o Online Boutique, um app de demonstração de microsserviços.

    kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/virtual-service.yaml
    
    kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/service-accounts
    

Ver seus serviços

  1. Veja os pods no namespace onlineboutique:

    kubectl get pods -n onlineboutique
    

    Saída esperada:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    Todos os pods do aplicativo devem estar em execução, com um 2/2 na coluna READY. Isso indica que os pods têm um proxy sidecar do Envoy injetado com sucesso. Se ele não mostrar 2/2 após alguns minutos, acesse o Guia de solução de problemas.

  2. Defina o IP externo e uma variável:

    kubectl get services -n asm-ingress
    export FRONTEND_IP=$(kubectl --namespace asm-ingress \
    get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \
    )
    

    Você verá uma saída semelhante a esta:

    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
    asm-ingressgateway   LoadBalancer   10.19.247.233   35.239.7.64   80:31380/TCP,443:31390/TCP,31400:31400/TCP   27m
    
    
  3. Acesse o endereço EXTERNAL-IP no navegador da Web. Você verá a loja Online Boutique no seu navegador.

    front-end do online boutique

Aplicar configuração de limitação de taxa

Esta seção aplica um recurso EnvoyFilter para limitar todo o tráfego ao serviço frontend a 5 solicitações/min.

  1. Aplique o CR ao serviço frontend:

    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: frontend-local-ratelimit
      namespace: onlineboutique
    spec:
      workloadSelector:
        labels:
          app: frontend
      configPatches:
        - applyTo: HTTP_FILTER
          match:
            context: SIDECAR_INBOUND
            listener:
              filterChain:
                filter:
                  name: "envoy.filters.network.http_connection_manager"
                  subFilter:
                    name: "envoy.filters.http.router"
          patch:
            operation: INSERT_BEFORE
            value:
              name: envoy.filters.http.local_ratelimit
              typed_config:
                "@type": type.googleapis.com/udpa.type.v1.TypedStruct
                type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
                value:
                  stat_prefix: http_local_rate_limiter
                  token_bucket:
                    max_tokens: 5
                    tokens_per_fill: 5
                    fill_interval: 60s
                  filter_enabled:
                    runtime_key: local_rate_limit_enabled
                    default_value:
                      numerator: 100
                      denominator: HUNDRED
                  filter_enforced:
                    runtime_key: local_rate_limit_enforced
                    default_value:
                      numerator: 100
                      denominator: HUNDRED
    EOF
    

    Saída esperada:

    envoyfilter.networking.istio.io/frontend-local-ratelimit created
    
  2. Verifique se o status do CR não informa erros:

    kubectl get envoyfilter -n onlineboutique frontend-local-ratelimit -o yaml
    

    Saída esperada:

    ...
    status:
      conditions:
      - lastTransitionTime: "2025-06-30T14:29:25.467017594Z"
        message: This resource has been accepted. This does not mean it has been propagated
          to all proxies yet
        reason: Accepted
        status: "True"
        type: Accepted
    
  3. Remova a implantação loadgenerator, porque ela chama o serviço várias vezes, o que consome tokens:

    kubectl delete -n onlineboutique deployment loadgenerator
    

    Saída esperada:

    deployment.apps/loadgenerator deleted
    
  4. Usando curl, verifique se não são permitidas mais de cinco solicitações em 60 segundos. O código 429 indica que a limitação de taxa está sendo aplicada.

    for i in {1..10}; do curl -s http://${FRONTEND_IP} -o /dev/null -w "%{http_code}\n"; sleep 1; done
    

    Saída esperada:

    200
    200
    200
    200
    200
    429
    429
    429
    429
    429
    

Limpar

Para evitar cobranças recorrentes na sua conta do Google Cloud pelos recursos usados neste tutorial, é possível excluir o projeto ou excluir os recursos individuais.

Excluir o projeto

No Cloud Shell, exclua o projeto:

  gcloud projects delete PROJECT_ID

Excluir os recursos

  • Se quiser manter o cluster e remover o aplicativo de amostra do Online Boutique:

    1. Exclua os namespaces do aplicativo:

      kubectl delete namespace onlineboutique
      

      Saída esperada:

      namespace "onlineboutique" deleted
      
    2. Exclua o namespace do gateway de entrada:

      kubectl delete namespace asm-ingress
      

      Saída esperada:

      namespace "asm-ingress" deleted
      
  • Se quiser evitar cobranças adicionais, exclua o cluster:

    gcloud container clusters delete CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    

Solução de problemas

Consulte Como resolver problemas de extensibilidade do plano de dados.