Personalizzare il traffico del gateway GKE utilizzando le Service Extensions

Questa pagina descrive come Google Kubernetes Engine (GKE) utilizza Service Extensions per aggiungere logica personalizzata a Cloud Load Balancing.

Questa pagina è destinata agli amministratori di identità e account GKE e agli sviluppatori che devono configurare la logica di gestione del traffico personalizzata utilizzando le Service Extensions.

Prima di leggere questa pagina, assicurati di avere familiarità con quanto segue:

Panoramica

GKE utilizza le estensioni di servizio per aggiungere logica personalizzata in Cloud Load Balancing. Puoi utilizzare Service Extensions per attività come la suddivisione avanzata del traffico, l'autenticazione personalizzata o la registrazione delle richieste.

Il controller GKE Gateway supporta le seguenti estensioni di servizio:

  • GCPRoutingExtension: questa estensione aggiunge una logica personalizzata a Cloud Load Balancing per controllare il routing del traffico.
  • GCPTrafficExtension: questa estensione inserisce una logica personalizzata in Cloud Load Balancing per modificare il traffico. Questa logica viene applicata al traffico dopo la selezione del servizio. Il bilanciatore del carico può aggiungere o modificare le intestazioni e i payload delle richieste e delle risposte HTTP. GCPTrafficExtension non influisce sulla selezione dei servizi o sulle norme di sicurezza dei servizi.
  • GCPEdgeExtension: questa estensione ti consente di influenzare la selezione del servizio di backend e le chiavi della cache Cloud CDN modificando le intestazioni delle richieste. È supportato esclusivamente per i bilanciatori del carico gestiti esterni globali.
  • GCPAuthzExtension: questa estensione consente di delegare le decisioni di autorizzazione a un motore di autorizzazione personalizzato o di terze parti (ad esempio un web application firewall esterno) o a Identity-Aware Proxy. Questa estensione viene utilizzata con una risorsa GCPAuthzPolicy, che applica il controllo dell'accesso al traffico in entrata nel gateway e stabilisce quando deve verificarsi il callout all'estensione.

Un'estensione si collega a un gateway. Per un gateway a cluster singolo, l'estensione fa riferimento a una risorsa Service, a una risorsa GCPWasmPlugin o a una risorsa GoogleAPIServiceName. Per un gateway multicluster, l'estensione fa riferimento a una risorsa ServiceImport o a una risorsa GoogleAPIServiceName.

  • Fai riferimento a una risorsa Service o a una risorsa ServiceImport: in questo modello, esegui il deployment della logica personalizzata come applicazione di backend separata, esposta come servizio Kubernetes. Il bilanciatore del carico effettua una chiamata a questo servizio per elaborare il traffico. Questo approccio è versatile e ti consente di implementare una logica di routing personalizzata o di manipolare il traffico, ad esempio modificando l'intestazione o ispezionando il payload.

  • Fai riferimento a una risorsa GCPWasmPlugin: per i casi d'uso ad alte prestazioni, puoi inserire una logica personalizzata scritta dall'utente direttamente nel percorso dei dati del bilanciatore del caricoCloud de Confiance by S3NS utilizzando un modulo WebAssembly (Wasm). Definisci una risorsa GCPWasmPlugin che punta all'immagine del modulo Wasm in Artifact Registry. Questo metodo viene utilizzato solo con le risorse GCPTrafficExtension e GCPEdgeExtension e un bilanciatore del carico delle applicazioni esterno globale

  • Fai riferimento a un servizio API di Google: puoi anche fare riferimento direttamente a un servizio API di Google utilizzando il campo googleAPIServiceName all'interno di un'estensione GCPTrafficExtension o GCPAuthzExtension.

Nel seguente diagramma, la risorsa GCPRoutingExtension è collegata a un gateway e fa riferimento a più servizi. L'estensione controlla il routing del traffico ai Servizi.

La risorsa GCPRoutingExtension è collegata a un gateway e
        fa riferimento a un servizio. L'estensione
        controlla il routing del traffico.
Figura: come funziona GCPRoutingExtension con i gateway

Nel seguente diagramma, la risorsa GCPTrafficExtension è collegata a un gateway e fa riferimento a un servizio, a un GoogleAPIServiceName o a un GCPWasmPlugin. L'estensione modifica le intestazioni e i payload di richieste e risposte.

La risorsa GCPTrafficExtension è collegata a un gateway e
        fa riferimento a un servizio, a un GoogleAPIServiceName o a un GCPWasmPlugin. L'estensione
        modifica le intestazioni e i payload di richieste e risposte.
Figura: come funziona GCPTrafficExtension con i gateway

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti operazioni:

  • Attiva l'API Google Kubernetes Engine.
  • Attiva l'API Google Kubernetes Engine
  • Per utilizzare Google Cloud CLI per questa attività, installala e poi inizializza gcloud CLI. Se hai già installato gcloud CLI, scarica l'ultima versione eseguendo il comando gcloud components update. Le versioni precedenti di gcloud CLI potrebbero non supportare l'esecuzione dei comandi in questo documento.

Requisiti del controller GKE Gateway

  • Il cluster deve utilizzare GKE 1.33 o versioni successive.
  • Per utilizzare GCPWasmPlugin, il cluster deve utilizzare GKE versione 1.33.3 o successive.
  • Per utilizzare la risorsa ServiceImport, il cluster deve utilizzare GKE versione 1.34.3 o successive.
  • Devi disporre di una risorsa Gateway configurata per un gateway multi-cluster interno. Questa risorsa può essere un bilanciatore del carico delle applicazioni esterno globale, un bilanciatore del carico delle applicazioni interno tra regioni, un bilanciatore del carico delle applicazioni esterno regionale o un gateway del bilanciatore del carico delle applicazioni interno regionale.
  • Nel cluster deve essere abilitata l'API Gateway.
  • Devi disporre di una risorsa gateway configurata. Questa risorsa può essere un bilanciatore del carico delle applicazioni esterno globale, un bilanciatore del carico delle applicazioni esterno regionale o un gateway del bilanciatore del carico delle applicazioni interno regionale. Se utilizzi una risorsa GCPWasmPlugin, devi eseguire il deployment solo di un gateway del bilanciatore del carico delle applicazioni esterno globale.
  • Devi avere una risorsa HTTPRoute configurata.

Limitazioni e restrizioni

La tabella seguente elenca le limitazioni associate alla configurazione delle estensioni del servizio gateway in GKE:

Categoria Limitazioni e restrizioni
Bilanciatore del carico L'estensione GCPRoutingExtension è supportata per i seguenti bilanciatori del carico:
  • Bilanciatore del carico delle applicazioni esterno regionale (classe gateway gke-l7-regional-external-managed)
  • Bilanciatore del carico delle applicazioni esterno regionale (classe gateway gke-l7-regional-external-managed-mc)
  • Bilanciatore del carico delle applicazioni interno regionale (classe gateway gke-l7-rilb)
  • Bilanciatore del carico delle applicazioni interno regionale (classe gateway gke-l7-rilb-mc)
  • Bilanciatore del carico delle applicazioni interno tra regioni (classe Gateway gke-l7-cross-regional-internal-managed-mc)
