WASM
To add your new Wasm filter to the mesh, all you need is a WasmDeploymentPolicy
Kubernetes custom resource. Paired with a valid Workspace
and WorkspaceSettings
to allow fine-tuned control over your namespace boundaries, all you need to do is specify which Workloads should be configured and with which Wasm filters, then let Gloo Mesh handle the rest. Gloo Mesh will watch for WasmDeployments and manage the lifecycle of all your Wasm deployments accordingly.
In this guide we will enable a Wasm filter for use by an Envoy proxy. The filter will add a custom header to the response from the reviews service in the bookinfo application. To do this, we will walk through the following steps:
- Prepare the Envoy sidecar to fetch Wasm filters
- Deploy the Wasm filter and validate
Before you begin
-
Complete the example setup to install Gloo Mesh, Istio, and Bookinfo in your cluster.
-
Create the Gloo Mesh resources for this policy in the management and workload clusters.
The following files are examples only for testing purposes. Your actual setup might vary. You can use the files as a reference for creating your own tests.
- Download the following Gloo Mesh resources:
- Apply the files to your management cluster.
kubectl apply -f kubernetes-cluster_gloo-mesh_cluster-1.yaml --context ${MGMT_CONTEXT} kubectl apply -f kubernetes-cluster_gloo-mesh_cluster-2.yaml --context ${MGMT_CONTEXT} kubectl apply -f workspace_gloo-mesh_anything.yaml --context ${MGMT_CONTEXT}
- Download the following Gloo Mesh resources:
- Workspace settings that enable federation so that traffic can be routed across clusters
- Apply the files to your workload cluster.
kubectl apply -f workspace-settings_bookinfo_anything.yaml --context ${REMOTE_CONTEXT1}
Prepare the Envoy sidecar to fetch Wasm filters
Our Envoy instances will fetch their wasm filters from an envoy cluster that must be defined in the static bootstrap config. We must therefore perform a one-time operation to add the gloo-mesh-agent
as a cluster in the Envoy bootstrap.
To do so, let's create a ConfigMap containing the custom additions to the Envoy bootstrap:
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
Next we'll patch the ratings-v1
deployment to include this custom boostrap in the sidecar:
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
Now our deployment is wasm-ready.
The next step is to deploy the WasmDeploymentPolicy and start modifying traffic!
Deploy the Wasm filter and validate
We've got everything in place to use the Wasm filter, but first let's see what things look like without the filter added.
Test without Wasm Filter
As a sanity check, let's run a curl
without any wasm filter deployed. First we'll create a temporary container to run curl from in the same namespace as the review service.
kubectl run -it -n bookinfo --context $REMOTE_CONTEXT1 curl \
--image=curlimages/curl:7.73.0 --rm -- sh
From the new terminal run the following:
curl http://ratings:9080/ratings/1 -v
You should see the following 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: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}}
Go ahead and exit the pod and it will delete itself. Next we'll try the same after we deploy the Wasm filter.
Deploy the Filter
Now let's deploy a Wasm filter with a WasmDeployment:
cat <<EOF | kubectl apply --context ${REMOTE_CONTEXT1} -f-
apiVersion: extensions.policy.gloo.solo.io/v2
kind: WasmDeploymentPolicy
metadata:
name: wasm-deployment-policy
namespace: bookinfo
spec:
applyToWorkloads:
- selector:
cluster: cluster-1
labels:
app: ratings
namespace: bookinfo
config:
filters:
- filterContext: SIDECAR_INBOUND
wasmImageSource:
wasmImageTag: webassemblyhub.io/ilackarms/assemblyscript-test:istio-1.8
EOF
You can verify the filter has been deployed successfully by checking on the new WasmDeployment:
kubectl get --context ${REMOTE_CONTEXT1} wasmdeploymentpolicy -n bookinfo wasm-deployment-policy -o yaml
Let's try our curl again:
kubectl run -it -n bookinfo --context $REMOTE_CONTEXT1 curl \
--image=curlimages/curl:7.73.0 --rm -- sh
From the new terminal run the following:
curl http://ratings:9080/ratings/1 -v
Expected 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}}
We should see the < hello: world!
header in our response if the filter was deployed successfully.
Summary and Next Steps
In this guide you used Gloo Mesh Enterprise and the Wasm extension to push a Wasm filter to a service managed by Gloo Mesh.
This is a simple example of a Wasm filter to illustrate the concept. The flexibility of Wasm filters coupled with Envoy provides a platform for incredible innovation. Check out our docs on Web Assembly Hub for more information.