Erweiterbarkeit der Datenebene mit EnvoyFilter

Mit der EnvoyFilter API können Sie die Funktionen der Datenebene in Cloud Service Mesh erweitern, die mit anderen Istio-APIs nicht möglich sind. Mit der EnvoyFilter API können Sie die Envoy-Konfiguration anpassen, die aus anderen auf die Arbeitslasten angewendeten Richtlinien generiert wird, z. B. indem Sie der HTTP-Filterkette Filter hinzufügen.

Was Sie bedenken sollten

  • Die API-Oberfläche ist an interne Implementierungsdetails gebunden. Daher ist bei der Verwendung dieser Funktion besondere Vorsicht geboten, da falsche Konfigurationen das Mesh destabilisieren können. Verwenden Sie die EnvoyFilter API nur, wenn andere Istio APIs nicht Ihren Anforderungen entsprechen.
  • Die EnvoyFilter API wird mit bestimmten Einschränkungen unterstützt. Aus Gründen der Zuverlässigkeit und des Supports dürfen nur bestimmte Felder und Erweiterungen verwendet werden. Eine vollständige Liste der unterstützten Funktionen in der EnvoyFilter API finden Sie unter Unterstützte Funktionen mit Istio APIs (verwaltete Steuerungsebene).
  • Der Umfang des Supports, den Google bietet, beschränkt sich auf die Weitergabe der vom Nutzer bereitgestellten Konfiguration an die Arbeitslasten mit Envoy-Sidecars und erstreckt sich nicht auf die Richtigkeit der Konfiguration, die mit den APIs für die einzelnen Erweiterungen angegeben wird.

Unterstützte API-Felder

Die EnvoyFilter API wird mit der TRAFFIC_DIRECTOR-Implementierung der Steuerungsebene nur mit eingeschränktem Support unterstützt:

  • targetRefs: Nicht unterstützt
  • configPatches[].applyTo : Nur HTTP_FILTER wird unterstützt.
  • configPatches[].patch.operation: In Kombination mit dem Routenfilter werden nur INSERT_FIRST und INSERT_BEFORE unterstützt.
  • configPatches[].patch.value.type_url: Siehe Unterstützte Erweiterungen
  • configPatches[].patch.filterClass: Nicht unterstützt
  • configPatches[].match.proxy: Nicht unterstützt
  • configPatches[].match.routeConfiguration: Nicht unterstützt
  • configPatches[].match.cluster: Nicht unterstützt
  • Die folgenden Felder werden nur für den Vorgang INSERT_BEFORE unterstützt:
    • configPatches[].match.listener: Nur filter wird unterstützt.
    • configPatches[].match.listener.filter.name: Nur envoy.filters.network.http_connection_manager wird unterstützt.
    • configPatches[].match.listener.filter.subFilter.name: Nur envoy.filters.http.router wird unterstützt.

Unterstützte Erweiterungen

Im Folgenden finden Sie eine Liste der unterstützten Erweiterungen sowie der unterstützten API-Felder für die verschiedenen Release-Channels. Die API-Definition und ihre Semantik finden Sie in der offiziellen Envoy-Dokumentation.

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

Feld Rapid Regulär Stabil
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

Feld Rapid Regulär Stabil
(Keine Felder)

Verwendungsbeispiel

In dieser Anleitung erfahren Sie, wie Sie die integrierte lokale Ratenbegrenzung von Envoy verwenden, um den Traffic zu einem Dienst mithilfe der EnvoyFilter API dynamisch zu begrenzen.

Kosten

In dieser Anleitung werden die folgenden kostenpflichtigen Komponenten von Google Cloudverwendet:

Nach Abschluss dieser Anleitung können Sie weitere Kosten durch Löschen von erstellten Ressourcen vermeiden. Weitere Informationen finden Sie unter Bereinigen.

Hinweis

Ingress-Gateway bereitstellen

  1. Legen Sie den aktuellen Kontext für kubectl auf den Cluster fest:

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  2. Erstellen Sie einen Namespace für Ihr Ingress-Gateway:

    kubectl create namespace asm-ingress
    
  3. Aktivieren Sie den Namespace für die Injektion. Die Schritte hängen von Ihrer Implementierung der Steuerungsebene ab.

    Wenden Sie das Standard-Einschleusungslabel auf den Namespace an.

    kubectl label namespace asm-ingress \
        istio.io/rev- istio-injection=enabled --overwrite
    
  4. Stellen Sie das Beispiel-Gateway im Repository anthos-service-mesh-samples bereit:

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

    Erwartete Ausgabe:

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

