wasm在云原生领域的运用

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-app
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
            subFilter:
              name: "envoy.filters.http.router"
    patch:
      operation: INSERT_BEFORE
      value:
        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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值