L'estensione GCPTrafficExtension è supportata per i seguenti bilanciatori del carico:
  • Bilanciatore del carico delle applicazioni esterno regionale (classe gateway gke-l7-regional-external-managed)
  • Bilanciatore del carico delle applicazioni esterno regionale (classe gateway gke-l7-regional-external-managed-mc)
  • Bilanciatore del carico delle applicazioni interno regionale (classe gateway gke-l7-rilb)
  • Bilanciatore del carico delle applicazioni interno regionale (classe gateway gke-l7-rilb-mc)
  • Bilanciatore del carico delle applicazioni esterno globale (classe Gateway gke-l7-global-external-managed)
  • Bilanciatore del carico delle applicazioni esterno globale (classe Gateway gke-l7-global-external-managed-mc)
  • Bilanciatore del carico delle applicazioni interno tra regioni (classe Gateway gke-l7-cross-regional-internal-managed-mc)
GCPEdgeExtension è supportato esclusivamente per il bilanciatore del carico gestito esterno globale (classe Gateway gke-l7-global-external-managed).
Catena e specifica delle estensioni
  • Per un'estensione GCPTrafficExtension, ogni ExtensionChain può avere un massimo di tre Extensions.
  • Per GCPRoutingExtension e GCPEdgeExtension, ogni ExtensionChain è limitato a 1 Extension.
  • Tutti i tipi di estensione (traffico, routing e edge) possono avere un massimo di 5 ExtensionChains per risorsa.
Timeout
  • Il timeout per ogni singolo messaggio nello stream all'interno di un'estensione deve essere compreso tra 10 e 10.000 millisecondi. Il timeout predefinito è di un secondo.
MatchCondition
  • Ogni MatchCondition all'interno di un ExtensionChain è limitato a un massimo di 10 CELExpressions.
  • La stringa MatchCondition risultante inviata a GCE ha un limite di 512 caratteri.
  • La stringa CELMatcher all'interno di un CELExpression ha una lunghezza massima di 512 caratteri.
  • Per GCPEdgeExtension:
    • Gli attributi di risposta (ad esempio response.code) in CELMatcher non sono supportati.
    • Gli attributi della richiesta non supportati includono backend_service_name e backend_service_project_number.
    • Il numero di espressioni regolari è limitato a 1.
  • In CELExpression è supportato solo il campo backendRefs di tipo Service o ServiceImport.
  • Il campo backendRefs non è supportato con gke-l7-global-external-managed e gke-l7-global-external-managed-mc Gateway Classes
Intestazione
  • L'elenco ForwardHeaders in un Extension può contenere un massimo di 50 nomi di intestazioni HTTP.
Metadati
  • La mappa Metadata in un Extension può contenere un massimo di 16 proprietà.
  • Le chiavi all'interno della mappa Metadata devono avere una lunghezza compresa tra 1 e 63 caratteri.
  • I valori all'interno della mappa Metadata devono essere compresi tra 1 e 1023 caratteri.
Evento
  • SupportedEvents è obbligatorio per un'estensione GCPTrafficExtension.
  • SupportedEvents è facoltativo per un'estensione GCPRoutingExtension.
  • Per GCPEdgeExtension, l'elenco SupportedEvents deve contenere solo RequestHeaders.
  • Se non specificato, si presume che l'evento RequestHeaders sia supportato.
RequestBodySendMode
  • RequestBodySendMode può essere utilizzato solo con backendRefs di tipo Service o ServiceImport.
  • RequestBodySendMode può essere impostato solo se SupportedEvents include RequestBody.
  • Se SupportedEvents include RequestBody, ma RequestBodySendMode non è impostato, viene utilizzato il valore predefinito Streamed.
  • Se RequestBodySendMode è impostato su FullDuplexStreamed, SupportedEvents deve includere sia RequestBody che RequestTrailers.
  • Per un'estensione GCPTrafficExtension, è supportato solo FullDuplexStreamed.
ResponseBodySendMode
  • Il campo ResponseBodySendMode è supportato solo per GCPTrafficExtension.
  • ResponseBodySendMode può essere utilizzato solo con backendRefs di tipo Service o ServiceImport.
  • Il campo può essere impostato solo se SupportedEvents include ResponseBody.
  • Se SupportedEvents include ResponseBody, ma ResponseBodySendMode non è impostato, viene utilizzato il valore predefinito Streamed.
  • Quando questo campo è impostato su FullDuplexStreamed, SupportedEvents deve includere sia ResponseBody che ResponseTrailers.
Riferimenti alle risorse
  • Per GCPEdgeExtension, l'unico tipo di backend supportato è GCPWasmPlugin.
  • Il campo googleAPIServiceName non è supportato per GCPEdgeExtension.
  • Il gateway, l'estensione Edge e il plug-in devono trovarsi nello stesso spazio dei nomi.
GCPWasmPlugin
  • Il campo GCPWasmPlugin è supportato solo per GCPTrafficExtension e GCPEdgeExtension.
  • Le estensioni con GCPWasmPlugin non supportano i seguenti campi:
    • authority
    • timeout
    • metadata
    • requestBodySendMode
    • responseBodySendMode
  • Le estensioni con supporto di GCPWasmPlugin supportano solo gli eventi RequestHeaders, RequestBody, ResponseHeaders e ResponseBody.
GCPAuthzPolicy e GCPAuthzExtension
  • Per un determinato gateway, può esistere una sola policy di autorizzazione con un'azione CUSTOM.
  • Un criterio di autorizzazione con un'azione CUSTOM è limitato a una sola estensione personalizzata.
  • Puoi creare un massimo di cinque policy di autorizzazione a livello di risorsa per gateway.
  • Hai un limite di 10 risorse GCPAuthzExtension e 10 risorse GCPAuthzPolicy per progetto.
  • Una singola risorsa GCPAuthzPolicy può puntare a un massimo di 100 regole di forwarding.
  • Il gateway, GCPAuthzPolicy e GCPAuthzExtension devono trovarsi nello stesso spazio dei nomi. Non sono consentiti riferimenti tra spazi dei nomi.
  • GCPAuthzExtension non può influire sulla selezione del servizio di backend.
  • GCPAuthzExtension riceve solo le intestazioni della richiesta, non il corpo o qualsiasi parte della risposta.
  • IAP è supportato solo per i bilanciatori del carico regionali con GCPAuthzExtension.
  • Quando utilizzi IAP con GCPAuthzExtension, non è possibile impostare le autorizzazioni IAM nella regola di forwarding. Sono consentite solo autorizzazioni a livello di progetto o organizzazione. Per saperne di più, consulta Applicare le autorizzazioni alle risorse.
googleAPIServiceName
  • Il campo googleAPIServiceName è supportato per GCPTrafficExtension e GCPAuthzExtension.
  • authority non deve essere impostato se googleAPIServiceName è impostato.
  • Per un'estensione può essere impostato esattamente un valore tra backendRef e googleAPIServiceName.
backendRef Quando fai riferimento a un servizio che utilizza backendRef in un'estensione, devi soddisfare le seguenti condizioni:
  • Deve utilizzare HTTP2 come appProtocol.
  • Deve trovarsi nello stesso spazio dei nomi dell'estensione e del gateway a cui fa riferimento l'estensione.
  • Impossibile utilizzare IAP.
  • Impossibile utilizzare i criteri di sicurezza di Google Cloud Armor.
  • Non puoi utilizzare Cloud CDN.
  • È necessario impostare esattamente uno dei valori backendRef o googleAPIServiceName per un Extension.
  • Devi impostare authority se backendRef è impostato e kind è Service.
