wasm在云原生领域的运用

server/2024/10/11 10:45:55/

Wasm 最初是以浏览器安全沙盒为目的开发的,发展到目前为止,WebAssembly 已经成为一个用于云原生软件组件的高性能、跨平台和多语言软件沙箱环境,Wasm 轻量级容器也非常适合作为下一代无服务器平台运行时

Envoy 社区在 Envoy 中嵌入了 WASM 虚拟机以获得一个安全的沙箱环境,用于动态加载和运行可拔插的扩展代码(被编译为 WASM 字节码),简化 Envoy 二次开发和功能增强的复杂度

prxoy_wasm 由一个关键的外部依赖提供,由 Envoy 社区和 Istio 社区等共同维护。它包含了对 WASM 虚拟机的封装。

并推出 针对代理的 WebAssembly (Wasm) (Proxy-Wasm):包括一个会标准化的ABI,SDK,

https://github.com/proxy-wasm/spec/pull/42/files?short_path=39c0fcb#diff-39c0fcbaec7f6ffb311e442b6f0774bf3c050cd9b3318f51f55c2d6c38d4976d

比如这样一个接口规范

#### `proxy_on_request_body`- params:- `i32 (uint32_t) stream_context_id`- `i32 (size_t) body_size`- `i32 (bool) end_of_stream`
- returns:- `i32 (`[`proxy_action_t`](https://github.com/proxy-wasm/spec/diffs/0?base_sha=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&head_user=PiotrSikora&name=v0.2.1&pull_number=42&sha1=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&sha2=3bf9d055ecab9ac2e25883c5f4f5082c1bda7a2b&short_path=39c0fcb&unchanged=expanded&w=false#proxy_action_t)`) action`Called for each chunk of HTTP request body received from downstream, even when the processing is paused.
Request body chunk (of `body_size`) can be retrieved and/or modified using [`proxy_get_buffer_bytes`](https://github.com/proxy-wasm/spec/diffs/0?base_sha=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&head_user=PiotrSikora&name=v0.2.1&pull_number=42&sha1=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&sha2=3bf9d055ecab9ac2e25883c5f4f5082c1bda7a2b&short_path=39c0fcb&unchanged=expanded&w=false#proxy_get_buffer_bytes) and/or [`proxy_set_buffer_bytes`](https://github.com/proxy-wasm/spec/diffs/0?base_sha=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&head_user=PiotrSikora&name=v0.2.1&pull_number=42&sha1=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&sha2=3bf9d055ecab9ac2e25883c5f4f5082c1bda7a2b&short_path=39c0fcb&unchanged=expanded&w=false#proxy_set_buffer_bytes) with `buffer_id` set to `HTTP_REQUEST_BODY`.
`body_size` represents total available size of the body that can be retrieved, and its value will increment if the processing is paused and the body is buffered by the host and not forwarded upstream.
Paused HTTP request can be resumed using [`proxy_continue_stream`](https://github.com/proxy-wasm/spec/diffs/0?base_sha=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&head_user=PiotrSikora&name=v0.2.1&pull_number=42&sha1=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&sha2=3bf9d055ecab9ac2e25883c5f4f5082c1bda7a2b&short_path=39c0fcb&unchanged=expanded&w=false#proxy_continue_stream) or closed using [`proxy_close_stream`](https://github.com/proxy-wasm/spec/diffs/0?base_sha=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&head_user=PiotrSikora&name=v0.2.1&pull_number=42&sha1=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&sha2=3bf9d055ecab9ac2e25883c5f4f5082c1bda7a2b&short_path=39c0fcb&unchanged=expanded&w=false#proxy_close_stream) with `stream_type` set to `HTTP_REQUEST`.
Additionally, as long as HTTP response headers were not send downstream, a HTTP response can be sent using [`proxy_send_local_response`](https://github.com/proxy-wasm/spec/diffs/0?base_sha=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&head_user=PiotrSikora&name=v0.2.1&pull_number=42&sha1=86719f51b29cc1fcdf2d07ae80a6cc7bae0bc99d&sha2=3bf9d055ecab9ac2e25883c5f4f5082c1bda7a2b&short_path=39c0fcb&unchanged=expanded&w=false#proxy_send_local_response).
Plugin must return one of the following values:
- `CONTINUE` to forward `HTTP_REQUEST_BODY` buffer upstream.
- `PAUSE` to pause processing.

下面我们来看下go-sdk里面的实现:
https://github.com/tetratelabs/proxy-wasm-go-sdk

//export proxy_on_request_body
func proxyOnRequestBody(contextID uint32, bodySize int, endOfStream bool) types.Action {if recordTiming {defer logTiming("proxyOnRequestBody", time.Now())}ctx, ok := currentState.httpContexts[contextID]if !ok {panic("invalid context on proxy_on_request_body")}currentState.setActiveContextID(contextID)return ctx.OnHttpRequestBody(bodySize, endOfStream)
}

可以看到每个实现的接口都有一个export标签,所以说proxy-wasm本质上还是遵循wasi规范,这样可以在编译为wasm文件的时候,能够被wasm任意虚拟机解析并调用。

Envoy使用WASM虚拟机(如WAVM或Wasmtime)加载和执行WASM模块。以下是Envoy解析WASM文件的过程:

  1. 配置WASM插件

在Envoy配置文件中,你需要配置WASM插件。配置文件中的wasm字段指定了WASM模块的路径、虚拟机类型、配置数据等信息。例如:

wasm:config:name: "my_plugin"root_id: "my_root_id"vm_config:runtime: "envoy.wasm.runtime.wavm"configuration:"@type": "type.googleapis.com/google.protobuf.StringValue"value: "my_plugin_config"vm_id: "my_vm_id"vm_type: "plugin"vm_environment:runtime_supports_wasi: true
  1. 加载WASM模块

Envoy使用配置文件中指定的虚拟机类型(如WAVM或Wasmtime)加载WASM模块。加载过程包括以下步骤:

  • 读取WASM文件。

  • 验证WASM文件的格式和结构。

  • 将WASM文件编译为宿主机器代码。

  • 初始化WASM虚拟机。

  1. 实例化WASM模块

Envoy使用配置文件中指定的根ID(root_id)实例化WASM模块。实例化过程包括以下步骤:

  • 分配内存。

  • 初始化全局变量。

  • 调用WASM模块的_start函数。

  1. 调用WASM模块的导出函数

Envoy通过ABI(应用程序二进制接口)与WASM模块进行交互。ABI定义了WASM模块中导出的函数和数据结构,这些函数和数据结构允许Envoy访问WASM模块的功能。Envoy在特定的事件(如HTTP请求、TCP连接等)上调用WASM模块的导出函数,并传递相关的数据。

  1. 销毁WASM模块

当WASM模块不再需要时,Envoy会销毁WASM模块,释放资源。
总之,Envoy通过配置文件中指定的虚拟机类型加载和执行WASM模块,并通过ABI与WASM模块进行交互。在开发基于Envoy的WASM插件时,你需要实现ABI中定义的导出函数,并根据需要调用Envoy的API。

在Istio中,你需要使用EnvoyFilter资源来配置WASM插件。EnvoyFilter资源允许你在Envoy代理中添加、修改或删除配置。你需要在EnvoyFilter资源中指定WASM模块的路径、虚拟机类型、配置数据等信息。例如:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: my-wasm-plugin
spec:workloadSelector:labels:app: my-appconfigPatches:- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener:filterChain:filter:name: "envoy.filters.network.http_connection_manager"subFilter:name: "envoy.filters.http.router"patch:operation: INSERT_BEFOREvalue:name: "envoy.filters.http.wasm"typed_config:"@type": "type.googleapis.com/udpa.type.v1.TypedStruct"type_url: "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm"value:config:name: "my_plugin"root_id: "my_root_id"vm_config:runtime: "envoy.wasm.runtime.wavm"configuration:"@type": "type.googleapis.com/google.protobuf.StringValue"value: "my_plugin_config"vm_id: "my_vm_id"vm_type: "plugin"vm_environment:runtime_supports_wasi: true

https://cloudnative.to/blog/envoy-wasm-source-deep-dive/


http://www.ppmy.cn/server/130088.html

相关文章

esp8266 at指令链接wifi时一直connect disconnest

那是你的连接wifi的名字密码有误或者热点有问题,看看热点是不是把设备拉入黑名单或者设置为5G或者连了校园网或者设置了最多链接设备

Linux——echo-tail-重定向符

echo命令 类似printf 输出 反引号 重定向符 > 和 >> > 覆盖 >> 追加 tail命令 查看文件尾部内容,追踪文件最新更改 tail -num 从尾部往上读num行,默认10行 tail -f 持续跟踪

Cherno游戏引擎笔记(61~72)

---------------一些维护和更改------------- 》》》》 Made Win-GenProjects.bat work from every directory 代码更改: echo off->pushd ..\->pushd %~dp0\..\call vendor\bin\premake\premake5.exe vs2019popdPAUSE 为什么要做这样的更改? …

moectf-Web题解

1、弗拉格之地的入口 2、垫刀之路01: MoeCTF?启动! 3、ez_http 4、ProveYourLove 5、弗拉格之地的挑战 6、ImageCloud前置 7、垫刀之路02: 普通的文件上传 8、垫刀之路03: 这是一个图床 9、垫刀之路05: 登陆网站 10、垫刀之路06: pop base mini …

笔记本电脑重启输入密码后黑屏

型号:Dell G3 3590 系统:Win10 背景 原本想安装火绒清一清缓存之类的垃圾文件的,安装完火绒之后点击垃圾清理,提示需要更新工具,ok,更新,进度到50%就不动了,然后火绒通知我 发现危险信息&…

订阅ROS2中相机的相关话题并保存RGB、深度和点云图

系统:Ubuntu22.04 ROS2版本:ROS2 humble 1.订阅ROS2中相机的相关话题并保存RGB图、深度图和点云图 ros2 topic list/stellar_1/rgb/image_raw /camera/depth/image_raw /stellar_1/points2CMakeLists.txt cmake_minimum_required(VERSION 3.15) projec…

WPF|依赖属性SetCurrentValue方法不会使绑定失效, SetValue方法会使绑定失效?是真的吗?

引言 最近因为一个触发器设置的结果总是不起效果的原因,进一步去了解[依赖属性的优先级](Dependency property value precedence - WPF .NET | Microsoft Learn)。在学习这个的过程中发现对SetCurrentValue一直以来的谬误。 在WPF中依赖属性Dependency property的…

【最新华为OD机试E卷-支持在线评测】虚拟理财游戏(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…