WebAssembly(WASM)是一种有效的可移植二进制指令格式,可以用于扩展ASM数据平面的功能。然而在服务网格内构建、部署和运行Wasm Filter较为复杂。本文介绍如何使用ORAS简化基于WASM的服务网格扩展功能。

前提条件

  • 已创建ASM实例,并添加集群到ASM实例。具体操作,请参见创建ASM实例添加集群到ASM实例
    说明 ASM实例必须为v1.8.3.17-g1399628c-aliyun或者以上版本。
  • 使用kubectl连接到ASM实例。具体操作,请参见通过kubectl连接ASM实例
  • 已部署应用到ASM实例。具体操作,请参见部署应用到ASM实例
  • 已创建Istio虚拟服务和入口网关。具体操作,请参见定义Istio资源
  • 已创建并编译一个Wasm Filter二进制文件。本文以将过滤器的头添加到响应头的Wasm Filter为例。

背景信息

ASM提供了对WASM技术的支持,可以把扩展的Wasm Filter通过ASM部署到数据面集群中相应的Envoy代理中,从而扩展数据平面的功能。ORAS是基于OCI Artifacts规范的OCI注册表存储,可以显著简化OCI注册库中内容的存储过程。基于WASM扩展ASM数据平面功能时,可以使用ORAS对功能扩展过程进行简化。

上传Wasm Filter

使用ORAS CLI工具上传Wasm Filter到镜像仓库,以阿里云容器镜像服务企业版ACR EE为例。

  1. 创建容器镜像仓库并获取登录镜像仓库的账号。具体操作,请参见使用企业版实例推送拉取镜像
  2. 执行以下命令,登录镜像仓库。
    oras login --username=<登录账号> acree-1-registry.cn-hangzhou.cr.aliyuncs.com
  3. 执行以下命令,将Wasm Filter推送到镜像仓库。
    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. 在容器镜像仓库查看推送的Wasm Filter。
    1. 登录容器镜像服务控制台
    2. 在顶部菜单栏,选择所需地域。
    3. 在左侧导航栏,选择实例列表
    4. 实例列表页面单击目标企业版实例。
    5. 在企业版实例管理页面左侧导航栏选择仓库管理 > 镜像仓库
    6. 镜像仓库页面单击目标镜像仓库的名称。
    7. 在镜像仓库管理页面左侧导航栏单击镜像版本,在镜像版本页面可以看到上传的Wasm Filter。

启用使用WASM的功能

通过控制台启用使用WASM的功能

  1. 登录ASM控制台
  2. 在左侧导航栏,选择服务网格 > 网格管理
  3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
  4. 在网格管理详情页面左上角单击功能设置
  5. 功能设置更新面板数据面扩展区域选中启用基于WebAssembly的服务网格扩展,然后单击确定
    说明功能设置更新面板数据面扩展区域去掉选中启用基于WebAssembly的服务网格扩展,可以关闭使用WASM的功能。

通过命令行启用使用WASM的功能

通过Aliyun CLI可以启用服务网格中的使用WASM的功能。执行以下命令,启用使用WASM的功能。

aliyun servicemesh UpdateMeshFeature --ServiceMeshId=xxxx --WebAssemblyFilterEnabled=true
您也可以执行以下命令,关闭使用WASM的功能。
aliyun servicemesh UpdateMeshFeature --ServiceMeshId=xxxx --WebAssemblyFilterEnabled=false

在ASM中使用WASM

服务网格ASM产品提供了一个ASMFilterDeployment资源以及相关的Controller组件。这个Controller组件会监听ASMFilterDeployment资源对象的情况,并进行以下操作:
  • 创建用于控制面的Istio EnvoyFilter Custom Resource,并推送到对应的ASM控制面Istio中。
  • 从镜像仓库中拉取对应的Wasm Filter镜像, 并挂载到对应的Workload Pod中。

使用WASM流程

  1. 启用使用WASM的功能,启用后,自动部署一个DaemonSet类型的asmwasm-controller到ACK集群中。
  2. asmwasm-controller监听一个ConfigMap,该configmap存放了拉取的Wasm Filter的镜像仓库地址。
  3. 如果需要授权认证,该asmwasm-controller会根据定义的pullSecret值获得相应的Secret值。
  4. asmwasm-controller会调用ORAS API从注册库中动态拉取Wasm Filter。
  5. asmwasm-controller使用HostPath方式挂载Volume, 所以拉取的Wasm Filter会落盘到对应的节点上。
使用流程

操作步骤

  1. 执行以下命令,启用使用WASM的功能。
    aliyun servicemesh UpdateMeshFeature  --ServiceMeshId=xxxxxx --WebAssemblyFilterEnabled=true
  2. 在ACK集群中创建用来访问镜像仓库的Secret。
    关于Secret的详细信息,请参见Secret
    1. 使用以下内容,创建名为myconfig.json的文件。
      {
          "auths":{
              "**********.cn-hangzhou.cr.aliyuncs.com":{
                  "username":"*****username*****",
                  "password":"*****password*****"
              }
          }
      }
      • **********.cn-hangzhou.cr.aliyuncs.com:镜像仓库地址。
      • username:镜像仓库用户名。
      • password:镜像仓库密码。
    2. 执行以下命令,创建Sercet。
      说明 Secret名字必须为asmwasm-cache,命名空间为istio-system。
      kubectl create secret generic asmwasm-cache -n istio-system --from-file=.dockerconfigjson=myconfig.json --type=kubernetes.io/dockerconfigjson
  3. 部署ASMFilterDeployment资源。
    1. 使用以下内容,创建一个名为filter.yaml的文件。
      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'
      • workload下的参数解释:
        1. kind:目标工作负载的类型。
        2. labels:筛选的条件。
      • filter下的参数解释:
        1. patchContext:生效的上下文阶段。
        2. parameters:运行Wasm Filter所需的配置参数。
        3. image:Wasm Fitler对应的镜像仓库地址。
        4. rootID:Wasm Filter扩展插件对应的RootID。
        5. id:该Wasm Filter的唯一ID。
    2. 执行以下命令,部署ASMFilterDeployment资源。
      kubectl apply -f filter.yaml
      ASMFilterDeployment部署后,会自动生成EnvoyFilter。其中match片段中定义了envoy.router,patch片段中定义了INSERT_BEFORE。
      • match片段match
      • patch片段patch
  4. 查看Workload。
    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"}]'

    可以看到Wasm Filter文件以HostPath方式挂载到Proxy容器中。

验证Wasm Filter是否生效

执行以下命令,登录到productpage Pod的istio-proxy容器中并请求details服务。

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

预期输出:

*   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

返回结果中,可以看到过滤器的头添加到响应头中。