Envoy Wasm filters with Gloo Gateway

You can use WebAssembly (Wasm) Envoy filters with Gloo Gateway Enterprise. WebAssembly (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.

The upstream Envoy Wasm filter is experimental, and not yet recommended for production usage.

Before you begin

  1. Create your environment, such as a Kubernetes cluster in a cloud provider.
  2. Install Gloo Gateway Enterprise in your environment.
  3. Install a test app such as Pet Store from the Hello World tutorial.

Prepare your Wasm filter

WebAssembly provides a safe, secure, and dynamic way of extending infrastructure with the programming language of your choice.

  1. Get a Wasm image. For more information on building your own Wasm image, see the WebAssembly Developer’s Guide.

  2. Prepare your Wasm image for use with Gloo Gateway 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 Gateway gatewayProxy deployment to load a .wasm file into a shared volume.

Configure Gloo Gateway to use a Wasm filter

Now that Gloo Gateway Enterprise is installed and you have your Wasm image, you are ready to configure Gloo Gateway to use the Wasm filter. You add the filter to your gateway proxy configuration. For more information, check out the API docs .

  1. Get the configuration for your gateway-proxy gateway.
    kubectl get -n gloo-system gateways.gateway.solo.io gateway-proxy -o yaml > gateway-proxy.yaml
    open gateway-proxy.yaml
    
  2. Add the reference to your Wasm filter in the httpGateway section as follows.
      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
    
  3. Update the gateway-proxy gateway.
    kubectl apply -n gloo-system -f gateway-proxy.yaml
    

Now that your gateway-proxy gateway is updated, the hard work has been done. All traffic on the HTTP gateway calls the Wasm filter.

Verify the Wasm filter

  1. 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
    
  2. Check the config_dump from the Envoy Admin page for the Wasm filter by opening this URL: localhost:19000/config_dump.

    • Example output in the filter_chains section:
    ...
    {
        "name": "envoy.filters.http.wasm",
        "typed_config": {
            "@type": "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm",
            "config": {
                "name": "myfilter",
                "root_id": "add_header",
                "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"
                        }
                    },
                    "nack_on_code_cache_miss": true
                },
                "configuration": {
                    "@type": "type.googleapis.com/google.protobuf.StringValue",
                    "value": "my test config"
                }
            }
        }
    },
    ...
    
  3. 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.

       * 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"}]