WebAssembly(WASM)是基于堆栈的虚拟机的二进制指令格局。用相熟的术语来说,WASM是各种编程语言(例如C,C ++,Rust或Golang)的编译指标,生成具备已知格局的紧凑二进制文件。 Mozilla开发人员称WebAssembly对Web平台具备微小的意义--它提供了一种以近乎本机的速度在Web上运行以多种语言编写的代码的形式。

这里的最大含意是可能以靠近本机的速度在Web上执行模块。过来应用JavaScript编写时性能低下的工作能够用高性能编程语言(例如C ++或Rust)来重写。

然而WebAssembly不仅实用于Web。 WebAssembly零碎接口我的项目(WASI)旨在通过提供操作系统工作的形象来标准化WebAssembly以在Web内部运行。这带来了两个次要长处:可移植性和安全性。明天,您能够应用wasmtime之类的运行时,在具备对文件系统和网络的细粒度拜访的沙盒环境中,在各种操作系统(Linux,macOS,Windows)上执行WASM模块。

咱们认真想想,这些劣势不正是现在如日中天的容器具备的劣势吗?

WASI能够为容器生态系统提供一个十分乏味的代替办法-然而对于本文,咱们仅探讨如何散发WebAssembly模块。

应用OCI注册核心散发WebAssembly模块

目前,有两种调配WebAssembly模块的办法-- wasm-pack(应用NPM来存储模块)或WAPM(独立于编程语言和工具链,但仍是一个十分晚期的工具,尚未在其内部宽泛采纳)。然而,如果咱们认为WebAssembly是Linux容器的潜在跨平台替代品,那么咱们还须要一种独立于编程语言和工具链的散发形式。为何不齐全应用OCI注册核心散发容器镜像的办法呢?

此外,OCI最近发表了OCI Artifacts我的项目,该我的项目旨在扩大OCI注册管理机构标准并存储其余云原生工件(思考Helm图表或CNAB捆绑软件)。具备间接的长处--一种统一的形式来调配多个工件类型,应用曾经存在的注册表服务或重用和扩大以后的平安模型(例如TUF)。

ORAS(OCI注册表存储)是OCI Artifacts我的项目的拟议施行,可显著简化OCI注册表中任意内容的存储。因而,咱们能够应用ORAS客户端库来构建一个非常简单的工具,以将WebAssembly模块推入和推到OCI注册表中。

然而请留神,以后,大多数注册表服务都回绝未知的工件类型--ORAS已通过开源Docker Distribution我的项目和Azure Container Registry进行了测试。

第一步是定义要与WebAssembly模块关联的媒体类型--这有助于辨认工件类型,能够在配置注册表以显式容许或不容许存储它们时应用。

ConfigMediaType       = "application/vnd.wasm.config.v1+json"ContentLayerMediaType = "application/vnd.wasm.content.layer.v1+wasm"

为了推送,咱们读取了模块的内容,将它们作为单个层增加到OCI描述符中,而后应用oras.Push

contents, err := ioutil.ReadFile(module)desc := store.Add(module, ContentLayerMediaType, contents)layers := []ocispec.Descriptor{desc}pushOpts := []oras.PushOpt{    oras.WithConfigMediaType(ConfigMediaType),    oras.WithNameValidation(nil),}manifest, err := oras.Push(ctx, resolver, ref, store, layers, pushOpts...)

拉取同样简单明了--咱们应用oras.Pull来获取OCI清单和理论模块,而后将其写入文件中:

pullOpts := []oras.PullOpt{    oras.WithAllowedMediaType(ContentLayerMediaType),    oras.WithPullEmptyNameAllowed(),}_, layers, err := oras.Pull(ctx, resolver, ref, store, pullOpts...)manifest, contents, _ := store.Get(layers[0])ioutil.WriteFile(outFile, contents, 0755)

能够在GitHub上找到Go软件包和一个wasm-to-oci实用程序。

应用OCI注册表进行测试

咱们有一个本地模块(能够在repo的 testdata目录中找到),并且咱们应用wasm-to-oci推送到咱们以后登录的Azure容器注册表存储库(应用Docker CLI):

$ ls.rwxr-xr-x 1.6M radu  hello.wasm$ wasm-to-oci push hello.wasm <oci-registry>.azurecr.io/wasm-to-oci:v1Pushed: <oci-registry>.azurecr.io/wasm-to-oci:v1Size: 1624962Digest: sha256:4c7915b4c1f9b0c13f962998e4199ceb00db39a4a7fa4554f40ae0bed83d9510

此时,咱们能够应用雷同的实用程序从刚刚推送的存储库中提取信息,而后应用抉择的WebAssembly运行时执行模块:

$ wasm-to-oci pull <oci-registry>.azurecr.io/wasm-to-oci:v1 --out test.wasmPulled: <oci-registry>.azurecr.io/wasm-to-oci:v1Size: 1624962Digest: sha256:4c7915b4c1f9b0c13f962998e4199ceb00db39a4a7fa4554f40ae0bed83d9510$ wasmtime test.wasmHello from WebAssembly!$ wasmer run test.wasmHello from WebAssembly!

咱们能够查看生成的OCI清单,并查看咱们之前设置的媒体类型,以及清单和理论模块的摘要和大小:

{  "schemaVersion": 2,  "config": {    "mediaType": "application/vnd.wasm.config.v1+json",    "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",    "size": 2  },  "layers": [    {      "mediaType": "application/vnd.wasm.content.layer.v1+wasm",      "digest": "sha256:4c7915b4c1f9b0c13f962998e4199ceb00db39a4a7fa4554f40ae0bed83d9510",      "size": 1624962    }  ]}

论断

这是将WASM存储在OCI注册核心的乏味概念证实。如果您当初正在Web上应用WebAssembly,则很可能不须要它,然而在WASI的状况下,它很有用,尤其是思考到WebAssembly的 container shim 程序。

PS: 本文属于翻译,原文