WebAssembly (Wasm) is an effective and portable binary instruction format. You can use Wasm to extend the data plane of an Alibaba Cloud Service Mesh (ASM) instance with new features. However, building, deploying, and running Wasm filters in an ASM instance are complex. This topic shows you how to use OCI Registry as Storage (ORAS) to simplify Wasm-based ASM instance extension.

Prerequisites

  • An ASM instance is created, and a Container Service for Kubernetes (ACK) cluster is added to the ASM instance. For more information, see Create an ASM instance and Add a cluster to an ASM instance.
    Note The version of the ASM instance must be v1.8.3.17-g1399628c-aliyun or later.
  • The kubectl client is used to connect to the ASM instance. For more information, see Use kubectl to connect to an ASM instance.
  • An application is deployed in the ACK cluster that is added to the ASM instance. For more information, see Deploy an application in an ASM instance.
  • A virtual service and an ingress gateway are created. For more information, see Define Istio resources.
  • A binary Wasm filter file is created and compiled. In this example, the header of a Wasm filter is added to the response header.

Background information

ASM supports Wasm. You can deploy Wasm filters in the Envoy that is used to manage clusters on the data plane. This helps you extend the data plane with new features. ORAS provides registry storage based on the Open Container Initiative (OCI) Artifacts project. You can use ORAS to simplify the storage process in OCI registries. When you use Wasm to extend the data plane of an ASM instance with new features, you can use ORAS to simplify the extension process.

Push a Wasm filter

Use ORAS CLI to push a Wasm filter to an image repository. In this example, Container Registry Enterprise Edition is used.

  1. Create an image repository in Container Registry Enterprise Edition and obtain the username that is used to log on to the image repository. For more information, see Use a Container Registry Enterprise Edition instance to push and pull images.
  2. Run the following command to log on to the image repository:
    oras login --username=<Username> acree-1-registry.cn-hangzhou.cr.aliyuncs.com
  3. Run the following command to push a Wasm filter to the image repository:
    oras push acree-1-registry.cn-hangzhou.cr.aliyuncs.com/******/asm-test:v0.1 --manifest-config runtime-config.json:application/vnd.module.wasm.config.v1+json  example-filter.wasm:application/vnd.module.wasm.content.layer.v1+wasm
  4. View the pushed Wasm filter in the Container Registry console.
    1. Log on to the Container Registry console.
    2. In the top navigation bar, select a region.
    3. In the left-side navigation pane, click Instances.
    4. On the Instances page, click the required Container Registry Enterprise Edition instance.
    5. On the management page of the Container Registry Enterprise Edition instance, choose Repositories > Repositories in the left-side navigation pane.
    6. On the Repositories page, click the name of the image repository to which you want to log on.
    7. In the left-side navigation pane of the repository information page, click Tags. On the page that appears, you can view the pushed Wasm filter.

Enable Wasm-based ASM instance extension

Wasm-based ASM instance extension in the ASM console

  1. Log on to the ASM console.
  2. In the left-side navigation pane, choose Service Mesh > Mesh Management.
  3. On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column of the ASM instance.
  4. On the management page of the ASM instance, click Settings in the upper-right corner.
  5. In the Settings Update panel, select Enable Wasm-based ASM Instance Extension in the Data Plane Extension section and click OK.
    Note To disable Wasm-based ASM instance extension, clear Enable Wasm-based ASM Instance Extension.

Use Alibaba Cloud CLI to enable Wasm-based ASM instance extension

You can use Alibaba Cloud CLI to enable Wasm-based ASM instance extension. Run the following command to enable Wasm-based ASM instance extension:

aliyun servicemesh UpdateMeshFeature --ServiceMeshId=xxxx --WebAssemblyFilterEnabled=true
Run the following command to disable Wasm-based ASM instance extension:
aliyun servicemesh UpdateMeshFeature --ServiceMeshId=xxxx --WebAssemblyFilterEnabled=false

Use the Wasm filter in ASM

ASM provides ASMFilterDeployment resources and related controllers. A controller listens to the status of its ASMFilterDeployment resource and performs the following operations:
  • Creates an Envoy filter and pushes the Envoy filter to the control plane.
  • Pulls the Wasm filter image from the image repository and mounts the image to the pod that is controlled by the specified workload.

