什么是 Wasm 插件
WebAssembly(WASM)是一种由多种语言编写的,可移植的字节码格式,它能以接近本机的速度执行。作为一种可移植、体积小、加载快并且兼容 Web 的全新格式。
需要注意的是,WASM 是一个编译目标,不是一种编程语言,WebAssembly 是经过编译器编译之后的目标格式,具有高效、安全、开发 、标准等特点。
你可以使用 Wasm 插件在数据路径上添加自定义代码,轻松地扩展服务网格的功能。可以用你选择的语言编写插件。目前,有 AssemblyScript(TypeScript-ish)、C++、Rust、Zig 和 Go 语言的 Proxy-Wasm SDK
何时使用 Wasm 插件
为了提供更加方便、更加灵活的扩展方式,istio从1.12版本开始引入wasm扩展envoy
当你需要添加 Envoy 或 Istio 不支持的自定义功能时,你应该使用 Wasm 插件。使用 Wasm 插件来添加自定义验证、认证、日志或管理配额
技术实现
istio架构及wasm可插入的位置:
envoy架构:
envoy过滤机制
Envoy 提供了进程外架构、支持L3/L4 filter、HTTP L7 filter,过滤器包括侦听器过滤器(Listener Filters)、网络过滤器(Network Filters)、HTTP过滤器(HTTP Filters)三种类型
1、侦听器过滤器
侦听器过滤器在初始连接阶段访问原始数据并操作 L4 连接的元数据。例如,TLS 检查器过滤器(TLS Inspector Filter)标识连接是否经过 TLS 加密,并解析与该连接关联的 TLS 元数据(SNI或ALPN协商的协议类型;
HTTP Inspector Filter 检测应用协议是否是 HTTP,如果是的话,再进一步检测 HTTP 协议类型 (HTTP/1.x or HTTP/2) ,这两种过滤器解析到的元数据都可以和 FilterChainMatch 结合使用。
2、网络过滤器
网络过滤器访问和操作 L4 连接上的原始数据,即TCP数据包。例如,TCP代理过滤器(TCP Proxy Filter)将客户端连接数据路由到上游主机,它还可以生成连接统计数据。
此外,MySQL proxy、Redis proxy、Dubbo proxy、Thrift proxy等都属于网络过滤器。
3、HTTP过滤器
HTTP 过滤器在 L7 上运行,由网络过滤器(即 HTTP 连接管理器,HTTP Connection Manager)创建。这些过滤器用于访问、操作 HTTP 请求和响应,例如,gRPC-JSON 转码器过滤器(gRPC-JSON Transcoder Filter)可以为 gRPC 后端提供一个 REST API,并将请求和响应转换为相应的格式。
此外,还包括 JWT、Router、RBAC 等多种过滤器。
编写wasm插件
编写wasm的工具有:Solo.io 团队的wasme、tinygo等,当前比较应用比较多是tinygo
tinygo支持的包:https://tinygo.org/docs/reference/lang-support/stdlib/
考虑到DAS基于k8s及golang,故开发sdk选择proxy-wasm-go-sdk,地址:https://github.com/tetratelabs/proxy-wasm-go-sdk
以proxy-wasm-go-sdk官方examples为例:
1 、安装tinygo(ubuntu为例) wget https: //github.com/tinygo-org/tinygo/releases/download/v0.27.0/tinygo_0.27.0_amd64.deb dpkg -i tinygo_0. 27 .0_amd64.deb //# docker 版本测试跑不起来 //# 测试命令及版本(0.27.0) tinygo version 2 、代码编写及编译 # sdk下载 git clone https: //github.com/tetratelabs/proxy-wasm-go-sdk //# examples 编译 make build.examples //#tinygo命令编译(cd到主函数所在的目录) tinygo build -o plugin.wasm -scheduler=none -target=wasi -no-debug 3 、镜像构建 //# Dockerfile FROM scratch COPY plugin.wasm ./ //# 编译镜像 docker build -t harbor-dev.eecos.cn: 1443 /esx/das/proxy-wasm-go-sdk-examples:http_headers . //# examples构建镜像前需要修改镜像地址,如:ref=harbor-dev.eecos.cn:1443/esx/das/proxy-wasm-go-sdk-examples:$$name make wasm_image.build_push |
发布WASM插件
常见的部署方式有:
1)打包到镜像并部署到envoy中,通常用于研测测试
2)使用wasmPlugin部署
3)使用EnvoyFilter部署
简单分析:
第一种方式:进推荐在研发调试阶段使用
第三种方式:首先需要创建一个包含已编译的 Wasm 插件的 ConfigMap,将 ConfigMap 挂载到网关 pod 中,然后通过 EnvoyFilter 配置 Envoy,从本地文件加载 Wasm 插件。
这种方法的限制是,复杂的 或者功能丰富的Wasm 模块可能超出 ConfigMap 1MB 的大小限制。
第二种方式:是基于命名空间级别,通过matchLabels 指定插件应用的 Pod 范围,管理方式跟DAS平台吻合
综上推荐使用wasmPlugin方式部署
//# WasmPlugin编排,das-ns-test命名空间下issac-ngnix应用 apiVersion: extensions.istio.io/v1alpha1 kind: WasmPlugin metadata: name: httpheaders namespace: das-ns-test spec: selector: matchLabels: app.kubernetes.io/name: issac-ngnix url: oci: //harbor-dev.eecos.cn:1443/esx/das/proxy-wasm-go-sdk-examples:http_headers imagePullPolicy: IfNotPresent //# 生效查看 //# 查看istiod pod的日志,如下: ads Push debounce stable[ 23138 ] 1 for config WasmPlugin/das-ns-test/httpheaders and 1 more configs: 100 .350664ms since last change, 108 .622738ms since last push, full= true //# wasmPlugin删除时,日志: ads Push debounce stable[ 23138 ] 2 for config WasmPlugin/das-ns-test/httpheaders and 1 more configs: 100 .350664ms since last change, 108 .622738ms since last push, full= true |
性能数据
未进行性能测试,参考阿里云性能测试结果(仅供参考):
1000并发1000QPS持续10秒钟
|
基准
|
WASM
|
LUA
|
---|---|---|---|
平均延迟 | 0.6317 secs | 0.6395 secs | 0.7012 secs |
延迟99%分布 | 0.9167 secs | 0.9352 secs | 1.1355 secs |
QPS | 1541 | 1519 | 1390 |
Total | 16281 | 16109 | 1390 |
相对于基准版本,增加EnvoyFilter的两个版本,平均延迟多出几十个到几百个毫秒,增加耗时比为
1. wasm 1.2% (0.6395-0.6317)/0.6317
和1% (1.3290-1.2078)/1.2078
2. lua 11%(0.7012-0.6317)/0.6317
和20% (1.4593-1.2078)/1.2078
侧面说明:WASM版本的性能明显优于LUA版本