Estensibilità del piano dati con EnvoyFilter

Puoi utilizzare l'API EnvoyFilter per estendere le funzionalità del piano dati in Cloud Service Mesh che altrimenti non sono raggiungibili utilizzando altre API Istio. Con l'API EnvoyFilter, puoi personalizzare la configurazione di Envoy generata da altre policy applicate ai carichi di lavoro, ad esempio aggiungendo filtri alla catena di filtri HTTP.

Considerazioni importanti

  • Tieni presente che la superficie dell'API è legata ai dettagli di implementazione interni, pertanto è necessario prestare particolare attenzione quando utilizzi questa funzionalità, poiché configurazioni errate potrebbero destabilizzare la mesh. Utilizza l'API EnvoyFilter solo se le altre API Istio non soddisfano le tue esigenze.
  • L'API EnvoyFilter è supportata con restrizioni specifiche sui campi e sulle estensioni che possono essere utilizzati per motivi di affidabilità e supporto. Per un elenco esaustivo delle funzionalità supportate nell'API EnvoyFilter, consulta Funzionalità supportate che utilizzano le API Istio (control plane gestito).
  • L'ambito del supporto offerto da Google è limitato alla propagazione della configurazione fornita dall'utente ai carichi di lavoro con i sidecar Envoy e non si estende alla correttezza della configurazione specificata utilizzando le API per estensione.

Campi API supportati

L'API EnvoyFilter è supportata con l'implementazione del control plane TRAFFIC_DIRECTOR solo con supporto limitato come segue:

  • targetRefs: non supportato
  • configPatches[].applyTo : è supportato solo HTTP_FILTER
  • configPatches[].patch.operation: sono supportati solo INSERT_FIRST e INSERT_BEFORE se utilizzati con il filtro di route.
  • configPatches[].patch.value.type_url: consulta Estensioni supportate
  • configPatches[].patch.filterClass: non supportato
  • configPatches[].match.proxy: non supportato
  • configPatches[].match.routeConfiguration: non supportato
  • configPatches[].match.cluster: non supportato
  • I seguenti campi sono supportati solo per l'operazione INSERT_BEFORE:
    • configPatches[].match.listener: è supportato solo filter.
    • configPatches[].match.listener.filter.name: è supportato solo envoy.filters.network.http_connection_manager.
    • configPatches[].match.listener.filter.subFilter.name: è supportato solo envoy.filters.http.router.

Estensioni supportate

Di seguito è riportato l'elenco delle estensioni supportate insieme ai relativi campi API supportati nei vari canali di rilascio. La definizione dell'API e la relativa semantica sono disponibili nella documentazione ufficiale di Envoy.

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

Campo Rapido Normale Stabile
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 Rapido Normale Stabile
(Nessun campo)

Esempi di utilizzo

In questo tutorial imparerai a utilizzare la limitazione di frequenza locale integrata di Envoy per limitare dinamicamente il traffico a un servizio utilizzando l'API EnvoyFilter.

Costi

Questo tutorial utilizza i seguenti componenti fatturabili di Google Cloud:

Al termine di questo tutorial, puoi evitare costi continui eliminando le risorse che hai creato. Per ulteriori informazioni, consulta Liberare spazio.

Prima di iniziare

Esegui il deployment di un gateway in entrata

  1. Imposta il contesto attuale di kubectl sul cluster:

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  2. Crea uno spazio dei nomi per il gateway in entrata:

    kubectl create namespace asm-ingress
    
  3. Abilita lo spazio dei nomi per l'inserimento. I passaggi dipendono dall'implementazione del control plane.

    Applica l'etichetta di inserimento predefinita allo spazio dei nomi:

    kubectl label namespace asm-ingress \
        istio.io/rev- istio-injection=enabled --overwrite
    
  4. Esegui il deployment del gateway di esempio nel repository anthos-service-mesh-samples:

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

    Output previsto:

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

Deployment dell'applicazione di esempio Online Boutique

  1. Se non l'hai ancora fatto, imposta il contesto attuale di kubectl sul cluster:

    gcloud container clusters get-credentials CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    
  2. Crea lo spazio dei nomi per l'applicazione di esempio:

    kubectl create namespace onlineboutique
    
  3. Etichetta lo spazio dei nomi onlineboutique per inserire automaticamente i proxy Envoy:

    kubectl label namespace onlineboutique \
       istio.io/rev- istio-injection=enabled --overwrite
    
  4. Esegui il deployment dell'app di esempio, di VirtualService per il frontend e dei service account per i carichi di lavoro. Per questo tutorial, esegui il deployment di Online Boutique, un'app demo di microservizi.

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

Visualizza i tuoi servizi

  1. Visualizza i pod nello spazio dei nomi onlineboutique:

    kubectl get pods -n onlineboutique
    

    Output previsto:

    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
    

    Tutti i pod della tua applicazione devono essere attivi e in esecuzione, con un valore 2/2 nella colonna READY. Ciò indica che i pod hanno un proxy sidecar Envoy inserito correttamente. Se dopo qualche minuto non viene visualizzato 2/2, consulta la guida alla risoluzione dei problemi.

  2. Ottieni l'IP esterno e impostalo su una variabile:

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

    Viene visualizzato un output simile al seguente:

    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. Visita l'indirizzo EXTERNAL-IP nel browser web. Dovresti visualizzare il negozio Online Boutique nel browser.

    frontend del negozio online

Applica la configurazione della limitazione di frequenza

In questa sezione viene applicata una risorsa EnvoyFilter per limitare tutto il traffico al servizio frontend a 5 richieste/min.

  1. Applica il CR al servizio 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
    

    Output previsto:

    envoyfilter.networking.istio.io/frontend-local-ratelimit created
    
  2. Verifica che lo stato del CR non segnali errori:

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

    Output previsto:

    ...
    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. Rimuovi il deployment di loadgenerator perché chiama il servizio più volte e consuma token:

    kubectl delete -n onlineboutique deployment loadgenerator
    

    Output previsto:

    deployment.apps/loadgenerator deleted
    
  4. Utilizzando curl, verifica che non siano consentite più di 5 richieste in 60 secondi. Il codice 429 indica che la limitazione di frequenza è in vigore.

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

    Output previsto:

    200
    200
    200
    200
    200
    429
    429
    429
    429
    429
    

Libera spazio

Per evitare che al tuo Google Cloud account vengano addebitati costi continui per le risorse utilizzate in questo tutorial, puoi eliminare il progetto o eliminare le singole risorse.

Elimina il progetto

In Cloud Shell, elimina il progetto:

  gcloud projects delete PROJECT_ID

Elimina le risorse

  • Se vuoi conservare il cluster e rimuovere l'esempio Online Boutique:

    1. Elimina gli spazi dei nomi dell'applicazione:

      kubectl delete namespace onlineboutique
      

      Output previsto:

      namespace "onlineboutique" deleted
      
    2. Elimina lo spazio dei nomi del gateway in entrata:

      kubectl delete namespace asm-ingress
      

      Output previsto:

      namespace "asm-ingress" deleted
      
  • Se vuoi evitare addebiti aggiuntivi, elimina il cluster:

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

Risoluzione dei problemi

Consulta Risolvere i problemi di estensibilità del piano dati.