Il codice personalizzato che crei per i plug-in Service Extensions deve essere pacchettizzato e caricato in Artifact Registry prima che altri servizi possano accedervi. Questa pagina descrive come creare il codice del plug-in, creare il pacchetto del codice e caricarlo in un repository Artifact Registry.
Questa funzionalità è in anteprima per Media CDN.
Per informazioni su Service Extensions, consulta la panoramica di Service Extensions.
Prima di iniziare, consulta le best practice per la scrittura del codice del plug-in.
Per altri esempi, vedi Esempi di codice per i plug-in.
Prima di iniziare
- Accedi al tuo account Google Cloud . Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti senza costi per l'esecuzione, il test e il deployment dei workload.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Network Services, Network Actions, Artifact Registry, Cloud Build, Cloud Logging, and Cloud Monitoring APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
Installa Google Cloud CLI.
-
Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.
-
Per inizializzare gcloud CLI, esegui questo comando:
gcloud init -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Network Services, Network Actions, Artifact Registry, Cloud Build, Cloud Logging, and Cloud Monitoring APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
Installa Google Cloud CLI.
-
Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.
-
Per inizializzare gcloud CLI, esegui questo comando:
gcloud init
Configura la toolchain
C++
L'SDK Proxy-Wasm C++ consente agli sviluppatori di utilizzare C++ per implementare plug-in WebAssembly (Wasm) per Service Extensions. L'SDK utilizza la toolchain C++ WebAssembly Emscripten, nonché altre librerie, come protobuf e, facoltativamente, Abseil.
Poiché la creazione di plug-in scritti in C++ dipende da versioni specifiche di questi strumenti e librerie, ti consigliamo di utilizzare l'immagine Docker fornita dall'SDK Proxy-Wasm C++. Le istruzioni per C++ in questa pagina utilizzano il metodo Docker. Per creare plug-in C++ senza utilizzare Docker, consulta la documentazione dell'SDK Proxy-Wasm C++.
Installa Docker se non è già installato. Docker è incluso in Cloud Shell, l'ambiente shell interattivo Google Cloud .
Scarica una copia dell'SDK Proxy-Wasm C++. Il modo più semplice per farlo è clonare il repository Git:
git clone https://github.com/proxy-wasm/proxy-wasm-cpp-sdk.gitCrea l'immagine Docker dell'SDK Proxy-Wasm C++ dal Dockerfile fornito dall'SDK:
cd proxy-wasm-cpp-sdk docker build -t wasmsdk:v3 -f Dockerfile-sdk .Al termine della creazione delle librerie e delle dipendenze dell'SDK, l'immagine Docker risultante viene associata al tag specificato, che in questo esempio è
wasmsdk:v3.
Go
L'SDK Go Proxy-Wasm fornisce un SDK Go completo. Go offre buone prestazioni e un ricco supporto per le librerie di terze parti scritte in Go puro.
Ruggine
La funzionalità di personalizzazione di Service Extensions viene fornita tramite l'utilizzo di WebAssembly e Proxy-Wasm. WebAssembly supporta diversi linguaggi di programmazione. Google consiglia Rust perché offre un eccellente supporto di WebAssembly e Proxy-Wasm fornisce un SDK Rust completo. Rust offre anche buone prestazioni e una forte sicurezza dei tipi.
-
Al termine della procedura di installazione, segui le istruzioni stampate sulla console per completare la procedura di configurazione.
Aggiungi il supporto Wasm alla toolchain Rust:
rustup target add wasm32-wasip1
Crea il pacchetto del plug-in
C++
Crea una nuova directory separata da
proxy-wasm-cpp-sdk:mkdir myprojectNella directory, crea un Makefile con il seguente contenuto:
# Express any dependencies PROTOBUF= # full / lite / none WASM_DEPS= # absl_base re2 ... # Include the SDK Makefile PROXY_WASM_CPP_SDK=/sdk include ${PROXY_WASM_CPP_SDK}/MakefileAggiungi un file di origine C++ per il plug-in nella stessa directory. I nomi dei file di origine C++ devono corrispondere ai file Wasm a cui fa riferimento il Makefile, con il suffisso
.wasmsostituito da.cc. In questo esempio, il file di origine deve essere denominatomyproject.cc.Aggiungi il codice del plug-in al file di origine.
Il seguente codice sorgente di esempio è un plug-in che riscrive l'host della richiesta ed emette un'intestazione della risposta:
Il metodo
onRequestHeadersè un callback richiamato da Service Extensions.
Go
Crea una nuova directory per il plug-in:
mkdir go-pluginNella directory, crea un file
go.modutilizzando lo strumento Go:go mod init go-pluginNella stessa directory, crea un file di origine denominato
main.goe aggiungi il codice del plug-in al file.Il seguente codice sorgente di esempio è un plug-in che riscrive l'host della richiesta ed emette un'intestazione della risposta:
Il metodo
OnHttpRequestHeadersè un callback richiamato da Service Extensions.Per scaricare e bloccare le dipendenze della libreria, esegui
go mod tidy:go mod tidy
Ruggine
Crea una directory del pacchetto Rust utilizzando il comando
cargo newdal gestore dei pacchetti di Rust, Cargo:cargo new --lib my-wasm-pluginIl comando crea una directory contenente un file
cargo.tomlche puoi aggiornare per descrivere come creare il pacchetto Rust e una directorysrcin cui archiviare il codice del plug-in.Aggiorna il file
cargo.tomlper specificare i parametri richiesti per creare il pacchetto:[package] name = "my-wasm-plugin" version = "0.1.0" edition = "2021"Per registrare l'SDK Proxy-Wasm Rust e il supporto della registrazione come dipendenze, aggiungi la sezione
dependencies. Ad esempio:[dependencies] proxy-wasm = "0.2" log = "0.4"Per creare una libreria dinamica come richiesto per i plug-in, aggiungi la sezione
lib. Ad esempio:[lib] crate-type = ["cdylib"]Per ridurre le dimensioni del plug-in compilato, aggiungi la sezione
profile.release. Ad esempio:[profile.release] lto = true opt-level = 3 codegen-units = 1 panic = "abort" strip = "debuginfo"Aggiungi il codice del plug-in al file
lib.rsnella directorysrc.Il seguente codice sorgente di esempio è un plug-in che riscrive l'host della richiesta ed emette un'intestazione della risposta:
Il metodo
on_http_request_headersè un callback richiamato da Service Extensions.
Compila il plug-in
C++
Per compilare il plug-in, esegui questo comando dalla directory in cui si trovano i file di origine del plug-in Makefile e C++:
docker run -v $PWD:/work -w /work wasmsdk:v3 /build_wasm.sh myproject.wasm
Questo comando mappa la directory corrente alla directory work all'interno
dell'immagine Docker, quindi esegue lo script build_wasm.sh fornito dall'immagine
Docker per creare il codice del plug-in. Al termine dell'operazione di compilazione, viene creato un file myproject.wasm, che contiene il bytecode Wasm compilato, nella directory corrente.
La prima volta che il codice del plug-in viene compilato utilizzando l'immagine Docker, Emscripten genera le librerie standard. Per memorizzarli nella cache nell'immagine Docker in modo che non debbano essere rigenerati ogni volta, esegui il commit dell'immagine con le librerie standard dopo la prima compilazione riuscita:
docker commit `docker ps -l | grep wasmsdk:v3 | awk '{print $1}'` wasmsdk:v3
Per ulteriori informazioni sulla creazione di plug-in C++, consulta la documentazione dell'SDK Proxy-Wasm C++.
Go
Per compilare il codice del plug-in, esegui il comando go build:
env GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o main.wasm main.go
Una compilazione riuscita crea un file main.wasm nella directory corrente.
Ruggine
Per compilare il codice del plug-in, esegui il comando cargo build:
cargo build --release --target wasm32-wasip1
Quando la build viene completata correttamente, viene visualizzato un messaggio Finished release [optimized] target(s). Se hai familiarità con Envoy,
potresti voler caricare il plug-in in Envoy e verificarne il comportamento.
Carica il codice del plug-in compilato in Artifact Registry
Carica il codice del plug-in compilato in un repository Artifact Registry in modo che i servizi Google Cloud possano accedervi.
Se utilizzi Service Extensions con un bilanciatore del carico globale,
utilizza un repository in una posizione multiregionale us.
Se utilizzi un bilanciatore del carico regionale, utilizza un repository nella stessa regione
o in una località multiregionale sullo stesso continente.
Quando colleghi un plug-in a un bilanciatore del carico globale, Service Extensions copia il modulo Wasm dal repository Artifact Registry nel proprio spazio di archiviazione in località di tutto il mondo. Pertanto, la posizione del repository non influisce sulla latenza delle richieste inviate al bilanciatore del carico. Per i bilanciatori del carico regionali, il plug-in viene copiato nelle località della stessa regione in cui si trova il bilanciatore del carico.
I plug-in di Service Extensions possono essere caricati nei repository generici o Docker di Artifact Registry.
Per un approccio più diretto alla gestione dei file binari autonomi, ti consigliamo di utilizzare un repository generico per archiviare i file Wasm. Questa opzione è in anteprima.
Repository generico
Crea una directory locale
package/e copia il modulo del plug-in pubblicabile. L'artefatto del plug-in deve essere denominatoplugin.wasmIl seguente comando di esempio copia l'artefatto del plug-in creato da Rust:mkdir -p package && cp -f target/wasm32-wasip1/release/my_wasm_plugin.wasm package/plugin.wasmCrea un repository Artifact Registry con
--repository-formatimpostato sugeneric.Verifica di disporre delle autorizzazioni necessarie per il repository.
Per caricare il modulo Wasm come artefatto generico nel repository, utilizza il comando
gcloud artifacts generic upload.gcloud artifacts generic upload \ --project=PROJECT_ID \ --location=LOCATION \ --repository=REPOSITORY \ --source=package/plugin.wasm \ --package=PACKAGE \ --version=VERSIONSostituisci quanto segue:
PROJECT_ID: il tuo Google Cloud ID progettoLOCATION: la posizione regionale o multiregionale del repositoryREPOSITORY: il nome del repository in cui vuoi caricare il modulo WasmPACKAGE: il nome del pacchetto del fileVERSION: la versione del modulo Wasm
Al termine del caricamento, prendi nota del nome dell'artefatto generico come indicato con l'etichetta
name, ad esempioadd_header_plugin:v4nel seguente esempio. Specifica questo nome quando crei un plug-in o una versione del plug-in.Uploading file: plugin.wasm...done. '@type': type.googleapis.com/google.devtools.artifactregistry.v1.GenericArtifact createTime: '2025-06-16T11:02:25.080248Z' name: projects/my-project/locations/us/repositories/my-generic-repo/genericArtifacts/add_header_plugin:v4 updateTime: '2025-06-16T11:02:25.080248Z' version: v4Per verificare che l'artefatto sia stato caricato correttamente in Artifact Registry, esegui il comando
gcloud artifacts files liste verifica che l'elenco contenga un file denominatoPACKAGE:VERSION:plugin.wasm.gcloud artifacts files list \ --project=PROJECT_ID \ --location=LOCATION \ --repository=REPOSITORY
Repository Docker
Crea un repository Artifact Registry con
--repository-formatimpostato sudocker.Verifica di disporre delle autorizzazioni necessarie per il repository.
Crea una directory locale
package/e copia l'artefatto del plug-in pubblicabile. L'esempio seguente copia l'artefatto del plug-in creato da Rust:mkdir -p package && cp -f target/wasm32-wasip1/release/my_wasm_plugin.wasm package/plugin.wasmCrea un file
package/Dockerfilecon il seguente contenuto:FROM scratch COPY plugin.wasm plugin.wasmPacchettizza il codice del plug-in utilizzando Cloud Build o Docker.
Cloud Build
Crea un file di configurazione della build
package/cloudbuild.yamlcon il seguente contenuto:steps: - name: 'gcr.io/cloud-builders/docker' args: [ 'build', '--no-cache', '--platform', 'wasm', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG', '.' ] images: [ 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG' ]Il percorso in cui memorizzi il plug-in deve avere il seguente formato:
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
Sostituisci quanto segue:
LOCATION: la posizione regionale o multiregionale del repositoryPROJECT_ID: l'ID progetto della console Google CloudREPOSITORY: il nome del repository in cui intendi archiviare l'immagineIMAGE: il nome dell'immagine container nel repository, ad esempious-docker.pkg.dev/my-project/my-repo/my-wasm-pluginIMAGE_TAG: il tag immagine da assegnare al container, ad esempioproduction
Attiva l'operazione per creare il container del plug-in e caricarlo in Artifact Registry:
gcloud builds submit --config package/cloudbuild.yaml package/
Docker
Installa Docker se non è già installato. Docker è incluso in Cloud Shell, l'ambiente shell interattivo Google Cloud .
Configura Docker per l'autenticazione in Artifact Registry. Ad esempio:
gcloud auth login gcloud auth configure-docker LOCATION-docker.pkg.dev gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://LOCATION-docker.pkg.dev
Crea l'immagine container:
docker build --no-cache --platform wasm -t my-wasm-plugin package/
Per taggare l'immagine locale con il nome dell'immagine del repository, utilizza i tag immagine:
docker tag my-wasm-plugin LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
Sostituisci quanto segue:
LOCATION: la posizione regionale o multiregionale del repositoryPROJECT_ID: l'ID progetto della console Google CloudREPOSITORY: il nome del repository in cui intendi archiviare l'immagineIMAGE: il nome dell'immagine container nel repository, ad esempious-docker.pkg.dev/my-project/my-repo/my-wasm-plugin.IMAGE_TAG: il tag immagine da assegnare al container, ad esempioproduction
Carica l'immagine container taggata in Artifact Registry.
docker push LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
Per verificare che l'immagine sia stata caricata correttamente in Artifact Registry, esegui il comando
gcloud artifacts docker images list.gcloud artifacts docker images list LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE \ --include-tags
Prepara e carica il file di configurazione
I plug-in possono ricevere facoltativamente dati di configurazione, che possono influire sul comportamento del plug-in in fase di runtime. I dati di configurazione possono essere di tipo testo o binario e in qualsiasi formato accettato dal plug-in. Se le dimensioni dei dati di configurazione sono elevate, potresti dover caricare il file di configurazione in Artifact Registry.
Scrivi il codice del plug-in per leggere i dati di configurazione
C++
I dati di configurazione vengono passati al metodo onConfigure dell'oggetto contesto radice, che viene istanziato una volta all'avvio del plug-in e rimane attivo per la durata del runtime Wasm che ospita il plug-in. L'oggetto contesto radice è un'istanza della classe RootContext o di una sottoclasse di RootContext.
Il codice del plug-in può controllare la classe utilizzata per il contesto radice tramite il valore
RegisterContextFactory. Ad esempio, il seguente codice del plug-in
registra MyRootContext e MyHttpContext come classi da utilizzare per le istanze di contesto radice
e di stream. Quindi legge un valore secret dai dati di configurazione del plug-in, a cui le istanze del contesto di flusso possono accedere tramite l'oggetto contesto radice.
Go
I dati di configurazione vengono letti durante l'esecuzione di OnPluginStart, un ricevitore di metodi
che il runtime esegue sulla struct PluginContext una volta all'avvio
del plug-in. I dati di configurazione non cambiano durante il ciclo di vita del runtime Wasm che ospita il plug-in. PluginContext è utile per eseguire
la logica di inizializzazione e mantenere lo stato in molte richieste.
Il codice del plug-in può controllare il contesto utilizzato per PluginContext implementando il metodo NewPluginContext su VMContext, che crea un'istanza di PluginContext. PluginContext quindi crea istanze dei contesti HttpContext.
Ad esempio, il seguente codice del plug-in registra VMContext, che istanzia PluginContext, il contesto responsabile della lettura dei dati di configurazione e dell'istanza dei contesti HttpContext in base alle necessità.
PluginContext legge un valore segreto dai dati di configurazione del plug-in, lo memorizza
nel contesto PluginContext e lo passa a HttpContext
in NewHttpContext.
Ruggine
I dati di configurazione vengono letti da un tratto RootContext, che viene
istanziato una volta all'avvio del plug-in e rimane attivo per tutta la durata
del runtime Wasm che ospita il plug-in. Gli attributi RootContext sono utili per
eseguire operazioni o mantenere lo stato in molte richieste.
Il codice del plug-in può controllare quale classe viene utilizzata per il contesto radice tramite il metodo
set_root_context e il contesto radice crea istanze dei contesti di stream.
Ad esempio, il seguente codice del plug-in registra MyRootContext, che
crea un'istanza di MyHttpContext in base alle necessità. Il contesto radice legge un valore segreto
dai dati di configurazione del plug-in e lo passa ai contesti dello stream.
Carica il file di configurazione
Se le dimensioni dei dati da inviare al plug-in in on_configure
superano i 900 KiB, caricali in Artifact Registry seguendo il metodo
descritto in Caricare il codice del plug-in compilato in Artifact Registry.
In questo caso, salva il file di configurazione con il nome plugin.config
(e non plugin.wasm).
Il passaggio successivo consiste nel creare un plug-in.
Durante la creazione del plug-in, devi fornire l'URI del modulo o dell'immagine Wasm caricati.
Crea una nuova versione del codice del plug-in
Per creare una nuova versione del codice del plug-in, modifica il file del plug-in. Poi, come descritto nelle sezioni precedenti, compila il codice del plug-in, ricompattalo e caricalo su Artifact Registry.
Callback
Il codice che compili in Wasm può definire metodi o funzioni arbitrari, ma alcuni di questi hanno un significato speciale. Questi sono i metodi definiti nell'SDK Proxy-Wasm per il linguaggio che preferisci e mappati alle specifiche dell'Application Binary Interface (ABI) Proxy-Wasm. Service Extensions richiama questi callback in risposta alle richieste degli utenti o agli eventi del ciclo di vita del plug-in.
Questi callback sono elencati nella tabella seguente nell'ordine in cui vengono generalmente richiamati:
| Nome e descrizione del callback | Nome del metodo C++ | Nome del metodo Go | Nome del metodo Rust |
|---|---|---|---|
START_PLUGIN: Richiamato all'avvio di un plug-in. |
RootContext::onStart |
VMContext.OnVmStart |
RootContext::on_vm_start |
CONFIGURE_PLUGIN: Richiamato dopo l'avvio di un plug-in per fornire i dati di configurazione al plug-in. |
RootContext::onConfigure |
PluginContext.OnPluginStart |
RootContext::on_configure |
CREATE_CONTEXT: Richiamato quando viene creato un nuovo contesto di stream. Ogni flusso corrisponde a una richiesta HTTP del client. |
Context::onCreate |
PluginContext.NewHttpContext |
RootContext::create_http_context |
HTTP_REQUEST_HEADERS: Richiamato per elaborare le intestazioni delle richieste HTTP. |
Context::onRequestHeaders |
HttpContext.OnHttpRequestHeaders |
HttpContext::on_http_request_headers |
HTTP_REQUEST_BODY: Richiamato ripetutamente per elaborare i blocchi del corpo della richiesta HTTP. |
Context::onRequestBody |
HttpContext.OnHttpRequestBody |
HttpContext::on_http_request_body |
HTTP_RESPONSE_HEADERS: richiamato per elaborare le intestazioni
della risposta HTTP. |
Context::onResponseHeaders |
HttpContext.OnHttpResponseHeaders |
HttpContext::on_http_response_headers |
HTTP_RESPONSE_BODY: Richiamato ripetutamente per elaborare i blocchi del corpo della risposta HTTP. |
Context::onResponseBody |
HttpContext.OnHttpResponseBody |
HttpContext::on_http_response_body |
DONE: Richiamato al termine dell'elaborazione di un plug-in. |
Context::onDone |
HttpContext.OnHttpStreamDone |
Context::on_done |
DELETE: viene richiamato quando l'oggetto contesto dello stream
corrispondente a una richiesta HTTP del client viene eliminato. |
Context::onDelete |
(nessun callback) | (nessun callback) |
Passaggi successivi
- Crea un plug-in
- Consulta la panoramica di Service Extensions.