observabilityMode Il campo observabilityMode può essere impostato su Extension con le seguenti limitazioni:
  • Supportato per i cluster GKE sulla versione 1.35.0-gke.3047000 o successive.
  • Supportato dalle risorse GCPTrafficExtension e GCPRoutingExtension collegate ai gateway con classi di gateway regionali.
  • L'opzione observabilityMode abilitata è supportata solo quando i campi requestBodySendMode e responseBodySendMode non sono impostati o sono impostati su Streamed.

Fare riferimento a un servizio

In Service Extensions, puoi fare riferimento a un servizio che ospita la logica personalizzata che vuoi che il bilanciatore del carico esegua. I gateway non hanno Service Extensions per impostazione predefinita.

Per configurare le estensioni di servizio GKE:

  1. Deploy di un servizio di callout di backend: crea un servizio Kubernetes che rappresenti il servizio di backend per l'esecuzione della logica personalizzata. Il bilanciatore del carico richiama questo servizio.

  2. Configura le estensioni di servizio: utilizza l'estensione appropriata in base al tipo di bilanciatore del carico.

    1. GCPRoutingExtension per i gateway regionali: utilizza questa estensione per il bilanciatore del carico delle applicazioni esterno regionale e il bilanciatore del carico delle applicazioni interno regionale per implementare una logica di routing personalizzata all'interno della regione.

    2. GCPTrafficExtension per gateway esterni globali, esterni regionali e interni: utilizza questa estensione per il bilanciatore del carico delle applicazioni esterno globale, il bilanciatore del carico delle applicazioni esterno regionale e il bilanciatore del carico delle applicazioni interno regionale per eseguire la manipolazione del traffico, ad esempio la modifica dell'intestazione o l'ispezione del payload, su vari tipi di bilanciatori del carico.

Esegui il deployment di un servizio di callout di backend

Un servizio di callout implementa una logica personalizzata per le Service Extensions di Gateway in GKE. Il gateway richiama queste applicazioni di backend, in base alle configurazioni di GCPTrafficExtension o GCPRoutingExtension, per modificare o instradare il traffico.

Esegui il deployment di un servizio di callout per aggiungere una logica personalizzata al tuo gateway. Questo servizio separato gestisce l'elaborazione personalizzata, ad esempio la manipolazione dell'intestazione, le trasformazioni del payload o il routing del traffico.

Per eseguire il deployment di un servizio che possa fungere da callout per il tuo gateway, segui questi passaggi:

  1. (Facoltativo) Crea un secret per TLS: Questo comando crea un secret Kubernetes di tipo TLS che contiene il certificato TLS e la chiave privata.

    Per creare il secret TLS per il servizio di callout, sostituisci quanto segue:

    • SECRET_NAME: il nome del secret per il servizio di callout
    • path-to-cert: i percorsi dei file del certificato
    • path-to-key: i percorsi dei file della chiave
  2. Per verificare che il secret sia stato aggiunto, esegui questo comando:

    kubectl get secrets SECRET_NAME
    

    Sostituisci SECRET_NAME con il nome del secret per il tuo servizio di callout.

    L'output dovrebbe essere simile al seguente:

    NAME            TYPE                DATA   AGE
    SECRET_NAME     kubernetes.io/tls   2      12s
    
  3. Definisci le risorse di Deployment e Service.

    Devi definire quanto segue:

    • Deployment: per gestire i pod dell'applicazione che contengono la logica personalizzata per le Service Extensions.
    • Service: per esporre i pod dell'applicazione gestiti dal deployment come servizio di rete.
    1. Crea un manifest di esempio extension-service-app.yaml che contenga le definizioni di Deployment e Service:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: extension-service-app
      spec:
        selector:
          matchLabels:
            app: store
        replicas: 1
        template:
          metadata:
            labels:
              app: store
          spec:
            containers:
            - name: serviceextensions
              image: us-docker.pkg.dev/service-extensions-samples/callouts/python-example-basic:public-image-e42d951
              ports:
              - containerPort: 8080
              - containerPort: 443
              volumeMounts:
              - name: certs
                mountPath: "/etc/certs/"
                readOnly: true
              env:
              - name: POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
              - name: TLS_SERVER_CERT_PATH
                value: "/etc/certs/path-to-cert"
              - name: TLS_SERVER_PRIVKEY
                value: "/etc/certs/path-to-key"
              resources:
                requests:
                  cpu: 10m
            volumes:
            - name: certs
              secret:
                secretName: SECRET_NAME
                optional: false
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: extension-service
      spec:
        ports:
        - port: 443
          targetPort: 443
          appProtocol: HTTP2
        selector:
          app: store
      

      Sostituisci quanto segue:

      • POD_NAME: il nome del pod.
      • SECRET_NAME: il nome del secret per il servizio di callout.
      • TLS_SERVER_CERT_PATH: il percorso del certificato del server TLS all'interno del pod.
      • TLS_SERVER_PRIVKEY: il percorso della chiave privata del server TLS all'interno del pod.
    2. Applica il manifest extension-service-app.yaml:

      kubectl apply -f extension-service-app.yaml
      
  4. Verifica la configurazione:

    1. Verifica che l'applicazione sia stata eseguita il deployment:

      kubectl get pod --selector app=store
      

      Una volta avviata l'applicazione, l'output è simile al seguente:

      NAME                                     READY   STATUS    RESTARTS   AGE
      extension-service-app-85f466bc9b-b5mf4   1/1     Running   0          7s
      
    2. Verifica che il servizio sia stato eseguito il deployment:

      kubectl get service extension-service
      

      L'output è simile al seguente, che mostra un servizio per ogni deployment dello store:

      NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
      extension-service   ClusterIP   34.118.225.9   <none>        443/TCP   2m40s
      

Configura le estensioni di servizio

Puoi configurare un'estensione GCPRoutingExtension o GCPTrafficExtension per personalizzare il flusso di traffico.

Configura l'estensione GCPRoutingExtension per i gateway regionali

