Apply Wasm filters
Add a Wasm filter to the Envoy sidecar proxy, for use cases such as customizing the endpoints and thresholds for your workloads.
WebAssembly (Wasm) is an open standard, binary instruction format to enable high-performing web apps. Gloo Mesh integrates with Wasm filters by using Gloo Mesh policies. Add a Wasm filter to the Envoy sidecar proxy, for use cases such as customizing the endpoints and thresholds for your workloads.
The WasmDeploymentPolicy
Gloo CR is currently unsupported in Istio version 1.18.0 and later.
If you import or export resources across workspaces, your policies might not apply. For more information, see Import and export policies.
In this guide, you set up a sample Wasm filter that is hosted in Solo’s public Google Container Registry. The filter adds a custom header to the response from the ratings service in the Bookinfo application. To set up the filter, you complete two main steps.
- Enable the Envoy sidecar to fetch Wasm filters.
- Apply a Wasm deployment policy to the ratings workload.
Before you begin
This guide assumes that you use the same names for components like clusters, workspaces, and namespaces as in the getting started. If you have different names, make sure to update the sample configuration files in this guide.
Complete the multicluster getting started guide to set up the following testing environment.
- Three clusters along with environment variables for the clusters and their Kubernetes contexts.
- The Gloo
meshctl
CLI, along with other CLI tools such askubectl
andistioctl
. - The Gloo management server in the management cluster, and the Gloo agents in the workload clusters.
- Istio installed in the workload clusters.
- A simple Gloo workspace setup.
- Install Bookinfo and other sample apps.
Optional: Create your own Wasm filter to extend Envoy gateway functionality. To easily refer to your filter in the Wasm deployment policy, store your Wasm filter in an OCI-compliant registry, such as Docker Hub or Amazon ECR.
Enable the Envoy sidecar to fetch Wasm filters
To apply Wasm filters, you must enable the Envoy sidecar proxies on your workloads to fetch Wasm filters from an Envoy cluster. The Envoy cluster is defined in the static bootstrap configuration. You can perform a one-time operation to add the gloo-mesh-agent
as an Envoy cluster in the Envoy bootstrap.
Create a config map that defines the
gloo-mesh-agent
as the Envoy cluster to bootstrap your workloads’ Envoy sidecar proxies with.cat <<EOF | kubectl apply --context ${REMOTE_CONTEXT1} -n bookinfo -f - apiVersion: v1 kind: ConfigMap metadata: name: gloo-mesh-custom-envoy-bootstrap namespace: bookinfo data: custom_bootstrap.json: | { "static_resources": { "clusters": [{ "name": "gloo_mesh_agent_cluster", "type" : "STRICT_DNS", "connect_timeout": "1s", "lb_policy": "ROUND_ROBIN", "load_assignment": { "cluster_name": "gloo_mesh_agent_cluster", "endpoints": [{ "lb_endpoints": [{ "endpoint": { "address":{ "socket_address": { "address": "gloo-mesh-agent.gloo-mesh.svc.cluster.local", "port_value": 9977 } } } }] }] }, "circuit_breakers": { "thresholds": [ { "priority": "DEFAULT", "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 100000 }, { "priority": "HIGH", "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 100000 } ] }, "upstream_connection_options": { "tcp_keepalive": { "keepalive_time": 300 } }, "max_requests_per_connection": 1, "http2_protocol_options": { } }] } } EOF
Patch the
ratings-v1
deployment to include the custom Envoy sidecar bootstrap configuration.kubectl patch deployment -n bookinfo ratings-v1 --context ${REMOTE_CONTEXT1} \ --patch='{"spec":{"template": {"metadata": {"annotations": {"sidecar.istio.io/bootstrapOverride": "gloo-mesh-custom-envoy-bootstrap"}}}}}' \ --type=merge
Great job! Your ratings-v1
workload’s Envoy sidecar is ready to accept Wasm filters. You can repeat these steps for any workloads that you want to apply a Wasm filter to.
Apply the Wasm filter
Your Wasm filter configuration is stored in an OCI-compliant registry, and your workload’s Envoy sidecar is enabled for Wasm filters. Now you can start to modify traffic by creating a Wasm deployment policy. The policy includes a reference to the filter image that you want to apply. You apply Wasm deployment policies at the workload level.
In this example, you use a filter that adds a custom header to the response from the ratings service in the Bookinfo application. You can also make your own filters.
Test your Bookinfo setup before applying the Wasm filter.
Create a temporary
curl
pod in thebookinfo
namespace, so that you can test the app setup.kubectl run -it -n bookinfo --context $REMOTE_CONTEXT1 curl \ --image=curlimages/curl:7.73.0 --rm -- sh
Send a request to the ratings app.
curl http://ratings:9080/ratings/1 -v
In the output, note the response headers.
* Trying 10.96.31.140:9080... * Connected to ratings (10.96.31.140) port 9080 (#0) > GET /ratings/1 HTTP/1.1 > Host: ratings:9080 > User-Agent: curl/7.73.0-DEV > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < content-type: application/json < date: Wed, 11 May 2022 17:00:40 GMT < x-envoy-upstream-service-time: 104 < server: envoy < transfer-encoding: chunked < * Connection #0 to host ratings left intact {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
Exit the temporary pod. The pod is automatically deleted.
exit
Create the Wasm deployment policy. Note: Change
cluster-1
as needed to your cluster’s actual name (value of$CLUSTER_NAME
).cat <<EOF | kubectl apply --context ${REMOTE_CONTEXT1} -f- apiVersion: extensions.policy.gloo.solo.io/v2 kind: WasmDeploymentPolicy metadata: annotations: cluster.solo.io/cluster: "" name: wasm-deployment-policy namespace: bookinfo spec: applyToWorkloads: - selector: cluster: cluster-1 labels: app: ratings namespace: bookinfo config: filters: - filterContext: SIDECAR_INBOUND wasmImageSource: wasmImageTag: gcr.io/solo-public/docs/assemblyscript-test:istio-1.8 EOF
Review the following table to understand this configuration. For more information, see the API docs.
Setting Description applyToWorkloads
Configure which workloads to apply the policy to by using labels. Workloads can be apps that have injected sidecars, such as deployments or stateful sets, or standalone proxies, such as gateways. If omitted, the policy applies to all workloads in the workspace. Note: Change cluster-1
as needed to your cluster’s actual name (value of$CLUSTER_NAME
).filters
Specify the details of the Wasm filter to apply. If you have multiple Wasm filters, you can also add a weight
field at the same level asfilters
to specify the order in which the filters are applied. In this example, no weight field is set because only one Wasm filter is applied.filterContext
Specify what context the filter is attached to: any workload context ( ANY
), a gateway (GATEWAY
), inbound traffic to a sidecar proxy (SIDECAR_INBOUND
), or outbound traffic from a sidecar (SIDECAR_OUTBOUND
). By default, the value isANY
to permit any context. In this example, the filter is applied only to the context ofSIDECAR_INBOUND
traffic.wasmImageSource
Specify where to pull the Wasm image to use for the filter. In this example, the image is hosted in Solo’s public Google Container Registry. insertBeforeFilter
Specify before which filter in the Envoy HTTP filter chain you want to insert your filter. Note that not all filters might be applied to a particular workload. In the example, this field is not set, so the filter defaults to being inserted before the envoy.router
filter.Verify that the Wasm deployment policy is created. In the output, check the status field.
kubectl get wasmdeploymentpolicy -n bookinfo -o yaml --context $REMOTE_CONTEXT1
If you do not see a status:
- Check for other policies that might block the ratings app.
- Check the management server logs for errors related to
WasmDeploymentPolicy
,wasm
, or the imagegcr.io/solo-public/docs/assemblyscript-test:istio-1.8
.
Verify that the Wasm deployment policy works.
Create a temporary
curl
pod again.kubectl run -it -n bookinfo --context $REMOTE_CONTEXT1 curl \ --image=curlimages/curl:7.73.0 --rm -- sh
Re-send a request to the ratings app.
curl http://ratings:9080/ratings/1 -v
In the output, note that the new
hello, world!
header is added to the response.* Trying 10.96.31.140:9080... * Connected to ratings (10.96.31.140) port 9080 (#0) > GET /ratings/1 HTTP/1.1 > Host: ratings:9080 > User-Agent: curl/7.73.0-DEV > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < content-type: application/json < date: Wed, 11 May 2022 17:09:10 GMT < x-envoy-upstream-service-time: 18 < hello: world! < server: envoy < transfer-encoding: chunked < * Connection #0 to host ratings left intact {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
Exit the temporary pod. The pod is automatically deleted.
exit
Optional: Clean up the resources that you created.
kubectl --context $REMOTE_CONTEXT1 -n bookinfo delete WasmDeploymentPolicy wasm-deployment-policy kubectl --context $REMOTE_CONTEXT1 -n bookinfo delete ConfigMap gloo-mesh-custom-envoy-bootstrap kubectl annotate deploy -n bookinfo ratings-v1 --context $REMOTE_CONTEXT1 sidecar.istio.io/bootstrapOverride-
Next steps
In this guide, you used Gloo Mesh Enterprise and the Wasm extension to enforce a Wasm filter on traffic to a service managed by Gloo Mesh.
Now that you know how to integrate Gloo Mesh Gateway with Wasm filters, you can create more complex filters.