Project: Gloo (Orchestration & Management / API Gateway)
File: wasm.md

title: Envoy Wasm filters with Gloo Edge weight: 70 description: Using Wasm filters in Envoy with Gloo Edge You can use WebAssembly (Wasm) Envoy filters with Gloo Edge Enterprise. (Wasm) is an open standard, binary instruction format to enable high-performing web apps, for use cases such as customizing the endpoints and thresholds of your workloads. {{% notice note %}} The is experimental, and not yet recommended for production usage. {{% /notice %}} , such as a Kubernetes cluster in a cloud provider. in your environment. Install a test app such as Pet Store from the . WebAssembly provides a safe, secure, and dynamic way of extending infrastructure with the programming language of your choice. Get a Wasm image. For more information on building your own Wasm image, see the . Prepare your Wasm image for use with Gloo Edge Enterprise. Review the following options. Store in an OCI-compliant image repository. This guide uses an example Wasm image from Solo's public Google Container Registry. Load the Wasm file directly into the filter. If your filter is not hosted in an image repository, you can refer to the filepath directly, such as `<directory>/<filter-name>.wasm`. Use an init container. In some circumstances, you might not be able to use an image repository due to enterprise networking restrictions. Instead, you can use an `initContainer` on the Gloo Edge `gatewayProxy` deployment to load a `.wasm` file into a shared `volume`. Now that Gloo Edge Enterprise is installed and you have your Wasm image, you are ready to configure Gloo Edge to use the Wasm filter. You add the filter to your gateway proxy configuration. For more information, check out the {{% protobuf name="wasm.options.gloo.solo.io.PluginSource" display="API docs"%}}. {{< tabs >}} {{% tab name="From an image registry" %}} Get the configuration for your `gateway-proxy` gateway. ```shell kubectl get -n gloo-system gateways.gateway.solo.io gateway-proxy -o yaml > gateway-proxy.yaml open gateway-proxy.yaml ``` Add the reference to your Wasm filter in the `httpGateway` section as follows. ```yaml httpGateway: options: wasm: filters: config: '@type': type.googleapis.com/google.protobuf.StringValue value: "world" image: gcr.io/solo-public/docs/assemblyscript-test:istio-1.8 name: add-header rootId: add_header ``` Update the `gateway-proxy` gateway. ```sh kubectl apply -n gloo-system -f gateway-proxy.yaml ``` {{% /tab %}} {{% tab name="From filepath" %}} Get the configuration for your `gateway-proxy` gateway. ```shell kubectl get -n gloo-system gateways.gateway.solo.io gateway-proxy -o yaml > gateway-proxy.yaml ``` Add the filepath reference to your `.wasm` file in the `httpGateway` section as follows. ```yaml httpGateway: options: wasm: filters: config: '@type': type.googleapis.com/google.protobuf.StringValue value: "world" filePath: filters-dir/my-filter.wasm name: add-header rootId: add_header ``` Update the `gateway-proxy` gateway. ```sh kubectl apply -n gloo-system -f gateway-proxy.yaml ``` {{% /tab %}} {{% tab name="From an init container" %}} Build a Docker image that has the Wasm filter image you previously created and use this image in an init container that runs alongside the gateway proxy. {{% notice note %}}Note: If you use a C++ Wasm filter, make sure to upgrade to `proxy-wasm-cpp-sdk-b2e6b0759d34d760e527dadca413a285614f9e99`.{{% /notice %}} Create a Dockerfile in the same location as your Wasm filter. The Dockerfile makes an image that has your Wasm filter, and copies the filter to the `/wasm-filters/` directory when the image runs. Later, you mount this directory in a shared volume. Note: In the previous section, your Wasm file is called `filter.wasm` and is located at