Puoi reindirizzare il traffico utilizzando un'estensione GCPRoutingExtension. Per configurare un'estensione GCPRoutingExtension, aggiorna HTTPRoute per specificare le richieste per l'host service-extensions.com.

  1. Aggiorna HTTPRoute. Modifica HTTPRoute in modo da includere nomi host o percorsi che attiveranno l'estensione di routing.

    1. Salva il seguente manifest di esempio come file store-route.yaml:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name:GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      Sostituisci GATEWAY_NAME con il nome del gateway.

    2. Applica il manifest store-route.yaml:

      kubectl apply -f store-route.yaml
      
  2. Definisci GCPRoutingExtension.

    1. Salva la configurazione di GCPRoutingExtension nell'esempio di file gcp-routing-extension.yaml:

      kind: GCPRoutingExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: my-gateway-extension
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            authority: "myext.com"
            timeout: 1s
            backendRef:
              group: ""
              kind: Service
              name: extension-service
              port: 443
      

      Sostituisci GATEWAY_NAME con il nome del gateway.

    2. Applica il manifest di esempio al tuo cluster:

      kubectl apply -f gcp-routing-extension.yaml
      
  3. Verifica la configurazione di GCPRoutingExtension e la relativa associazione al gateway.

    1. Controlla il deployment di GCPRoutingExtension:

      kubectl describe gcproutingextension my-gateway-extension
      

      L'output è simile al seguente:

      Name:         my-gateway-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPRoutingExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      L'output mostra i dettagli di GCPRoutingExtension, denominata my-gateway-extension, all'interno dello spazio dei nomi predefinito. L'output mostra il campo Spec, che contiene la definizione del comportamento dell'estensione.

    2. Verifica l'associazione del gateway:

      1. Verifica che GCPRoutingExtension sia associato al gateway. Questa operazione potrebbe richiedere alcuni minuti:

        kubectl describe gateway GATEWAY_NAME
        

        Sostituisci GATEWAY_NAME con il nome del gateway.

        L'output è simile al seguente:

        Name:         GATEWAY_NAME
        Namespace:    default
        Labels:       none
        Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                      networking.gke.io/backend-services:
                        /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                      networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                      networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                      networking.gke.io/health-checks:
                        /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                      networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                      networking.gke.io/lb-route-extensions:
                        /projects/1234567890/locations/us-central1/lbRouteExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                      networking.gke.io/lb-traffic-extensions:
                      networking.gke.io/ssl-certificates:
                      networking.gke.io/target-http-proxies:
                        /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                      networking.gke.io/target-https-proxies:
                      networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
        API Version:  gateway.networking.k8s.io/v1
        Kind:         Gateway
        Metadata:
          Creation Timestamp:  2025-03-02T16:37:50Z
          Finalizers:
          gateway.finalizer.networking.gke.io
          Generation:        1
          Resource Version:  31284863
          UID:               fd512611-bad2-438e-abfd-5619474fbf31
        ...
        

        L'output mostra le annotazioni, che GKE utilizza per memorizzare i link tra il gateway e le risorse Cloud de Confiance sottostanti. L'annotazione networking.gke.io/lb-route-extensions conferma il binding del gateway a GCPRoutingExtension.

      2. Controlla lo stato dell'estensione verificando che GCPRoutingExtension abbia lo stato Programmed con il motivo ProgrammingSucceeded. Questo comando potrebbe richiedere alcuni minuti.

        kubectl describe gcproutingextension my-gateway-extension
        

        L'output è simile al seguente:

        Name:         my-gateway-extension
        Namespace:    default
        Labels:       <none>
        Annotations:  <none>
        API Version:  networking.gke.io/v1
        Kind:         GCPRoutingExtension
        Metadata:
          Creation Timestamp:  2025-03-02T17:12:30Z
          Generation:          1
          Resource Version:    31284378
          UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
        Spec:
          Extension Chains:
            Extensions:
              Authority:  myext.com
              Backend Ref:
                Group:
                Kind:   Service
                Name:   extension-service
                Port:   443
              Name:     ext1
              Timeout:  1s
            Match Condition:
              Cel Expressions:
                Cel Matcher:  request.path.contains("serviceextensions")
            Name:             chain1
          Target Refs:
            Group:  gateway.networking.k8s.io
            Kind:   Gateway
            Name:   GATEWAY_NAME
        Status:
          Ancestors:
            Ancestor Ref:
              Group:      gateway.networking.k8s.io
              Kind:       Gateway
              Name:       GATEWAY_NAME
              Namespace:  default
            Conditions:
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                Accepted
              Status:                True
              Type:                  Accepted
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                ProgrammingSucceeded
              Status:                True
              Type:                  Programmed
            Controller Name:         networking.gke.io/gateway
        Events:
          Type    Reason  Age                From                   Message
          ----    ------  ----               ----                   -------
          Normal  ADD     2m31s              sc-gateway-controller  default/my-gateway-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        GATEWAY_NAME,
        SectionName: nil,
        Port:        nil} was a success
          Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        GATEWAY_NAME,
        SectionName: nil,
        Port:        nil} was a success
        

        Il campo Status.Conditions mostra una condizione Programmed con Status: True e Reason: ProgrammingSucceeded. Queste informazioni confermano che l'estensione è stata applicata correttamente.

  4. Inviare traffico alla tua applicazione.

    Dopo che il gateway, la route e l'applicazione sono stati sottoposti a deployment nel cluster, puoi trasferire il traffico all'applicazione.

    1. Per accedere all'applicazione, devi trovare l'indirizzo IP del tuo gateway.

      Nel terminale, utilizza il seguente comando:

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      Sostituisci GATEWAY_NAME con il nome del gateway.

      Questo comando restituisce l'indirizzo IP del gateway. Nei comandi successivi, sostituisci GATEWAY_IP_ADDRESS con l'indirizzo IP dell'output.

    2. Testa l'aggiornamento del percorso accedendo alla versione serviceextensions del servizio di archiviazione all'indirizzo store.example.com/serviceextensions:

      curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
      

      L'output è simile al seguente:

      {
      "cluster_name": "gke1",
      "host_header": "service-extensions.com",
      "metadata": "store-v1",
      "pod_name": "store-v1-5d9554f847-cvxpd",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo",
      "timestamp": "2025-03-15T12:00:00",
      "zone": "us-central1-c"
      }
      

Configura GCPTrafficExtension