Beispielanwendung für Online-Boutique bereitstellen

  1. Falls noch nicht geschehen, legen Sie den aktuellen Kontext für kubectl auf den Cluster fest:

    gcloud container clusters get-credentials CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    
  2. Erstellen Sie den Namespace für die Beispielanwendung:

    kubectl create namespace onlineboutique
    
  3. Fügen Sie dem Namespace onlineboutique ein Label hinzu, um Envoy-Proxys automatisch einzufügen:

    kubectl label namespace onlineboutique \
       istio.io/rev- istio-injection=enabled --overwrite
    
  4. Stellen Sie die Beispielanwendung, die VirtualService für das Frontend und Dienstkonten für die Arbeitslasten bereit. In dieser Anleitung stellen Sie die Mikrodienst-Demo-Anwendung "Online Boutique" bereit.

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

Dienste ansehen

  1. Sehen Sie sich die Pods im Namespace onlineboutique an:

    kubectl get pods -n onlineboutique
    

    Erwartete Ausgabe:

    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
    

    Alle Pods für Ihre Anwendung sollten mit dem Wert 2/2 in der Spalte READY ausgeführt werden. Dieser Wert weist darauf hin, dass die Pods einen Envoy-Sidecar-Proxy erfolgreich eingefügt haben. Wenn 2/2 nach einigen Minuten nicht angezeigt wird, rufen Sie die Anleitung zur Fehlerbehebung auf.

  2. Rufen Sie die externe IP-Adresse ab und legen Sie sie auf eine Variable fest:

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

    Die Ausgabe sollte in etwa so aussehen:

    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. Rufen Sie die Adresse EXTERNAL-IP in Ihrem Webbrowser auf. Sie sollten den Online Boutique-Shop in Ihrem Browser sehen.

    Online-Boutique-Frontend

Ratenbegrenzungskonfiguration anwenden

In diesem Abschnitt wird eine EnvoyFilter-Ressource angewendet, um den gesamten Traffic für den frontend-Dienst auf 5 Anfragen/Minute zu beschränken.

  1. Wenden Sie die CR auf den frontend-Dienst an:

    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
    

    Erwartete Ausgabe:

    envoyfilter.networking.istio.io/frontend-local-ratelimit created
    
  2. Prüfen Sie, ob im CR-Status Fehler gemeldet werden:

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

    Erwartete Ausgabe:

    ...
    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. Entfernen Sie das loadgenerator-Deployment, da der Dienst dadurch mehrmals aufgerufen wird, was Tokens verbraucht:

    kubectl delete -n onlineboutique deployment loadgenerator
    

    Erwartete Ausgabe:

    deployment.apps/loadgenerator deleted
    
  4. Prüfen Sie mit curl, ob in 60 Sekunden maximal 5 Anfragen zulässig sind. Der Code 429 gibt an, dass die Ratenbegrenzung erzwungen wird.

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

    Erwartete Ausgabe:

    200
    200
    200
    200
    200
    429
    429
    429
    429
    429
    

Bereinigen

Damit Ihrem Google Cloud Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, können Sie entweder das Projekt löschen oder die einzelnen Ressourcen löschen.

Projekt löschen

Löschen Sie das Projekt in Cloud Shell:

  gcloud projects delete PROJECT_ID

Ressourcen löschen

  • Wenn Sie den Cluster behalten und das Online Boutique-Beispiel entfernen möchten:

    1. Löschen Sie die Anwendungs-Namespaces:

      kubectl delete namespace onlineboutique
      

      Erwartete Ausgabe:

      namespace "onlineboutique" deleted
      
    2. Löschen Sie den Ingress-Gateway-Namespace:

      kubectl delete namespace asm-ingress
      

      Erwartete Ausgabe:

      namespace "asm-ingress" deleted
      
  • Wenn Sie zusätzliche Gebühren vermeiden möchten, löschen Sie den Cluster:

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

Fehlerbehebung

Weitere Informationen finden Sie unter Probleme mit der Erweiterbarkeit der Datenebene beheben.