If built your filter with a different tool than `wasme` (such as `bazel`), your filter location might differ. ``` FROM alpine COPY filter.wasm filter.wasm CMD ["cp", "filter.wasm", "/wasm-filters/"] ``` Build and tag a Docker image from this Dockerfile. Replace the example values with your repository URL and preferred image name in the following example command. ```sh docker build . -t localhost:8888/myorg/my-wasm-getter:1.0.0 ``` Push the Docker image to an image repository that your enterprise network can access. ``` docker push localhost:8888/myorg/my-wasm-getter:1.0.0 ``` Edit your `gateway-proxy` deployment to add an init container and mount a shared volume. For a full example, see this . Get the configuration for the `gateway-proxy` deployment. ```sh kubectl get -n gloo-system deployment gateway-proxy -o yaml > gateway-proxy-wasm.yaml ``` In the `spec.template.spec.volumes` section, add a volume named `wasm-filters` that all the containers in the template can access. ```yaml volumes: configMap: defaultMode: 420 name: gateway-proxy-envoy-config name: envoy-config name: wasm-filters ``` In the `spec.template.spec.containers` section, add a mount path to the `wasm-filters` volume that you just configured. ```yaml containers: volumeMounts: mountPath: /etc/envoy name: envoy-config mountPath: /wasm-filters name: wasm-filters ``` In the `spec.template.spec` section, add the following init container stanza, which refers to the Wasm image that you just built and mounts the volume. ```yaml initContainers: name: wasm-image image: localhost:8888/myorg/my-wasm-getter:1.0.0 imagePullPolicy: IfNotPresent volumeMounts: mountPath: /wasm-filters name: wasm-filters ``` Apply the updated `gateway-proxy` deployment. ```sh kubectl apply -n gloo-system -f gateway-proxy-wasm.yaml ``` Now that the Wasm filter is in a shared mount filepath accessible by Envoy, get the configuration for your `gateway-proxy` gateway. ```shell kubectl get -n gloo-system gateways.gateway.solo.io gateway-proxy -o yaml > gateway-proxy.yaml ``` Add the filepath reference to your `.wasm` file in the `httpGateway` section as follows. ```yaml httpGateway: options: wasm: filters: config: '@type': type.googleapis.com/google.protobuf.StringValue value: "my test config" filePath: /wasm-filters/filter.wasm name: add-header rootId: add_header ``` Update the `gateway-proxy` gateway. ```sh kubectl apply -n gloo-system -f gateway-proxy.yaml ``` {{% /tab %}} {{< /tabs >}} Now that your `gateway-proxy` gateway is updated, the hard work has been done. All traffic on the HTTP gateway calls the Wasm filter. Enable port-forwarding for the `gateway-proxy` on the port for the Envoy Admin page, usually 19000. ``` kubectl port-forward -n gloo-system pods/$(kubectl get pod -l gloo=gateway-proxy -n gloo-system -o jsonpath='{.items[0].metadata.name}') 19000:19000 ``` Check the `config_dump` from the Envoy Admin page for the Wasm filter by opening this URL: . Example output in the `filter_chains` section: ```json ... { "name": "envoy.filters.http.wasm", "typed_config": { "@type": "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm", "config": { "name": "myfilter", "rootid": "addheader", "vm_config": { "vm_id": "gloo-vm-id", "runtime": "envoy.wasm.runtime.v8", "code": { "remote": { "http_uri": { "uri": "http://gloo/images/ 8b3b05719379af3996d51bf6d5baed1103059fb908baec547f2136ed48aebd77" , "cluster": "wasm-cache", "timeout": "5s" }, "sha256": "8b3b05719379af3996d51bf6d5baed1103059fb908baec547f2136ed48aebd77" } }, "nackoncodecachemiss": true }, "configuration": { "@type": "type.googleapis.com/google.protobuf.StringValue", "value": "my test config" } } } }, ... ``` To check that the Wasm filter is applied, send a curl request to one of your endpoints. ``` curl -v $(glooctl proxy url)/all-pets ``` Example output: Notice the header that your Wasm filter adds. {{< highlight yaml "hl_lines=13" >}} TCP_NODELAY set Connected to 34.30.251.229 (34.30.251.229) port 80 (#0) > GET /all-pets HTTP/1.1 > Host: 34.30.251.229 > User-Agent: curl/7.64.1 > Accept: / > < HTTP/1.1 200 OK < content-type: text/xml < date: Thu, 02 Mar 2023 16:46:24 GMT < content-length: 86 < x-envoy-upstream-service-time: 2 < hello: world! < server: envoy < [{"id":1,"name":"Dog","status":"available"},{"id":2,"name":"Cat","status":"pending"}] {{< /highlight >}}