Puoi utilizzare un GCPTrafficExtension per utilizzare funzionalità avanzate di gestione del traffico all'interno del tuo ambiente Cloud de Confiance . Puoi configurare questa estensione nei bilanciatori del carico delle applicazioni esterni globali, nei bilanciatori del carico delle applicazioni esterni regionali e nei bilanciatori del carico delle applicazioni interni regionali. Puoi utilizzare GCPTrafficExtension per implementare logica personalizzata per richieste e risposte HTTP, routing sofisticato, trasformazioni e policy di sicurezza.

  1. Aggiorna HTTPRoute. Modifica HTTPRoute in modo da includere nomi host o percorsi che attiveranno l'estensione del traffico.

    1. Salva il seguente manifest di esempio come file store-route.yaml:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name: GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      Sostituisci GATEWAY_NAME con il nome del tuo gateway, ad esempio internal-http, external-http o global-external-http.

    2. Applica il manifest store-route.yaml al tuo cluster:

      kubectl apply -f store-route.yaml
      
  2. Definisci GCPTrafficExtension.

    1. Salva la configurazione di GCPTrafficExtension nel file di esempio gcp-traffic-extension.yaml:

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
      name: my-traffic-extension
      namespace: default
      spec:
      targetRefs:
      - group: "gateway.networking.k8s.io"
        kind: Gateway
        name: GATEWAY_NAME
      extensionChains:
      - name: chain1
        matchCondition:
          celExpressions:
          - celMatcher: request.path.contains("serviceextensions")
        extensions:
        - name: ext1
          authority: "myext.com"
          timeout: 1s
          backendRef:
            group: ""
            kind: Service
            name: extension-service
            port: 443
          supportedEvents:
            - RequestHeaders
            - RequestBody
            - ResponseHeaders
            - ResponseBody
      

      Sostituisci GATEWAY_NAME con il nome del tuo gateway, come internal-http, external-http o global-external-http.

    2. Applica il manifest di esempio al tuo cluster:

      kubectl apply -f gcp-traffic-extension.yaml
      
  3. Verifica la configurazione di GCPTrafficExtension e il relativo binding al gateway.

    1. Controlla il deployment di GCPTrafficExtension:

      kubectl describe gcptrafficextension my-traffic-extension
      

      L'output è simile al seguente:

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      L'output mostra i dettagli di GCPTrafficExtension denominato my-traffic-extension all'interno dello spazio dei nomi predefinito. Mostra il campo Spec, che contiene la definizione del comportamento dell'estensione.

    2. Verifica l'associazione del gateway:

      Verifica che GCPTrafficExtension sia associato al gateway. Il completamento di questo comando potrebbe richiedere alcuni minuti:

      kubectl describe gateway GATEWAY_NAME
      

      L'output è simile al seguente:

      Name:         GATEWAY_NAME
      Namespace:    default
      Labels:       <none>
      Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                    networking.gke.io/backend-services:
                      /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                    networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                    networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                    networking.gke.io/health-checks:
                      /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                    networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                    networking.gke.io/lb-traffic-extensions:
                      /projects/1234567890/locations/us-central1/lbTrafficExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                    networking.gke.io/ssl-certificates:
                    networking.gke.io/target-http-proxies:
                      /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                    networking.gke.io/target-https-proxies:
                    networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
      API Version:  gateway.networking.k8s.io/v1
      Kind:         Gateway
      Metadata:
        Creation Timestamp:  2025-03-02T16:37:50Z
        Finalizers:
          gateway.finalizer.networking.gke.io
        Generation:        1
        Resource Version:  31284863
        UID:               fd512611-bad2-438e-abfd-5619474fbf31
      ...
      

      L'output mostra le annotazioni, che GKE utilizza per archiviare i link tra il gateway e le risorse Cloud de Confiance sottostanti. L'annotazione networking.gke.io/lb-traffic-extensions conferma il binding.

    3. Controlla lo stato dell'estensione:

      Per controllare lo stato dell'estensione GCPTrafficExtension, esegui il seguente comando:

      kubectl describe gcptrafficextension my-traffic-extension
      

      Verifica che GCPTrafficExtension abbia lo stato Programmed con il motivo ProgrammingSucceeded. Il completamento del comando potrebbe richiedere alcuni minuti.

      L'output della risorsa GCPTrafficExtension è simile al seguente:

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:          1
        Resource Version:    31284378
        UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:  myext.com
            Backend Ref:
              Group:
              Kind:   Service
              Name:   extension-service
              Port:   443
            Name:     ext1
            Timeout:  1s
          Match Condition:
            Cel Expressions:
              Cel Matcher:  request.path.contains("serviceextensions")
          Name:             chain1
        Target Refs:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   GATEWAY_NAME
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       GATEWAY_NAME
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                ProgrammingSucceeded
            Status:                True
            Type:                  Programmed
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                From                   Message
        ----    ------  ----               ----                   -------
        Normal  ADD     2m31s              sc-gateway-controller  default/my-traffic-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPTrafficExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        GATEWAY_NAME,
        SectionName: nil,
        Port:        nil} was a success
        Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPTrafficExtension "default/my-traffic-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        GATEWAY_NAME,
        SectionName: nil,
        Port:        nil} was a success
      

      Il campo Status.Conditions mostra una condizione Programmed con Status: True e Reason: ProgrammingSucceeded. Queste informazioni confermano che l'estensione è stata applicata correttamente.

  4. Inviare traffico alla tua applicazione.

    Dopo che il gateway, la route e l'applicazione sono stati sottoposti a deployment nel cluster, puoi trasferire il traffico all'applicazione.

    1. Per accedere all'applicazione, devi trovare l'indirizzo IP del tuo gateway.

      Nel terminale, utilizza il seguente comando:

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      Sostituisci GATEWAY_NAME con il nome del gateway.

      Questo comando restituisce l'indirizzo IP del gateway. Nei comandi successivi, sostituisci GATEWAY_IP_ADDRESS con l'indirizzo IP dell'output.

    2. Testa l'aggiornamento del percorso accedendo alla versione serviceextensions del servizio di archiviazione all'indirizzo store.example.com/serviceextensions:

      curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
      

      L'output è simile al seguente:

      {
      *   Request completely sent off
      < HTTP/1.1 200 OK
      < server: Werkzeug/2.3.7 Python/3.11.3
      < date: Sun, 02 Mar 2025 16:58:10 GMT
      < content-type: application/json
      < access-control-allow-origin: *
      < hello: service-extensions
      < via: 1.1 google
      < transfer-encoding: chunked
      }
      

Configura la risorsa GCPAuthzExtension

Puoi utilizzare un GCPAuthzExtension con un GCPAuthzPolicy per applicare decisioni di autorizzazione complesse delegandole a un servizio esterno o a Identity-Aware Proxy (IAP).

  1. Definisci l'estensione GCPAuthzExtension:

    Puoi configurare GCPAuthzExtension in modo che faccia riferimento a un servizio di estensione personalizzato o a IAP come servizio di callout.

    • Opzione 1: fai riferimento a un servizio di estensione personalizzato

      1. Salva la configurazione di GCPAuthzExtension nel file gcp-authz-extension.yaml di esempio:
      apiVersion: networking.gke.io/v1
      kind: GCPAuthzExtension
      metadata:
        name: my-authz-ext
        namespace: default
      spec:
        backendRef:
          kind: Service
          name: "${authz-service}"
        forwardHeaders:
        - Authorization
        failOpen: false
        timeout: "0.1s"
        wireFormat: EXT_PROC_GRPC
      

      Nell'esempio precedente, "${authz-service}" è un servizio di estensione, che deve essere presente nello stesso spazio dei nomi di GCPAuthzPolicy.

      1. Applica il manifest:
      kubectl apply -f gcp-authz-extension.yaml
      
    • Opzione 2: fai riferimento all'IAP come servizio di callout personalizzato

      Puoi anche configurare IAP come servizio di callout personalizzato specificando iap.googleapis.com nel campo googleAPIServiceName:

      1. Salva la configurazione di GCPAuthzExtension nel file authz-extension-iap.yaml di esempio:
      apiVersion: networking.gke.io/v1
      kind: GCPAuthzExtension
      metadata:
        name: my-authz-ext-iap
        namespace: default
      spec:
        googleAPIServiceName: iap.googleapis.com
        timeout: 50ms
        failOpen: false
      
      1. Applica il manifest:
      kubectl apply -f authz-extension-iap.yaml
      
  2. Definisci GCPAuthzPolicy:

    GCPAuthzPolicy ha come target il gateway e specifica l'azione da intraprendere sul traffico corrispondente:

    • Configura una policy di autorizzazione CUSTOM:

      L'azione CUSTOM delega la decisione di autorizzazione all'estensione che hai creato nel passaggio precedente.

      1. Salva il seguente manifest in gcp-authz-policy.yaml:

        apiVersion: networking.gke.io/v1
        kind: GCPAuthzPolicy
        metadata:
          name: my-gateway-authz
          namespace: default
        spec:
          enforcementLevel: L7
          targetRefs:
          - group: gateway.networking.k8s.io
            kind: Gateway
            name: "GATEWAY_NAME"
          rules:
          - from:
              sources:
              - principals:
                - principal_selector: CLIENT_CERT_URI_SANS
                  principal:
                    exact: "spiffee://cluster.local/ns1/pod1"
          - to:
              operations:
              - paths:
                - exact: "/api/secure-endpoint"
          action: CUSTOM
          customProvider:
            authzExtension:
              extensionRefs:
              - group: networking.gke.io
                kind: GCPAuthzExtension
                name: my-authz-ext
        

        Sostituisci GATEWAY_NAME con il nome del gateway.

      2. Applica il manifest:

        kubectl apply -f gcp-authz-policy.yaml
        

Fare riferimento a una risorsa GCPWasmPlugin

Puoi inserire una logica personalizzata direttamente nel percorso dei dati del bilanciatore del carico utilizzando un GCPWasmPlugin con un'estensione GCPTrafficExtension o GCPEdgeExtension. Questo metodo consente di eseguire il deployment di funzionalità di gestione del traffico personalizzate pacchettizzate come modulo Wasm.

