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为例。
- 创建容器镜像仓库并获取登录镜像仓库的账号。具体操作,请参见使用企业版实例推送和拉取镜像。
- 执行以下命令,登录镜像仓库。
oras login --username=<登录账号> acree-1-registry.cn-hangzhou.cr.aliyuncs.com
- 执行以下命令,将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
- 在容器镜像仓库查看推送的Wasm Filter。
- 登录容器镜像服务控制台。
- 在顶部菜单栏,选择所需地域。
- 在左侧导航栏,选择实例列表。
- 在实例列表页面单击目标企业版实例。
- 在企业版实例管理页面左侧导航栏选择。
- 在镜像仓库页面单击目标镜像仓库的名称。
- 在镜像仓库管理页面左侧导航栏单击镜像版本,在镜像版本页面可以看到上传的Wasm Filter。
启用使用WASM的功能
通过控制台启用使用WASM的功能
- 登录ASM控制台。
- 在左侧导航栏,选择。
- 在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
- 在网格详情页面左侧导航栏选择,然后在右侧页面单击功能设置。
- 在功能设置更新面板数据面扩展区域选中启用基于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流程
- 启用使用WASM的功能,启用后,自动部署一个DaemonSet类型的asmwasm-controller到ACK集群中。
- asmwasm-controller监听一个ConfigMap,该configmap存放了拉取的Wasm Filter的镜像仓库地址。
- 如果需要授权认证,该asmwasm-controller会根据定义的pullSecret值获得相应的Secret值。
- asmwasm-controller会调用ORAS API从注册库中动态拉取Wasm Filter。
- asmwasm-controller使用HostPath方式挂载Volume, 所以拉取的Wasm Filter会落盘到对应的节点上。

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

- patch片段

- 查看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
返回结果中,可以看到过滤器的头添加到响应头中。