El código personalizado que crees para los complementos de Service Extensions debe empaquetarse y subirse a Artifact Registry antes de que otros servicios puedan acceder a él. En esta página, se describe cómo crear código de complementos, empaquetarlo y subirlo a un repositorio de Artifact Registry.
Esta función está en vista previa para Media CDN.
Para obtener información sobre las extensiones de servicio, consulta Descripción general de las extensiones de servicio.
Antes de comenzar, revisa las prácticas recomendadas para escribir código de complementos.
Para obtener más ejemplos, consulta Muestras de código para complementos.
Antes de comenzar
- Accede a tu cuenta de Google Cloud . Si es la primera vez que usas Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
-
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, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
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, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
Configura la cadena de herramientas
C++
El SDK de C++ de Proxy-Wasm permite que los desarrolladores usen C++ para implementar complementos de WebAssembly (Wasm) para Service Extensions. El SDK usa la cadena de herramientas de WebAssembly de C++ Emscripten, así como otras bibliotecas, como protobuf y, de forma opcional, Abseil.
Dado que la compilación de complementos escritos en C++ depende de versiones específicas de estas herramientas y bibliotecas, te recomendamos que uses la imagen de Docker proporcionada por el SDK de C++ de Proxy-Wasm. Las instrucciones para C++ de esta página usan el método de Docker. Para compilar complementos de C++ sin usar Docker, consulta la documentación del SDK de Proxy-Wasm para C++.
Instala Docker si aún no lo hiciste. Docker se incluye en Cloud Shell, el entorno de shell interactivo de Google Cloud .
Descarga una copia del SDK de C++ de Proxy-Wasm. La forma más simple de hacerlo es clonar el repositorio de Git:
git clone https://github.com/proxy-wasm/proxy-wasm-cpp-sdk.gitCompila la imagen de Docker del SDK de Proxy-Wasm para C++ desde el Dockerfile que proporciona el SDK:
cd proxy-wasm-cpp-sdk docker build -t wasmsdk:v3 -f Dockerfile-sdk .Cuando el comando completa la compilación de las bibliotecas y dependencias del SDK, la imagen de Docker resultante se asocia con la etiqueta especificada, que es
wasmsdk:v3en este ejemplo.
Go
El SDK de Proxy-Wasm para Go proporciona un SDK de Go con todas las funciones. Go proporciona un buen rendimiento y una gran compatibilidad con bibliotecas de terceros escritas en Go puro.
Rust
La capacidad de personalización de Service Extensions se proporciona a través del uso de WebAssembly y Proxy-Wasm. WebAssembly admite varios lenguajes de programación. Google recomienda Rust porque proporciona una excelente compatibilidad con WebAssembly y Proxy-Wasm ofrece un SDK de Rust con todas las funciones. Rust también proporciona un buen rendimiento y una sólida seguridad de tipos.
Instala la cadena de herramientas de Rust.
Al final del proceso de instalación, sigue las instrucciones que se muestran en la consola para finalizar el proceso de configuración.
Agrega compatibilidad con Wasm a la cadena de herramientas de Rust:
rustup target add wasm32-wasip1
Crea el paquete del complemento
C++
Crea un directorio nuevo, separado de
proxy-wasm-cpp-sdk:mkdir myprojectEn el directorio, crea un Makefile con el siguiente contenido:
# 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}/MakefileAgrega un archivo fuente C++ para el complemento en el mismo directorio. Los nombres de los archivos fuente de C++ deben coincidir con los archivos Wasm a los que se orienta el Makefile, con el sufijo
.wasmreemplazado por.cc. En este ejemplo, el archivo fuente debe llamarsemyproject.cc.Agrega el código del complemento al archivo fuente.
El siguiente código fuente de ejemplo es un complemento que reescribe el host de la solicitud y emite un encabezado de respuesta:
El método
onRequestHeaderses una devolución de llamada que invocan las extensiones de servicio.
Go
Crea un directorio nuevo para el complemento:
mkdir go-pluginEn el directorio, crea un archivo
go.modcon la herramienta de Go:go mod init go-pluginEn el mismo directorio, crea un archivo fuente llamado
main.goy agrega el código de tu complemento.El siguiente código fuente de ejemplo es un complemento que reescribe el host de la solicitud y emite un encabezado de respuesta:
El método
OnHttpRequestHeaderses una devolución de llamada que invocan las extensiones de servicio.Para descargar y fijar las dependencias de la biblioteca, ejecuta
go mod tidy:go mod tidy
Rust
Crea un directorio de paquetes de Rust con el comando
cargo newdel administrador de paquetes de Rust, Cargo:cargo new --lib my-wasm-pluginEl comando crea un directorio que contiene un archivo
cargo.tomlque puedes actualizar para describir cómo compilar el paquete de Rust y un directoriosrcen el que almacenas el código del complemento.Actualiza el archivo
cargo.tomlpara especificar los parámetros necesarios para compilar el paquete:[package] name = "my-wasm-plugin" version = "0.1.0" edition = "2021"Para registrar el SDK de Proxy-Wasm de Rust y la compatibilidad con el registro como dependencias, agrega la sección
dependencies. Por ejemplo:[dependencies] proxy-wasm = "0.2" log = "0.4"Para compilar una biblioteca dinámica como se requiere para los complementos, agrega la sección
lib. Por ejemplo:[lib] crate-type = ["cdylib"]Para reducir el tamaño del complemento compilado, agrega la sección
profile.release. Por ejemplo:[profile.release] lto = true opt-level = 3 codegen-units = 1 panic = "abort" strip = "debuginfo"Agrega el código del complemento al archivo
lib.rsen el directoriosrc.El siguiente código fuente de ejemplo es un complemento que reescribe el host de la solicitud y emite un encabezado de respuesta:
El método
on_http_request_headerses una devolución de llamada que invocan las extensiones de servicio.
Compila el complemento
C++
Para compilar el complemento, ejecuta el siguiente comando desde el directorio en el que se encuentran el archivo Makefile y los archivos fuente del complemento en C++:
docker run -v $PWD:/work -w /work wasmsdk:v3 /build_wasm.sh myproject.wasm
Este comando asigna el directorio actual al directorio work dentro de la imagen de Docker y, luego, ejecuta la secuencia de comandos build_wasm.sh proporcionada por la imagen de Docker para compilar el código del complemento. Cuando la operación de compilación se completa
correctamente, se crea un archivo myproject.wasm, que contiene el código de bytes de Wasm
compilado, en el directorio actual.
La primera vez que se compila el código del complemento con la imagen de Docker, Emscripten genera las bibliotecas estándar. Para almacenarlos en caché en la imagen de Docker, de modo que no sea necesario volver a generarlos cada vez, confirma la imagen con las bibliotecas estándar después de la primera compilación exitosa:
docker commit `docker ps -l | grep wasmsdk:v3 | awk '{print $1}'` wasmsdk:v3
Si deseas obtener más información para compilar complementos de C++, consulta la documentación del SDK de C++ de Proxy-Wasm.
Go
Para compilar el código del complemento, ejecuta el comando go build:
env GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o main.wasm main.go
Si la compilación se realiza correctamente, se crea un archivo main.wasm en el directorio actual.
Rust
Para compilar el código del complemento, ejecuta el comando cargo build:
cargo build --release --target wasm32-wasip1
Cuando la compilación se completa correctamente, aparece un mensaje Finished release [optimized] target(s). Si conoces Envoy,
es posible que quieras cargar el complemento en Envoy y verificar su comportamiento.
Sube el código del complemento compilado a Artifact Registry
Sube el código del complemento compilado a un repositorio de Artifact Registry para que los servicios de Google Cloud puedan acceder a él.
Si usas Service Extensions con un balanceador de cargas global,
usa un repositorio en una ubicación multirregional de us.
Si usas un balanceador de cargas regional, usa un repositorio en la misma región o en una ubicación multirregional del mismo continente.
Cuando conectas un complemento a un balanceador de cargas global, Service Extensions copia el módulo Wasm del repositorio de Artifact Registry a su propio almacenamiento en ubicaciones de todo el mundo. Por lo tanto, la ubicación del repositorio no afecta la latencia de las solicitudes enviadas al balanceador de cargas. En el caso de los balanceadores de cargas regionales, el complemento se copia en ubicaciones de la misma región en la que se encuentra el balanceador de cargas.
Los complementos de Service Extensions se pueden subir a repositorios genéricos o de Docker de Artifact Registry.
Para un enfoque más directo de la administración de objetos binarios independientes, te recomendamos que uses un repositorio genérico para almacenar tus archivos Wasm. Esta opción está en vista previa.
Repositorio genérico
Crea un directorio
package/local y copia en él el módulo del complemento publicable. El artefacto del complemento debe llamarseplugin.wasm. El siguiente comando de ejemplo copia el artefacto del complemento compilado por Rust:mkdir -p package && cp -f target/wasm32-wasip1/release/my_wasm_plugin.wasm package/plugin.wasmCrea un repositorio de Artifact Registry con
--repository-formatestablecido engeneric.Verifica que tengas los permisos necesarios para el repositorio.
Para subir tu módulo de Wasm como un artefacto genérico a tu repositorio, usa el comando
gcloud artifacts generic upload.gcloud artifacts generic upload \ --project=PROJECT_ID \ --location=LOCATION \ --repository=REPOSITORY \ --source=package/plugin.wasm \ --package=PACKAGE \ --version=VERSIONReemplaza lo siguiente:
PROJECT_ID: El Google Cloud ID del proyectoLOCATION: la ubicación regional o multirregional del repositorioREPOSITORY: El nombre del repositorio en el que deseas subir el módulo de WasmPACKAGE: Es el nombre del paquete del archivo.VERSION: La versión del módulo de Wasm
Cuando se complete la carga, ten en cuenta el nombre del artefacto genérico, como se menciona con la etiqueta
name, por ejemplo,add_header_plugin:v4en la siguiente muestra. Especifica este nombre cuando crees un complemento o una versión de complemento.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 que el artefacto se subió correctamente a Artifact Registry, ejecuta el comando
gcloud artifacts files listy verifica que la lista tenga un archivo llamadoPACKAGE:VERSION:plugin.wasm.gcloud artifacts files list \ --project=PROJECT_ID \ --location=LOCATION \ --repository=REPOSITORY
Repositorio de Docker
Crea un repositorio de Artifact Registry con
--repository-formatestablecido endocker.Verifica que tengas los permisos necesarios para el repositorio.
Crea un directorio
package/local y copia en él el artefacto del complemento publicable. En el siguiente ejemplo, se copia el artefacto del complemento compilado por Rust:mkdir -p package && cp -f target/wasm32-wasip1/release/my_wasm_plugin.wasm package/plugin.wasmCrea un archivo
package/Dockerfilecon el siguiente contenido:FROM scratch COPY plugin.wasm plugin.wasmEmpaqueta el código del complemento con Cloud Build o Docker.
Cloud Build
Crea un archivo de configuración de compilación
package/cloudbuild.yamlcon el siguiente contenido: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' ]La ruta de acceso en la que almacenas el complemento debe tener el siguiente formato:
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
Reemplaza lo siguiente:
LOCATION: la ubicación regional o multirregional del repositorioPROJECT_ID: el ID de tu proyecto en la consola de Google CloudREPOSITORY: Es el nombre del repositorio en el que planeas almacenar la imagen.IMAGE: Es el nombre de la imagen de contenedor en el repositorio, por ejemplo,us-docker.pkg.dev/my-project/my-repo/my-wasm-plugin.IMAGE_TAG: Es la etiqueta de imagen que se asignará al contenedor, por ejemplo,production.
Activa la operación para compilar el contenedor del complemento y subirlo a Artifact Registry:
gcloud builds submit --config package/cloudbuild.yaml package/
Docker
Instala Docker si aún no lo hiciste. Docker se incluye en Cloud Shell, el entorno de shell interactivo de Google Cloud .
Configura Docker para que se autentique en Artifact Registry. Por ejemplo:
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
Compila la imagen del contenedor:
docker build --no-cache --platform wasm -t my-wasm-plugin package/
Para etiquetar la imagen local con el nombre de la imagen del repositorio, usa etiquetas de imagen:
docker tag my-wasm-plugin LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
Reemplaza lo siguiente:
LOCATION: Es la ubicación regional o multirregional del repositorio.PROJECT_ID: el ID de tu proyecto en la consola de Google CloudREPOSITORY: El nombre del repositorio en el que deseas almacenar la imagenIMAGE: Es el nombre de la imagen de contenedor en el repositorio, por ejemplo,us-docker.pkg.dev/my-project/my-repo/my-wasm-plugin.IMAGE_TAG: Es la etiqueta de imagen que se asignará al contenedor, por ejemplo,production.
Sube la imagen de contenedor etiquetada a Artifact Registry.
docker push LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
Para confirmar que la imagen se subió correctamente a Artifact Registry, ejecuta el comando
gcloud artifacts docker images list.gcloud artifacts docker images list LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE \ --include-tags
Prepara y sube el archivo de configuración
De manera opcional, los complementos pueden recibir datos de configuración, lo que puede afectar su comportamiento en el entorno de ejecución. Los datos de configuración pueden ser de texto o binarios, y en cualquier formato que acepte el complemento. Si el tamaño de los datos de configuración es grande, es posible que debas subir el archivo de configuración a Artifact Registry.
Escribe código de complemento para leer datos de configuración
C++
Los datos de configuración se pasan al método onConfigure del objeto de contexto raíz, que se instancia una vez al inicio del complemento y permanece activo durante el ciclo de vida del tiempo de ejecución de Wasm que aloja el complemento. El objeto de contexto raíz es una instancia de la clase RootContext o de una subclase de RootContext.
El código del complemento puede controlar qué clase se usa para el contexto raíz a través del valor RegisterContextFactory. Por ejemplo, el siguiente código de complemento
registra MyRootContext y MyHttpContext como las clases que se usarán para las instancias de contexto raíz
y de transmisión. Luego, lee un valor de secreto de los datos de configuración del complemento, al que pueden acceder las instancias de contexto de transmisión a través del objeto de contexto raíz.
Go
Los datos de configuración se leen mientras se ejecuta OnPluginStart, un receptor de métodos que el entorno de ejecución ejecuta en la estructura PluginContext una vez al inicio del complemento. Los datos de configuración no cambian durante la vida útil del tiempo de ejecución de Wasm que aloja el complemento. PluginContext es útil para realizar
la lógica de inicialización y mantener el estado en muchas solicitudes.
El código del complemento puede controlar qué contexto se usa para PluginContext implementando el método NewPluginContext en VMContext, que instancia PluginContext. Luego, PluginContext crea una instancia de los contextos de HttpContext.
Por ejemplo, el siguiente código de complemento registra VMContext, que crea una instancia de PluginContext, el contexto responsable de leer los datos de configuración y crear instancias de los contextos de HttpContext según sea necesario.
PluginContext lee un valor de secreto de los datos de configuración del complemento, lo almacena
dentro del contexto de PluginContext y lo pasa a HttpContext
en NewHttpContext.
Rust
Los datos de configuración se leen desde un rasgo RootContext, que se instancia una vez en el inicio del complemento y permanece activo durante el ciclo de vida del tiempo de ejecución de Wasm que aloja el complemento. Los rasgos RootContext son útiles para realizar operaciones o mantener el estado en muchas solicitudes.
El código del complemento puede controlar qué clase se usa para el contexto raíz a través del
método set_root_context, y el contexto raíz crea instancias de los contextos de transmisión.
Por ejemplo, el siguiente código de complemento registra MyRootContext, que crea una instancia de MyHttpContext según sea necesario. El contexto raíz lee un valor
secreto de los datos de configuración del complemento y lo pasa a los contextos de transmisión.
Sube el archivo de configuración
Si el tamaño de los datos que se entregarán a tu complemento en on_configure
supera los 900 KiB, súbelos a Artifact Registry con el método
descrito en Sube el código del complemento compilado a Artifact Registry.
En este caso, guarda el archivo de configuración con el nombre plugin.config (y no plugin.wasm).
El siguiente paso es crear un complemento.
Cuando crees el complemento, deberás proporcionar el URI del módulo o la imagen de Wasm subidos.
Crea una versión nueva del código del complemento
Para crear una nueva versión del código del complemento, edita el archivo del complemento. Luego, como se describe en las secciones anteriores, compila el código del complemento, vuelve a empaquetarlo y súbelo a Artifact Registry.
Devoluciones de llamada
El código que compilas en Wasm puede definir métodos o funciones arbitrarios, pero algunos de ellos tienen un significado especial. Estos son los métodos que se definen en el SDK de Proxy-Wasm para el lenguaje que elijas y se asignan a las especificaciones de la interfaz binaria de la aplicación (ABI) de Proxy-Wasm. Las extensiones de servicio invocan estas devoluciones de llamada en respuesta a solicitudes del usuario o a eventos del ciclo de vida del complemento.
Estas devoluciones de llamada se enumeran en la siguiente tabla en el orden en que suelen invocarse:
| Nombre y descripción de la devolución de llamada | Nombre del método en C++ | Nombre del método Go | Nombre del método de Rust |
|---|---|---|---|
START_PLUGIN: Se invoca cuando se inicia un complemento. |
RootContext::onStart |
VMContext.OnVmStart |
RootContext::on_vm_start |
CONFIGURE_PLUGIN: Se invoca después de que se inicia un complemento para proporcionar datos de configuración al complemento. |
RootContext::onConfigure |
PluginContext.OnPluginStart |
RootContext::on_configure |
CREATE_CONTEXT: Se invoca cuando se crea un nuevo contexto de transmisión. Cada transmisión corresponde a una solicitud HTTP del cliente. |
Context::onCreate |
PluginContext.NewHttpContext |
RootContext::create_http_context |
HTTP_REQUEST_HEADERS: Se invoca para procesar los encabezados de la solicitud HTTP. |
Context::onRequestHeaders |
HttpContext.OnHttpRequestHeaders |
HttpContext::on_http_request_headers |
HTTP_REQUEST_BODY: Se invoca de forma repetida para procesar fragmentos del cuerpo de la solicitud HTTP. |
Context::onRequestBody |
HttpContext.OnHttpRequestBody |
HttpContext::on_http_request_body |
HTTP_RESPONSE_HEADERS: Se invoca para procesar los encabezados de respuesta HTTP. |
Context::onResponseHeaders |
HttpContext.OnHttpResponseHeaders |
HttpContext::on_http_response_headers |
HTTP_RESPONSE_BODY: Se invoca de forma repetida para procesar fragmentos del cuerpo de la respuesta HTTP. |
Context::onResponseBody |
HttpContext.OnHttpResponseBody |
HttpContext::on_http_response_body |
DONE: Se invoca cuando se completa el procesamiento de un complemento. |
Context::onDone |
HttpContext.OnHttpStreamDone |
Context::on_done |
DELETE: Se invoca cuando se borra el objeto de contexto de transmisión correspondiente a una solicitud HTTP del cliente. |
Context::onDelete |
(sin devolución de llamada) | (sin devolución de llamada) |