Per configurare le estensioni di servizio GKE:

  1. Esegui il deployment di un GCPWasmPlugin: crea ed esegui il deployment di una CustomResourceDefinition (CRD) GCPWasmPlugin che contiene il codice personalizzato per il tuo modulo Wasm. Puoi utilizzare GCPWasmPlugin con GCPTrafficExtension o GCPEdgeExtension per gke-l7-global-external-managed GatewayClass.

  2. Configura le estensioni di servizio: configura una delle seguenti estensioni con GCPWasmPlugin:

Esegui il deployment di un GCPWasmPlugin

Il plug-in GCPWasmPlugin consente di inserire una logica personalizzata scritta dall'utente direttamente nel percorso dei dati del bilanciatore del carico Cloud de Confiance . La risorsa GCPWasmPlugin punta all'immagine del modulo Wasm in Artifact Registry, che viene poi eseguita dal bilanciatore del carico.

Prima di continuare con i passaggi seguenti, assicurati di aver caricato il modulo Wasm in un repository Artifact Registry. Per saperne di più, consulta Preparare il codice del plug-in.

Per eseguire il deployment di una risorsa GCPWasmPlugin, completa i seguenti passaggi:

  1. Salva il seguente manifest come wasm-plugin.yaml:

    kind: GCPWasmPlugin
    apiVersion: networking.gke.io/v1
    metadata:
      name: gcp-wasm-plugin
    spec:
      versions:
      - name: wasm-plugin-version
        description: "Test wasm plugin version"
        image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main"
        weight: 1000000
      logConfig:
        enabled: true
        # Configures the sampling rate of activity logs.
        # The value of the field must be in range [0, 1e6].
        sampleRate: 1000000
        # Specifies the lowest level of logs that are exported to Cloud Logging.
        minLogLevel: INFO
    

    Tieni presente quanto segue:

    • spec.versions.name: il nome della versione deve essere univoco all'interno della risorsa GCPWasmPlugin. Puoi elencare fino a 10 versioni e solo una deve avere un peso diverso da zero.
    • spec.versions.image: fa riferimento all'immagine contenente il codice del plug-in archiviato in Artifact Registry.
    • spec.versions.weight: specifica il peso della versione del plug-in. Il peso deve essere un numero compreso tra 0 e 1.000.000 inclusi.
    • spec.logConfig: specifica se abilitare Cloud Logging per questo plug-in. Se il valore non è specificato, Cloud Logging è disattivato per impostazione predefinita.
    • spec.logConfig.sampleRate: configura la frequenza di campionamento dei log delle attività. La frequenza deve essere un numero compreso tra 0 e 1.000.000, inclusi. Se non specificato quando Cloud Logging è abilitato, il valore predefinito è 1,000,000 (viene registrato il 100% delle richieste).
    • spec.logConfig.minLogLevel: specifica il livello più basso di log esportati in Cloud Logging. Se il valore non viene specificato quando Cloud Logging è abilitato, il campo viene impostato su INFO per impostazione predefinita.
  2. Applica il manifest wasm-plugin.yaml:

    kubectl apply -f wasm-plugin.yaml
    
  3. Verifica che il plug-in sia stato implementato:

    kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-plugin
    

    L'output è simile al seguente:

    Name:         gcp-wasm-plugin
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         GCPWasmPlugin
    Metadata:
      Creation Timestamp:  2025-08-08T19:54:18Z
      Generation:          1
      Resource Version:    44578
      UID:                 549a12c7-91d1-43ad-a406-d6157a799b79
    Spec:
      Log Config:
        Enabled: true
        Min Log Level: INFO
        Sample Rate: 1000000
      Versions:
        Description:  Test wasm plugin version
        Image:        us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main
        Name:         wasm-plugin-version
        Weight:       1000000
      Events:     <none>
    

Configura GCPTrafficExtension

Per aggiungere logica personalizzata al bilanciatore del carico delle applicazioni esterno globale, puoi configurare un GCPTrafficExtension per utilizzare un GCPWasmPlugin. Puoi utilizzare un'estensione GCPTrafficExtension per utilizzare funzionalità avanzate di gestione del traffico all'interno del tuo ambiente Cloud de Confiance . Puoi configurare questa estensione in tutti i bilanciatori del carico delle applicazioni esterni globali.

