Istio 1.5 回归单体架构,并抛却原有的 out-of-process 的数据面扩展方式,转而拥抱基于 WASM 的 in-proxy 扩展,以期获得更好的性能。本文基于网易杭州研究院轻舟云原生团队的调研与探索,介绍 WASM 的社区发展与实践。
超简单版解释:
--> Envoy 内置 Google V8 引擎,支持WASM字节码运行,并开放相关接口用于和 WASM 虚拟机交互数据;
--> 使用各种语言开发相关扩展并编译为 .WASM 文件;
--> 将扩展文件挂载或者打包进入 Envoy 容器镜像,通过xDS动态下发文件路径及相关配置由虚拟机执行。
WebAssembly 简述
Istio 最新发布的 1.5 版本,架构发生了巨大调整,从原有的分布式结构回归为单体,同时抛却了原有的 out-of-process 的 Envoy 扩展方式,转而拥抱基于 WASM 的 in-proxy 扩展,以期获得更好的性能,同时减小部署和使用的复杂性。所有的 WASM 插件都在 Envoy 的沙箱中运行,相比于原生 C++ Envoy 插件,WASM 插件具有以下的优点:
接近原生插件性能(存疑,待验证,社区未给出可信测试结果,但是 WASM 字节码和机器码比较接近,它的性能极限确实值得期待);
沙箱运行,更安全,单个 filter 故障不会影响到 Envoy 主体执行,且 filter 通过特定接口和 Envoy 交互数据,Envoy 可以对暴露的数据进行限制(沙箱安全性对于 Envoy 整体稳定性保障具有很重要的意义);
可动态分发和载入运行(单个插件可以编译为 .WASM 文件进行分发共享,动态挂载,动态载入,且没有平台限制);
无开发语言限制,开发效率更高(WASM 本身支持语言众多,但是限定到 Envoy 插件开发,必然依赖一些封装好的 SDK 用于和 Envoy 进行交互,目前只有 C++ 语言本身、Rust 以及 AssemblysScript 有一定的支持)。
WASM 的诞生源自前端,是一种为了解决日益复杂的前端 web 应用以及有限的 JavaScript 性能而诞生的技术。它本身并不是一种语言,而是一种字节码标准,一个“编译目标”。WASM 字节码和机器码非常接近,因此可以非常快速的装载运行。任何一种语言,都可以被编译成 WASM 字节码,然后在 WASM 虚拟机中执行(本身是为 web 设计,必然天然跨平台,同时为了沙箱运行保障安全,所以直接编译成机器码并不是最佳选择)。理论上,所有语言,包括 JavaScript、C、C++、Rust、Go、Java 等都可以编译成 WASM 字节码并在 WASM 虚拟机中执行。
![任何一种语言都可以编译成 WASM 字节码并在 WASM 虚拟机中执行](https://i-blog.csdnimg.cn/blog_migrate/7c047365755dbc389719d454a1190a30.png)
社区发展及现状
Envoy & WASM
Envoy 提供了一个特殊的 Http 七层 filter,名为 wasm,用于载入和执行 WASM 字节码。该七层 filter 同样也负责 WASM 虚拟机的创建和管理,使用的是 Google 内部的 v8 引擎(支持 JS 和 WASM)。当前 filter 未进入 Envoy 主干,而是在单独的一个工程中。该工程会周期性从主干合并代码。从机制看,WASM 扩展和 Lua 扩展机制非常相似,只是 Lua 载入的是原始脚本,而 WASM 载入的是编译后的 WASM 字节码。Envoy 暴露相关的接口如获取请求头、请求体,修改请求头,请求体,改变插件链执行流程等等,用于 WASM 插件和 Envoy 主体进行数据交互。
对于每一个 WASM 扩展插件都可以被编译为一个 *.WASM 文件,而 Envoy 七层提供的 wasm Filter 可以通过动态下发相关配置(指定文件路径)使其载入对应的文件并执行:前提是对应的文件已经在镜像中或者挂载进入了对应的路径。当然,WASM Filter 也支持从远程获取对应的 *.WASM 文件(和目前网易轻舟 API 网关对 Lua 脚本扩展的支持非常相似)。
Istio & WASM
现有的 Istio 提供了名为 Mixer 插件模型用于扩展 Envoy 数据面功能,具体来说,在 Envoy 内部,Istio 开发了一个原生 C++ 插件用于收集和获取运行时请求信息并通过 gRPC 将信息上报给 Mixer,外部 Mixer 则调用各个 Mixer Adapter 用于监控、授权控制、限流等等操作,相关处理结果如有必要再返回给 Envoy 中 C++ 插件用于做相关控制。
Mixer 模型虽然提高了极高的灵活性,且对 Envoy 侵入性极低,但是引入了大量的额外的外部调用和数据交互,带来了巨大的性能开销(相关的测试结果很多,按照 istio 社区的数据:移除 Mixer 可以使整体 CPU 消耗减少 50%)。而且 Istio 插件扩展模型和 Envoy 插件模型整体是割裂的,Istio 插件在 out-of-process 中执行,通过 gRPC 进行插件与 Envoy 主体的数据交互,而 Envoy 原生插件则是 in-proxy 模式,在同一个进程中通过虚函数接口进行调用和执行。
因此在 Istio 1.5 中,Istio 提供了全新的插件扩展模型:WASM in proxy。使用 Envoy 支持的WASM机制来扩展插件:兼顾性能、多语言支持、动态下发动态载入、以及安全性。唯一的缺点就是现有的支持还不够完善。
为了提升性能,Istio 社区在 1.5 发布中,已经将