Process

  1. Enable Wasm-based ASM instance extension. After that, the ASM instance automatically deploys an asmwasm-controller DaemonSet to the ACK cluster that is added to the ASM instance.
  2. The asmwasm-controller DaemonSet listens to a ConfigMap. The ConfigMap stores the address of the image repository where the Wasm filter image is to be pulled.
  3. If authorization and authentication are required, the asmwasm-controller DaemonSet obtains a secret based on the pullSecret parameter.
  4. The asmwasm-controller DaemonSet calls the ORAS operation to dynamically pull the Wasm filter from the OCI registry.
  5. The asmwasm-controller DaemonSet uses a hostPath volume to mount the Wasm filter. Therefore, the pulled Wasm filter is stored in the corresponding nodes of the ACK cluster.
Flowchart

Procedure

  1. Run the following command to enable Wasm-based ASM instance extension:
    aliyun servicemesh UpdateMeshFeature  --ServiceMeshId=xxxxxx --WebAssemblyFilterEnabled=true
  2. Create a secret for the ACK cluster to access the image repository.
    For more information, see Secret.
    1. Create a myconfig.json file that contains the following code:
      {
          "auths":{
              "**********.cn-hangzhou.cr.aliyuncs.com":{
                  "username":"*****username*****",
                  "password":"*****password*****"
              }
          }
      }
      • **********.cn-hangzhou.cr.aliyuncs.com: the address of the image repository.
      • username: the username of the image repository.
      • password: the password of the image repository.
    2. Run the following command to create a secret:
      Note The secret must be named asmwasm-cache and belong to the istio-system namespace.
      kubectl create secret generic asmwasm-cache -n istio-system --from-file=.dockerconfigjson=myconfig.json --type=kubernetes.io/dockerconfigjson
  3. Deploy an ASMFilterDeployment resource.
    1. Create a filter.yaml file that contains the following code:
      apiVersion: istio.alibabacloud.com/v1beta1
      kind: ASMFilterDeployment
      metadata:
        name: details-v1-wasmfiltersample
      spec:
        workload:
          kind: Deployment
          labels:
            app: details
            version: v1
        filter:
          patchContext: 'SIDECAR_INBOUND'
          parameters: '{"name":"hello","value":"hello details"}'
          image: 'acree-1-registry.cn-hangzhou.cr.aliyuncs.com/asm/asm-test:v0.1'
          rootID: 'my_root_id'
          id: 'details-v1-wasmfiltersample.default'
      • Parameters in workload:
        1. kind: the type of the destination workload.
        2. labels: the filter conditions.
      • Parameters in filter:
        1. patchContext: the context that takes effect.
        2. parameters: the parameters that are required to run the Wasm filter.
        3. image: the address of the image repository to which the Wasm filter is pushed.
        4. rootID: the root ID of the Wasm filter.
        5. id: the unique ID of the Wasm filter.
    2. Run the following command to deploy the ASMFilterDeployment resource:
      kubectl apply -f filter.yaml
      After the ASMFilterDeployment resource is deployed, ASM automatically generates an Envoy filter. In the Envoy filter, the match parameter defines an envoy.router filter, and the patch parameter defines an INSERT_BEFORE operation.
      • match parametermatch
      • patch parameterpatch
  4. Check the definition of the workload to which the Wasm filter is mounted.
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
    ....
    spec:
       ...
       template:
          metadata:
              annotations:
                  sidecar.istio.io/userVolume: '[{"name":"wasmfilters-dir","hostPath":{"path":"/var/local/lib/wasm-filters"}}]'
                  sidecar.istio.io/userVolumeMount: '[{"mountPath":"/var/local/lib/wasm-filters","name":"wasmfilters-dir"}]'

    The preceding definition indicates that the Wasm filter is mounted to the istio-proxy container of the destination application by using a hostPath volume.

Check whether the Wasm filter takes effect

Run the following command to log on to the istio-proxy container of the productpage pod and send a request to access the details service:

kubectl exec -ti  deploy/productpage-v1 -c istio-proxy -- curl -v http://details:9080/details/123

Expected output:

*   Trying 172.21.9.191...
* TCP_NODELAY set
* Connected to details (172.21.9.191) port 9080 (#0)
> GET /details/123 HTTP/1.1
> Host: details:9080
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
xxxxxxx
< resp-header-demo: added by our filter
xxxxx
* Connection #0 to host details left intact
xxxxx

The response indicates that the header of the Wasm filter is added to the response header.