Per configurare un GCPTrafficExtension in modo che utilizzi un GCPWasmPlugin, completa i seguenti passaggi:

  1. Definisci GCPTrafficExtension.

    1. Salva la configurazione di GCPTrafficExtension come gcp-traffic-extension-with-plugin.yaml:

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: gcp-traffic-extension-with-plugin
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            supportedEvents:
            - RequestHeaders
            - ResponseHeaders
            backendRef:
              group: "networking.gke.io"
              kind: GCPWasmPlugin
              name: gcp-wasm-plugin
      

      Sostituisci GATEWAY_NAME con il nome del tuo gateway, ad esempio global-external-http.

    2. Applica il manifest di esempio al tuo cluster:

      kubectl apply -f gcp-traffic-extension-with-plugin.yaml
      
  2. Verifica la configurazione di GCPTrafficExtension e il relativo binding al gateway.

    1. Controlla il deployment di GCPTrafficExtension:

      kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-plugin
      

      L'output è simile al seguente:

      Name:         gcp-traffic-extension-with-plugin
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Backend Ref:
              Group: networking.gke.io
              Kind: GCPWasmPlugin
              Name: gcp-wasm-plugin
            Name:       ext1
            Supported Events:
              RequestHeaders
              ResponseHeaders
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      Sostituisci GATEWAY_NAME con il nome del gateway.

      L'output mostra i dettagli di GCPTrafficExtension denominato gcp-traffic-extension-with-plugin all'interno dello spazio dei nomi predefinito. Mostra il campo Spec, che contiene la definizione del comportamento dell'estensione.

    2. Verifica l'associazione del gateway:

      Verifica che GCPTrafficExtension sia associato al gateway. Il completamento di questo comando potrebbe richiedere alcuni minuti:

      kubectl describe gateway GATEWAY_NAME
      

      Sostituisci GATEWAY_NAME con il nome del gateway.

      L'output è simile al seguente:

      Name:         GATEWAY_NAME
      Namespace:    default
      Labels:       <none>
      Annotations:  networking.gke.io/addresses: /projects/922988411345/global/addresses/test-k18j-default-external-http-2jfqxrkgd0fm
                    networking.gke.io/backend-services:
                      /projects/922988411345/global/backendServices/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/backendServices...
                      networking.gke.io/certmap: store-example-com-map
                      networking.gke.io/firewalls: /projects/922988411345/global/firewalls/test-k18j-l7-default-global
                      networking.gke.io/forwarding-rules: /projects/922988411345/global/forwardingRules/test-k18j-default-external-http-wt1tl0cwi6zr
                      networking.gke.io/health-checks:
                        /projects/922988411345/global/healthChecks/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/healthChecks/test-...
                      networking.gke.io/last-reconcile-time: 2025-08-08T20:27:35Z
                      networking.gke.io/lb-route-extensions:
                      networking.gke.io/lb-traffic-extensions:
                        projects/922988411345/locations/global/lbTrafficExtensions/test-k18j-default-external-http-0tdum40yts35
                      networking.gke.io/ssl-certificates:
                      networking.gke.io/target-http-proxies:
                      networking.gke.io/target-https-proxies: /projects/922988411345/global/targetHttpsProxies/test-k18j-default-external-http-jy9mc97xb5yh
                      networking.gke.io/url-maps: /projects/922988411345/global/urlMaps/test-k18j-default-external-http-jy9mc97xb5yh
                      networking.gke.io/wasm-plugin-versions:
                        projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk/versions/test-k18j-wasm-plugin-version-i...
                      networking.gke.io/wasm-plugins: projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk
      API Version:  gateway.networking.k8s.io/v1
      Kind:         Gateway
      Metadata:
        Creation Timestamp:  2025-03-02T16:37:50Z
        Finalizers:
          gateway.finalizer.networking.gke.io
        Generation:        1
        Resource Version:  31284863
        UID:               fd512611-bad2-438e-abfd-5619474fbf31
      Spec:
        Gateway Class Name:  gke-l7-global-external-managed
        Listeners:
          Allowed Routes:
            Namespaces:
              From:  Same
          Name:      https
          Port:      443
          Protocol:  HTTPS
      ...
      

      L'output mostra le annotazioni, che GKE utilizza per archiviare i collegamenti tra il gateway e le risorse Cloud de Confiance sottostanti. Le annotazioni networking.gke.io/lb-traffic-extensions, networking.gke.io/wasm-plugin-versions e networking.gke.io/wasm-plugins confermano il binding.

    3. Controlla lo stato dell'estensione:

      Verifica che GCPTrafficExtension abbia lo stato Programmed con il motivo ProgrammingSucceeded. Il completamento del comando potrebbe richiedere alcuni minuti.

      kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-plugin
      

      L'output è simile al seguente:

      Name:         gcp-traffic-extension-with-plugin
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-08-08T20:08:09Z
        Generation:          1
        Resource Version:    56528
        UID:                 1389f790-9663-45ca-ac4e-a2c082f43359
      Spec:
        Extension Chains:
          Extensions:
            Backend Ref:
              Group:  networking.gke.io
              Kind:   GCPWasmPlugin
              Name:   gcp-wasm-plugin
            Name:     ext1
            Supported Events:
              RequestHeaders
              ResponseHeaders
          Match Condition:
            Cel Expressions:
              Cel Matcher:  request.path.contains("serviceextensions")
          Name:             chain1
        Target Refs:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   external-http
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       external-http
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-08-08T20:16:13Z
            Message:
            Observed Generation:   1
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-08-08T20:16:13Z
            Message:
            Observed Generation:   1
            Reason:                ResolvedRefs
            Status:                True
            Type:                  ResolvedRefs
            Last Transition Time:  2025-08-08T20:16:13Z
            Message:
            Observed Generation:   1
            Reason:                ProgrammingSucceeded
            Status:                True
            Type:                  Programmed
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                  From                   Message
        ----    ------  ----                 ----                   -------
        Normal  ADD     19m                  sc-gateway-controller  default/gcp-traffic-extension-with-plugin
        Normal  SYNC    3m25s (x4 over 11m)  sc-gateway-controller  Attachment of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
        Normal  SYNC  3m25s (x4 over 11m)  sc-gateway-controller  All the object references were able to be resolved for GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" bound to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil}
        Normal  SYNC  3m25s (x4 over 11m)  sc-gateway-controller  Programming of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
      
    4. Controlla lo stato del plug-in.

      Verifica che la risorsa GCPWasmPlugin abbia lo stato Programmed con il motivo ProgrammingSucceeded. Il completamento del comando potrebbe richiedere alcuni minuti.

      kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-plugin
      

      L'output è simile al seguente:

      Name:         gcp-wasm-plugin
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPWasmPlugin
      Metadata:
        Creation Timestamp:  2025-08-08T19:54:18Z
        Generation:          1
        Resource Version:    44578
        UID:                 549a12c7-91d1-43ad-a406-d6157a799b79
      Spec:
        Log Config:
          Enabled: true
          Min Log Level: INFO
          Sample Rate: 1000000
        Versions:
          Description:  Test wasm plugin version
          Image:        us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main
          Name:         wasm-plugin-version
          Weight:       1000000
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       external-http
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-08-08T19:59:06Z
            Message:
            Observed Generation:   1
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-08-08T19:59:06Z
            Message:
            Observed Generation:   1
            Reason:                ResolvedRefs
            Status:                True
            Type:                  ResolvedRefs
            Last Transition Time:  2025-08-08T19:59:06Z
            Message:
            Observed Generation:   1
            Reason:                ProgrammingSucceeded
            Status:                True
            Type:                  Programmed
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                 From                   Message
        ----    ------  ----                ----                   -------
        Normal  ADD     31m                 sc-gateway-controller  default/gcp-wasm-plugin
        Normal  SYNC    2m1s (x7 over 26m)  sc-gateway-controller  Attachment of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
        Normal  SYNC  2m1s (x7 over 26m)  sc-gateway-controller  All the object references were able to be resolved for WasmPlugin "default/gcp-wasm-plugin" bound to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil}
        Normal  SYNC  2m1s (x7 over 26m)  sc-gateway-controller  Programming of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
      
  3. Inviare traffico alla tua applicazione.

    Dopo che il gateway, la route e l'applicazione sono stati sottoposti a deployment nel cluster, puoi trasferire il traffico all'applicazione.

    1. Per accedere all'applicazione, devi trovare l'indirizzo IP del tuo gateway.

      Nel terminale, utilizza il seguente comando:

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      Sostituisci GATEWAY_NAME con il nome del gateway.

      Questo comando restituisce l'indirizzo IP del gateway. Nei comandi successivi, sostituisci GATEWAY_IP_ADDRESS con l'indirizzo IP dell'output.

    2. Testa l'aggiornamento del percorso accedendo alla versione serviceextensions del servizio di archiviazione all'indirizzo store.example.com/serviceextensions:

      curl https://store.example.com/serviceextensions --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
      

      L'output restituisce Hello World.

Configurare GCPEdgeExtension con GCPWasmPlugin

Per aggiungere una logica personalizzata al bilanciatore del carico delle applicazioni esterno globale utilizzando un modulo WebAssembly (Wasm), configura un GCPEdgeExtension che fa riferimento a GCPWasmPlugin.

  1. Salva il seguente manifest di GCPEdgeExtension come gcp-edge-extension-with-plugin.yaml:

    kind: GCPEdgeExtension
    apiVersion: networking.gke.io/v1
    metadata:
      name: gcp-edge-extension-with-plugin
      namespace: default
    spec:
      targetRefs:
      - group: "gateway.networking.k8s.io"
        kind: Gateway
        name: GATEWAY_NAME
      extensionChains:
      - name: chain1
        matchCondition:
          celExpressions:
          - celMatcher: request.path.startsWith("/serviceextensions")
        extensions:
        - name: ext1
          supportedEvents:
          - RequestHeaders
          backendRef:
            group: "networking.gke.io"
            kind: GCPWasmPlugin
            name: gcp-wasm-plugin
    

    Sostituisci GATEWAY_NAME con il nome del gateway.

  2. Applica il manifest al tuo cluster:

    kubectl apply -f gcp-edge-extension-with-plugin.yaml
    
  3. Verifica la configurazione di GCPEdgeExtension e il relativo binding al gateway:

    1. Controlla lo stato dell'estensione:

      Per controllare lo stato dell'estensione GCPEdgeExtension, esegui questo comando:

      kubectl describe gcpedgeextensions.networking.gke.io gcp-edge-extension-with-plugin
      

      Verifica che GCPEdgeExtension abbia lo stato Programmed con il motivo ProgrammingSucceeded. Il completamento di questo comando potrebbe richiedere alcuni minuti.

    2. Verifica l'associazione del gateway:

      Esegui questo comando:

      kubectl describe gateway GATEWAY_NAME
      

      Sostituisci GATEWAY_NAME con il nome del gateway.

      Verifica che GCPEdgeExtension sia associato al gateway. Il completamento di questo comando potrebbe richiedere alcuni minuti. L'output include l'annotazione networking.gke.io/lb-edge-extensions, che conferma il collegamento tra il gateway e l'estensione edge.

