El código personalizado que creas 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 la 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 eres nuevo en 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.
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.-
Instala Google Cloud CLI.
-
Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.
-
Para inicializar gcloud CLI, ejecuta el siguiente 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.-
Instala Google Cloud CLI.
-
Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.
-
Para inicializar gcloud CLI, ejecuta el siguiente comando:
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++ en esta página usan el método de Docker. Para compilar complementos de C++ sin usar Docker, consulta la documentación del SDK de C++ de Proxy-Wasm.
Instala Docker si aún no lo hiciste. Docker está incluido en Cloud Shell, el Google Cloud entorno de shell interactivo.
Descarga una copia del SDK de C++ de Proxy-Wasm. La forma más sencilla 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 C++ de Proxy-Wasm a partir del Dockerfile proporcionado por el SDK:
cd proxy-wasm-cpp-sdk docker build -t wasmsdk:v3 -f Dockerfile-sdk .Cuando el comando termina de compilar las bibliotecas y las dependencias del SDK, la imagen de Docker resultante se asocia con la etiqueta especificada, que es
wasmsdk:v3en este ejemplo.
Go
El SDK de Go de Proxy-Wasm proporciona un SDK de Go con todas las funciones. Go proporciona un buen rendimiento y una gran compatibilidad con las 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 gran seguridad de tipos.
Instala la cadena de herramientas de Rust.
Al final del proceso de instalación, sigue las instrucciones impresas 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 archivo 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 de 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 dirige el archivo 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 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 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 bytecode 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 almacenarlas en caché en la imagen de Docker de modo que no sea necesario volver a generarlas 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
Para obtener más información sobre cómo compilar complementos en C++, consulta la documentación del SDK de Proxy-Wasm en C++.
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, tal vez 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 us multirregional.
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 de 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 a ubicaciones de la misma región en la que se encuentra el balanceador de cargas.
Los complementos de Service Extensions se pueden subir a los repositorios genéricos o de Docker de Artifact Registry.
Para un enfoque más directo de la administración de archivos binarios independientes, te recomendamos que uses un repositorio genérico para almacenar tus archivos Wasm. Esta opción se encuentra 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: Es el Google Cloud ID del proyecto.LOCATION: la ubicación regional o multirregional del repositorioREPOSITORY: Es el nombre del repositorio en el que deseas subir el módulo de Wasm.PACKAGE: Es el nombre del paquete del archivo.VERSION: Es la versión del módulo de Wasm.
Cuando se complete la carga, anota el nombre del artefacto genérico como se menciona con la etiqueta
name, por ejemplo,add_header_plugin:v4en el siguiente ejemplo. Especifica este nombre cuando crees un complemento o una versión del 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 del contenedor en el repositorio, por ejemplo,us-docker.pkg.dev/my-project/my-repo/my-wasm-pluginIMAGE_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 está incluido en Cloud Shell, el Google Cloud entorno de shell interactivo.
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: 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.
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
Los complementos pueden recibir datos de configuración de forma opcional, lo que puede afectar su comportamiento en el tiempo 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 en el inicio del complemento y permanece activo durante la vida útil 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 secreto de los datos de configuración del complemento, a los que las instancias de contexto de transmisión pueden acceder 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 tiempo de ejecución ejecuta en la estructura PluginContext una vez en el 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 instancias de 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 secreto de los datos de configuración del complemento, lo almacena dentro del contexto 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 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 siguiendo el método que se describe en Cómo subir el código compilado del complemento 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 que se subieron.
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 las solicitudes del usuario o a los 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 en 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) |