O código personalizado criado para plug-ins do Service Extensions precisa ser empacotado e enviado ao Artifact Registry antes que outros serviços possam acessá-lo. Esta página descreve como criar código de plug-in, empacotar o código e fazer upload dele para um repositório do Artifact Registry.
Esse recurso está em pré-lançamento para a Media CDN.
Para mais informações sobre as Service Extensions, consulte Visão geral das Service Extensions.
Antes de começar, consulte as práticas recomendadas para escrever código de plug-in.
Para mais exemplos, consulte Exemplos de código para plug-ins.
Antes de começar
- Faça login na sua conta do Google Cloud . Se você começou a usar o Google Cloud, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
-
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.-
Instale a CLI do Google Cloud.
-
Ao usar um provedor de identidade (IdP) externo, primeiro faça login na gcloud CLI com sua identidade federada.
-
Para inicializar a gcloud CLI, execute o seguinte 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.-
Instale a CLI do Google Cloud.
-
Ao usar um provedor de identidade (IdP) externo, primeiro faça login na gcloud CLI com sua identidade federada.
-
Para inicializar a gcloud CLI, execute o seguinte comando:
gcloud init
Configurar o conjunto de ferramentas
C++
O SDK C++ do Proxy-Wasm permite que os desenvolvedores usem C++ para implementar plug-ins do WebAssembly (Wasm) para Service Extensions. O SDK usa a cadeia de ferramentas WebAssembly C++ Emscripten, além de outras bibliotecas, como protobuf e, opcionalmente, Abseil.
Como a criação de plug-ins escritos em C++ depende de versões específicas dessas ferramentas e bibliotecas, recomendamos usar a imagem Docker fornecida pelo SDK do Proxy-Wasm C++. As instruções para C++ nesta página usam o método Docker. Para criar plug-ins C++ sem usar o Docker, consulte a documentação do SDK Proxy-Wasm C++.
Instale o Docker se ele ainda não estiver instalado. O Docker está incluído no Cloud Shell, ambiente shell interativo Google Cloud .
Baixe uma cópia do SDK C++ do Proxy-Wasm. A maneira mais simples de fazer isso é clonar o repositório Git:
git clone https://github.com/proxy-wasm/proxy-wasm-cpp-sdk.gitCrie a imagem Docker do SDK C++ do Proxy-Wasm com o Dockerfile fornecido pelo SDK:
cd proxy-wasm-cpp-sdk docker build -t wasmsdk:v3 -f Dockerfile-sdk .Quando o comando terminar de criar as bibliotecas e dependências do SDK, a imagem Docker resultante será associada à tag especificada, que é
wasmsdk:v3neste exemplo.
Go
O SDK do Proxy-Wasm Go oferece um SDK do Go completo. O Go oferece bom desempenho e suporte completo para bibliotecas de terceiros escritas em Go puro.
Rust
A capacidade de personalização das Service Extensions é fornecida pelo uso do WebAssembly e do Proxy-Wasm. O WebAssembly é compatível com várias linguagens de programação. O Google recomenda o Rust porque ele oferece excelente suporte ao WebAssembly, e o Proxy-Wasm fornece um SDK Rust completo. O Rust também oferece bom desempenho e segurança de tipos.
Instale a cadeia de ferramentas do Rust.
Ao final do processo de instalação, siga as instruções impressas no console para concluir a configuração.
Adicione suporte ao Wasm ao conjunto de ferramentas do Rust:
rustup target add wasm32-wasip1
Criar o pacote de plug-in
C++
Crie um novo diretório, separado de
proxy-wasm-cpp-sdk:mkdir myprojectNo diretório, crie um Makefile com o seguinte conteúdo:
# 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}/MakefileAdicione um arquivo de origem C++ para o plug-in no mesmo diretório. Os nomes dos arquivos de origem C++ precisam corresponder aos arquivos Wasm que o Makefile segmenta, com o sufixo
.wasmsubstituído por.cc. Neste exemplo, o arquivo de origem precisa ser chamado demyproject.cc.Adicione o código do plug-in ao arquivo de origem.
O exemplo de código-fonte a seguir é um plug-in que reescreve o host da solicitação e emite um cabeçalho de resposta:
O método
onRequestHeadersé um callback invocado pelas Service Extensions.
Go
Crie um novo diretório para o plug-in:
mkdir go-pluginNo diretório, crie um arquivo
go.modusando a ferramenta Go:go mod init go-pluginNo mesmo diretório, crie um arquivo de origem chamado
main.goe adicione o código do plug-in a ele.O exemplo de código-fonte a seguir é um plug-in que reescreve o host da solicitação e emite um cabeçalho de resposta:
O método
OnHttpRequestHeadersé um callback invocado pelas Service Extensions.Para fazer o download e fixar as dependências da biblioteca, execute
go mod tidy:go mod tidy
Rust
Crie um diretório de pacote do Rust usando o comando
cargo newdo gerenciador de pacotes do Rust, o Cargo:cargo new --lib my-wasm-pluginO comando cria um diretório que contém um arquivo
cargo.tomlque pode ser atualizado para descrever como criar o pacote Rust e um diretóriosrcem que você armazena o código do plug-in.Atualize o arquivo
cargo.tomlpara especificar os parâmetros necessários para criar o pacote:[package] name = "my-wasm-plugin" version = "0.1.0" edition = "2021"Para registrar o SDK do Proxy-Wasm Rust e o suporte a registros como dependências, adicione a seção
dependencies. Exemplo:[dependencies] proxy-wasm = "0.2" log = "0.4"Para criar uma biblioteca dinâmica conforme necessário para plug-ins, adicione a seção
lib. Exemplo:[lib] crate-type = ["cdylib"]Para reduzir o tamanho do plug-in compilado, adicione a seção
profile.release. Exemplo:[profile.release] lto = true opt-level = 3 codegen-units = 1 panic = "abort" strip = "debuginfo"Adicione o código do plug-in ao arquivo
lib.rsno diretóriosrc.O exemplo de código-fonte a seguir é um plug-in que reescreve o host da solicitação e emite um cabeçalho de resposta:
O método
on_http_request_headersé um callback invocado pelas Service Extensions.
Compilar o plug-in
C++
Para compilar o plug-in, execute o seguinte comando no diretório em que o Makefile e os arquivos de origem do plug-in C++ estão localizados:
docker run -v $PWD:/work -w /work wasmsdk:v3 /build_wasm.sh myproject.wasm
Esse comando mapeia o diretório atual para o diretório work na imagem Docker e executa o script build_wasm.sh fornecido pela imagem Docker para criar o código do plug-in. Quando a operação de compilação for concluída com êxito, um arquivo myproject.wasm, que contém o bytecode Wasm compilado, será criado no diretório atual.
Na primeira vez que o código do plug-in é compilado usando a imagem Docker, o Emscripten gera as bibliotecas padrão. Para armazenar em cache na imagem do Docker e não precisar regenerar a cada vez, faça o commit da imagem com as bibliotecas padrão após a primeira compilação bem-sucedida:
docker commit `docker ps -l | grep wasmsdk:v3 | awk '{print $1}'` wasmsdk:v3
Para mais informações sobre como criar plug-ins C++, consulte a documentação do SDK C++ do Proxy-Wasm.
Go
Para compilar o código do plug-in, execute o comando go build:
env GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o main.wasm main.go
Uma compilação bem-sucedida cria um arquivo main.wasm no diretório atual.
Rust
Para compilar o código do plug-in, execute o comando cargo build:
cargo build --release --target wasm32-wasip1
Quando a build for concluída, uma mensagem Finished release [optimized] target(s)
vai aparecer. Se você conhece o Envoy,
carregue o plug-in nele e verifique o comportamento.
Fazer upload do código do plug-in compilado para o Artifact Registry
Faça upload do código do plug-in compilado para um repositório do Artifact Registry para que os serviços do Google Cloud possam acessá-lo.
Se você estiver usando Service Extensions com um balanceador de carga global,
use um repositório em um local us multirregional.
Se você estiver usando um balanceador de carga regional, use um repositório na mesma região
ou em um local multirregional no mesmo continente.
Quando você anexa um plug-in a um balanceador de carga global, o Service Extensions copia o módulo Wasm do repositório do Artifact Registry para o próprio armazenamento em locais do mundo todo. Portanto, o local do repositório não afeta a latência das solicitações enviadas ao balanceador de carga. Para balanceadores de carga regionais, o plug-in é copiado para locais na mesma região em que o balanceador de carga está localizado.
Os plug-ins do Service Extensions podem ser enviados para repositórios genéricos ou do Docker do Artifact Registry.
Para uma abordagem mais direta de gerenciamento de binários independentes, recomendamos usar um repositório genérico para armazenar seus arquivos Wasm. Essa opção está em pré-lançamento.
Repositório genérico
Crie um diretório
package/local e copie o módulo do plug-in publicável nele. O artefato do plug-in precisa ser chamadoplugin.wasm. O comando de exemplo a seguir copia o artefato do plug-in criado pelo Rust:mkdir -p package && cp -f target/wasm32-wasip1/release/my_wasm_plugin.wasm package/plugin.wasmCrie um repositório do Artifact Registry com
--repository-formatdefinido comogeneric.Verifique se você tem as permissões necessárias para o repositório.
Para fazer upload do módulo Wasm como um artefato genérico para o repositório, use o comando
gcloud artifacts generic upload.gcloud artifacts generic upload \ --project=PROJECT_ID \ --location=LOCATION \ --repository=REPOSITORY \ --source=package/plugin.wasm \ --package=PACKAGE \ --version=VERSIONSubstitua:
PROJECT_ID: o ID do projeto do Google CloudLOCATION: o local regional ou multirregional do repositórioREPOSITORY: o nome do repositório em que você quer fazer upload do módulo Wasm.PACKAGE: o nome do pacote do arquivo.VERSION: a versão do módulo Wasm
Quando o upload for concluído, observe o nome do artefato genérico, conforme mencionado com o rótulo
name, por exemplo,add_header_plugin:v4no exemplo a seguir. Especifique esse nome ao criar um plug-in ou uma versão dele.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: v4Para confirmar se o artefato foi enviado ao Artifact Registry, execute o comando
gcloud artifacts files liste verifique se a lista tem um arquivo chamadoPACKAGE:VERSION:plugin.wasm.gcloud artifacts files list \ --project=PROJECT_ID \ --location=LOCATION \ --repository=REPOSITORY
Repositório do Docker
Crie um repositório do Artifact Registry com
--repository-formatdefinido comodocker.Verifique se você tem as permissões necessárias para o repositório.
Crie um diretório
package/local e copie o artefato do plug-in publicável para ele. O exemplo a seguir copia o artefato do plug-in criado pelo Rust:mkdir -p package && cp -f target/wasm32-wasip1/release/my_wasm_plugin.wasm package/plugin.wasmCrie um arquivo
package/Dockerfilecom o seguinte conteúdo:FROM scratch COPY plugin.wasm plugin.wasmEmpacote o código do plug-in usando o Cloud Build ou o Docker.
Cloud Build
Crie um arquivo de configuração de build
package/cloudbuild.yamlcom o seguinte conteúdo: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' ]O caminho em que você armazena o plug-in precisa estar no seguinte formato:
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
Substitua:
LOCATION: o local regional ou multirregional do repositórioPROJECT_ID: o ID do projeto do console do Google CloudREPOSITORY: o nome do repositório onde você pretende armazenar a imagem.IMAGE: o nome da imagem do contêiner no repositório. Por exemplo,us-docker.pkg.dev/my-project/my-repo/my-wasm-pluginIMAGE_TAG: a tag da imagem a ser atribuída ao contêiner, por exemplo,production
Acione a operação para criar o contêiner do plug-in e fazer upload dele no Artifact Registry:
gcloud builds submit --config package/cloudbuild.yaml package/
Docker
Instale o Docker se ele ainda não estiver instalado. O Docker está incluído no Cloud Shell, ambiente shell interativo Google Cloud .
Configure o Docker para autenticar no Artifact Registry. Exemplo:
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
Crie a imagem do contêiner:
docker build --no-cache --platform wasm -t my-wasm-plugin package/
Para marcar a imagem local com o nome da imagem do repositório, use tags de imagem:
docker tag my-wasm-plugin LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
Substitua:
LOCATION: o local regional ou multirregional do repositórioPROJECT_ID: o ID do projeto do console do Google CloudREPOSITORY: o nome do repositório em que você pretende armazenar a imagem.IMAGE: o nome da imagem do contêiner no repositório, por exemplo,us-docker.pkg.dev/my-project/my-repo/my-wasm-plugin.IMAGE_TAG: a tag da imagem a ser atribuída ao contêiner, por exemplo,production
Faça upload da imagem de contêiner marcada para o Artifact Registry.
docker push LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
Para confirmar se a imagem foi enviada ao Artifact Registry, execute o comando
gcloud artifacts docker images list.gcloud artifacts docker images list LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE \ --include-tags
Preparar e fazer upload do arquivo de configuração
Os plug-ins podem receber dados de configuração, o que pode afetar o comportamento deles durante a execução. Os dados de configuração podem ser de texto ou binários e em qualquer formato aceito pelo plug-in. Se o tamanho dos dados de configuração for grande, talvez seja necessário fazer upload do arquivo de configuração para o Artifact Registry.
Escrever código de plug-in para ler dados de configuração
C++
Os dados de configuração são transmitidos ao método onConfigure do objeto de contexto raiz, que é instanciado uma vez na inicialização do plug-in e permanece ativo durante todo o ciclo de vida do ambiente de execução do Wasm que hospeda o plug-in. O objeto de contexto raiz é uma instância da classe RootContext ou de uma subclasse de RootContext.
O código do plug-in pode controlar qual classe é usada para o contexto raiz pelo valor
RegisterContextFactory. Por exemplo, o código de plug-in a seguir
registra MyRootContext e MyHttpContext como as classes a serem usadas para instâncias de contexto
raiz e de fluxo. Em seguida, ele lê um valor secreto dos dados de configuração do plug-in, que as instâncias de contexto de fluxo podem acessar pelo objeto de contexto raiz.
Go
Os dados de configuração são lidos durante a execução de OnPluginStart, um receptor de método
que o tempo de execução executa na struct PluginContext uma vez na inicialização
do plug-in. Os dados de configuração não mudam durante o ciclo de vida do
tempo de execução do Wasm que hospeda o plug-in. O PluginContext é útil para realizar a lógica de inicialização e manter o estado em várias solicitações.
O código do plug-in pode controlar qual contexto é usado para PluginContext implementando o método NewPluginContext em VMContext, que cria uma instância de PluginContext. Em seguida, PluginContext cria instâncias de contextos HttpContext.
Por exemplo, o código do plug-in a seguir registra VMContext, que
instancia PluginContext, o contexto responsável por ler
dados de configuração e instanciar contextos HttpContext conforme necessário.
PluginContext lê um valor secreto dos dados de configuração do plug-in, armazena
no contexto PluginContext e transmite para HttpContext
em NewHttpContext.
Rust
Os dados de configuração são lidos de uma característica RootContext, que é
instanciada uma vez na inicialização do plug-in e permanece ativa durante todo o ciclo de vida
do ambiente de execução do Wasm que hospeda o plug-in. As características RootContext são úteis para realizar operações ou manter o estado em várias solicitações.
O código do plug-in pode controlar qual classe é usada para o contexto raiz pelo método
set_root_context, e o contexto raiz cria instâncias de contextos de stream.
Por exemplo, o código de plug-in a seguir registra MyRootContext, que
instancia MyHttpContext conforme necessário. O contexto raiz lê um valor secreto dos dados de configuração do plug-in e o transmite para contextos de stream.
Fazer upload do arquivo de configuração
Se o tamanho dos dados a serem entregues ao seu plug-in em on_configure
exceder 900 KiB, faça upload para o Artifact Registry seguindo o método
descrito em Fazer upload do código do plug-in compilado para o Artifact Registry.
Nesse caso, salve o arquivo de configuração com o nome plugin.config (e não plugin.wasm).
A próxima etapa é criar um plug-in.
Ao criar o plug-in, você precisa fornecer o URI do módulo ou da imagem Wasm enviados.
Criar uma nova versão do código do plug-in
Para criar uma nova versão do código do plug-in, edite o arquivo dele. Em seguida, conforme descrito nas seções anteriores, compile o código do plug-in, reembale-o e faça upload dele para o Artifact Registry.
Chamadas de retorno
O código compilado em Wasm pode definir métodos ou funções arbitrárias, mas alguns deles têm um significado especial. Esses são os métodos definidos no SDK Proxy-Wasm para a linguagem de sua escolha e mapeados para as especificações da interface binária do aplicativo (ABI, na sigla em inglês) do Proxy-Wasm. As Service Extensions invocam esses callbacks em resposta a solicitações do usuário ou a eventos do ciclo de vida do plug-in.
Esses callbacks estão listados na tabela a seguir na ordem em que são normalmente invocados:
| Nome e descrição do callback | Nome do método C++ | Nome do método Go | Nome do método Rust |
|---|---|---|---|
START_PLUGIN: invocado quando um plug-in é iniciado. |
RootContext::onStart |
VMContext.OnVmStart |
RootContext::on_vm_start |
CONFIGURE_PLUGIN: invocado depois que um plug-in é iniciado para
fornecer dados de configuração a ele. |
RootContext::onConfigure |
PluginContext.OnPluginStart |
RootContext::on_configure |
CREATE_CONTEXT: invocado quando um novo contexto de stream é criado. Cada fluxo corresponde a uma solicitação HTTP do cliente. |
Context::onCreate |
PluginContext.NewHttpContext |
RootContext::create_http_context |
HTTP_REQUEST_HEADERS: invocado para processar cabeçalhos de solicitação HTTP. |
Context::onRequestHeaders |
HttpContext.OnHttpRequestHeaders |
HttpContext::on_http_request_headers |
HTTP_REQUEST_BODY: invocado repetidamente para processar partes do corpo da solicitação HTTP. |
Context::onRequestBody |
HttpContext.OnHttpRequestBody |
HttpContext::on_http_request_body |
HTTP_RESPONSE_HEADERS: invocado para processar cabeçalhos de resposta HTTP. |
Context::onResponseHeaders |
HttpContext.OnHttpResponseHeaders |
HttpContext::on_http_response_headers |
HTTP_RESPONSE_BODY: invocado repetidamente para processar partes do corpo da resposta HTTP. |
Context::onResponseBody |
HttpContext.OnHttpResponseBody |
HttpContext::on_http_response_body |
DONE: invocado quando o processamento de um plug-in é
concluído. |
Context::onDone |
HttpContext.OnHttpStreamDone |
Context::on_done |
DELETE: invocado quando o objeto de contexto de fluxo
correspondente a uma solicitação HTTP do cliente é excluído. |
Context::onDelete |
(sem retorno de chamada) | (sem retorno de chamada) |
A seguir
- Criar um plug-in
- Consulte a Visão geral das extensões de serviço.