Distributing WebAssembly Modules

Istio provides the ability to extend proxy functionality using WebAssembly (Wasm). One of the key advantages of Wasm extensibility is that extensions can be loaded dynamically at runtime. These extensions must first be distributed to the Envoy proxy. Istio makes this possible by allowing the proxy agent to dynamically download Wasm modules.

Setup the Test Application

Before you begin this task, please deploy the Bookinfo sample application.

Configure Wasm Modules

In this example, you will add a HTTP Basic auth extension to your mesh. You will configure Istio to pull the Basic auth module from a remote image registry and load it. It will be configured to run on calls to /productpage.

To configure a WebAssembly filter with a remote Wasm module, create a WasmPlugin resource:

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: extensions.istio.io/v1alpha1
  3. kind: WasmPlugin
  4. metadata:
  5. name: basic-auth
  6. namespace: istio-system
  7. spec:
  8. selector:
  9. matchLabels:
  10. istio: ingressgateway
  11. url: oci://ghcr.io/istio-ecosystem/wasm-extensions/basic_auth:1.12.0
  12. phase: AUTHN
  13. pluginConfig:
  14. basic_auth_rules:
  15. - prefix: "/productpage"
  16. request_methods:
  17. - "GET"
  18. - "POST"
  19. credentials:
  20. - "ok:test"
  21. - "YWRtaW4zOmFkbWluMw=="
  22. EOF

An HTTP filter will be injected into ingress gateway proxies as an authentication filter. The Istio agent will interpret the WasmPlugin configuration, download remote Wasm modules from the OCI image registry to a local file, and inject the HTTP filter into Envoy by referencing that file.

If a WasmPlugin is created in a specific namespace besides istio-system, the pods in that namespace will be configured. If the resource is created in the istio-system namespace, all namespaces will be affected.

Check the configured Wasm module

  1. Test /productpage without credentials
  1. $ curl -s -o /dev/null -w "%{http_code}" "http://$INGRESS_HOST:$INGRESS_PORT/productpage"
  2. 401
  1. Test /productpage with credentials
  1. $ curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Basic YWRtaW4zOmFkbWluMw==" "http://$INGRESS_HOST:$INGRESS_PORT/productpage"
  2. 200

For more example usage of the WasmPlugin API, please take a look at the API reference.

Clean up Wasm modules

  1. $ kubectl delete wasmplugins.extensions.istio.io -n istio-system basic-auth

Monitor Wasm Module Distribution

There are several stats which track the distribution status of remote Wasm modules.

The following stats are collected by Istio agent:

  • istio_agent_wasm_cache_lookup_count: number of Wasm remote fetch cache lookups.
  • istio_agent_wasm_cache_entries: number of Wasm config conversions and results, including success, no remote load, marshal failure, remote fetch failure, and miss remote fetch hint.
  • istio_agent_wasm_config_conversion_duration_bucket: Total time in milliseconds istio-agent spends on config conversion for Wasm modules.
  • istio_agent_wasm_remote_fetch_count: number of Wasm remote fetches and results, including success, download failure, and checksum mismatch.

If a Wasm filter configuration is rejected, either due to download failure or other reasons, istiod will also emit pilot_total_xds_rejects with the type label type.googleapis.com/envoy.config.core.v3.TypedExtensionConfig.

Develop a Wasm Extension

To learn more about Wasm module development, please refer to the guides provided in the istio-ecosystem/wasm-extensions repository, which is maintained by the Istio community and used to develop Istio’s Telemetry Wasm extension:

Limitations

There are known limitations with this module distribution mechanism, which will be addressed in future releases:

  • Only HTTP filters are supported.