Inviare traffico all'estensione

Dopo aver eseguito il deployment di Gateway e GCPEdgeExtension, testa la logica di routing inviando traffico alla tua applicazione.

  1. Per accedere all'applicazione, ottieni l'indirizzo IP del gateway:

    kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"
    

    L'output è l'indirizzo IP del gateway. Nei comandi seguenti, sostituisci GATEWAY_IP_ADDRESS con l'indirizzo IP dell'output.

  2. Invia una richiesta all'URL di base:

    curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    Il gateway indirizza la richiesta al servizio predefinito, ad esempio store-v1.

  3. Invia una richiesta al percorso specificato in celMatcher, ad esempio /serviceextensions:

    curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    L'estensione attiva il plug-in Wasm, che indirizza la richiesta al servizio secondario, ad esempio store-v2.

Gestire la risorsa GCPWasmPlugin

Puoi aggiornare il CRD GCPWasmPlugin e monitorare il plug-in.

Aggiornare GCPWasmPlugin

Per aggiornare una risorsa GCPWasmPlugin:

  1. Apporta la modifica nel file manifest di GCPWasmPlugin e segui i passaggi descritti in Deploy di un plug-in GCPWasmPlugin.

    Ad esempio, per avere due versioni del plug-in, una che gestisce il traffico e l'altra no, aggiorna il file wasm-plugin.yaml nel seguente modo:

    kind: GCPWasmPlugin
    apiVersion: networking.gke.io/v1
    metadata:
      name: gcp-wasm-plugin
    spec:
      versions:
      - name: wasm-plugin-version-v1
        description: "Serving Wasm Plugin version"
        image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main"
        weight: 1000000
      - name: wasm-plugin-version-v2
        description: "Non serving Wasm Plugin version"
        image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main"
        weight: 0
      logConfig:
        enabled: true
        sampleRate: 1000000
        minLogLevel: INFO
    

    In questo esempio, si applica quanto segue:

    • wasm-plugin-version-v1 ha un weight di 1000000, il che significa che gestisce tutto il traffico.
    • wasm-plugin-version-v2 ha un weight di 0, il che significa che non eroga traffico.
  2. Per assicurarti che il gateway sia aggiornato, esegui il comando seguente. Il completamento di questo comando potrebbe richiedere alcuni minuti:

    kubectl describe gateway GATEWAY_NAME
    

    Sostituisci GATEWAY_NAME con il nome del gateway.

Monitora GCPWasmPlugin

Per visualizzare le metriche per GCPWasmPlugin nella console Cloud de Confiance , consulta Monitoraggio dal punto di vista dei plug-in.

Quando raggiungi il passaggio della guida in cui devi selezionare un valore dall'elenco Filtro versione plug-in, cerca il formato prefix−WASM_PLUGIN_VERSION_NAME_FROM_FILE−suffix, dove WASM_PLUGIN_VERSION_NAME_FROM_FILE è il nome della versione specifica che hai definito nel file di configurazione GCPWasmPlugin.

Risolvere i problemi relativi alle estensioni del traffico sui gateway

Questa sezione fornisce suggerimenti per la risoluzione dei problemi relativi alla configurazione delle estensioni del traffico sui gateway.

Gateway non trovato

Il seguente errore indica che la risorsa Gateway specificata nel campo targetRefs della risorsa GCPTrafficExtension, GCPRoutingExtension o GCPEdgeExtension non esiste:

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.gatewayRef: gateway "my-gateway" not found in namespace "default"

Per risolvere il problema, assicurati che la risorsa Gateway specificata nel campo targetRefs della risorsa GCPTrafficExtension o GCPRoutingExtension esista nello spazio dei nomi specificato.

Servizio o porta del servizio non trovati

Il seguente errore indica che il servizio o la porta del servizio specificati nel campo backendRef della risorsa GCPTrafficExtension o GCPRoutingExtension non esiste:

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: service "callout-service" not found in namespace "default"

Per risolvere il problema, assicurati che il servizio e la porta di servizio specificati nel campo backendRef della risorsa GCPTrafficExtension o GCPRoutingExtension esistano nello spazio dei nomi specificato.

Nessun endpoint di rete nel NEG

Il seguente errore indica che nessun endpoint di rete nel NEG è associato al servizio specificato nel campo backendRef della risorsa GCPTrafficExtension o GCPRoutingExtension:

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: no network endpoints found for service "callout-service"

Per risolvere il problema, assicurati che il servizio specificato nel campo backendRef della risorsa GCPTrafficExtension o GCPRoutingExtension disponga di endpoint di rete.

Nessuna risposta o risposta con un errore durante l'invio della richiesta

Se non ricevi una risposta o se ricevi una risposta con un errore quando invi una richiesta, potrebbe indicare che il servizio di callout non funziona correttamente.

Per risolvere il problema, controlla la presenza di errori nei log del servizio di callout.

Codice di errore 404 nel payload JSON

Il seguente errore indica che il callout Service non è stato trovato o non risponde alla richiesta:

{
  "error": {
    "code": 404,
    "message": "Requested entity was not found.",
    "status": "NOT_FOUND"
  }
}

Per risolvere il problema, assicurati che il callout Service sia in esecuzione, che sia in ascolto sulla porta corretta e che il servizio sia configurato correttamente nella risorsa GCPTrafficExtension o GCPRoutingExtension.

Codice di errore 500 nel payload JSON

Il seguente errore indica che il callout Service sta riscontrando un errore interno del server:

{
  "error": {
    "code": 500,
    "message": "Internal server error.",
    "status": "INTERNAL"
  }
}

Per risolvere il problema, controlla i log del servizio di callout per identificare la causa dell'errore interno del server.

GCPWasmPlugin non esiste

Il seguente errore indica che la risorsa GCPWasmPlugin non esiste nel tuo progetto per GCPTrafficExtension o GCPEdgeExtension:

Status:
  Ancestors:
    Ancestor Ref:
      Group:      gateway.networking.k8s.io
      Kind:       Gateway
      Name:       external-http
      Namespace:  default
    Conditions:
      Last Transition Time:  2025-03-06T16:27:57Z
      Message:
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2025-03-06T16:27:57Z
      Message:               error cause: invalid-wasm-plugin: GCPWasmPlugin default/my-wasm-plugin in GCPTrafficExtension default/my-gateway-plugin-extension does not exist
      Reason:                GCPWasmPluginNotFound
      Status:                False
      Type:                  ResolvedRefs
    Controller Name:         networking.gke.io/gateway

Per risolvere il problema, crea un GCPWasmPlugin corrispondente nel progetto Cloud de Confiance o indirizza un'estensione a un GCPWasmPlugin esistente.

Passaggi successivi