关于webassembly:使用OCI注册中心分发WebAssembly模块

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:v1
Pushed: <oci-registry>.azurecr.io/wasm-to-oci:v1
Size: 1624962
Digest: sha256:4c7915b4c1f9b0c13f962998e4199ceb00db39a4a7fa4554f40ae0bed83d9510

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

$ wasm-to-oci pull <oci-registry>.azurecr.io/wasm-to-oci:v1 --out test.wasm

Pulled: <oci-registry>.azurecr.io/wasm-to-oci:v1
Size: 1624962
Digest: sha256:4c7915b4c1f9b0c13f962998e4199ceb00db39a4a7fa4554f40ae0bed83d9510

$ wasmtime test.wasm
Hello from WebAssembly!

$ wasmer run test.wasm
Hello 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: 本文属于翻译,原文

【腾讯云】轻量 2核2G4M,首年65元

阿里云限时活动-云数据库 RDS MySQL  1核2G配置 1.88/月 速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

您可能还喜欢...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据