前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OCI容器与Wasm初体验

OCI容器与Wasm初体验

作者头像
zouyee
发布2023-02-06 10:40:10
9150
发布2023-02-06 10:40:10
举报
文章被收录于专栏:Kubernetes GOKubernetes GO

WebAssembly(Wasm)有一套完整的语义,在web中被设计成无版本、特性可测试、向后兼容的,当然,WebAssembly 不仅可以运行在浏览器上,也可以运行在非web环境下。实际上wasm是体积小且加载快的二进制格式,其目标就是充分发挥硬件能力以达到原生执行效率,在本文中,将介绍以容器镜像方式运行Wasm工作负载的场景,关于运行时的介绍可以参看Containerd深度剖析-runtime篇

编辑|阎锡山

技术深度|简单

Wasm简介

WebAssembly(简称 Wasm)是一种为栈式虚拟机设计的二进制指令集。Wasm 被设计为可供类似C/C++/Rust等高级语言的平台编译目标,最初设计目的是解决 JavaScript 的性能问题。Wasm 是由 W3C 牵头正在推进的 Web 标准,并得到了谷歌、微软和 Mozilla 等浏览器厂商的支持。当然,WebAssembly 不仅可以运行在浏览器上,也可以运行在非web环境下。

Wasm 具有运行高效、内存安全、无未定义行为和平台独立等特点,经过了编译器和标准化团队多年耕耘,目前已经有了成熟的社区。对于 Wasmtime、Wamr、Wasm3、WasmEdge 和 Wasmer 等采用 Wasm 格式的非浏览器运行时,其一方面展示了 Wasm 规范的灵活性,比如把 Wasm3 当成解释器来执行;另一方面则能支持 JIT 和 AOT 编译,外加各种缓存及优化功能。

WASM虚拟机

  • WASMTIME WASMTIME是字节码联盟主推的一个WASM虚拟机,既可以作为一个CLI,也可以被嵌入到其他应用系统中,如IoT或者云原生
  • WAMR 同样是字节码联盟旗下的,更偏向于芯片场景的虚拟机,如它的名字所示,体积非常小,起步速度只要100微秒,内存耗费最低只需100KB
  • WASMER 这是独立于字节码联盟,并努力构建自己生态的社区推出的产品,特点是支持在更多的编程语言运行WASM实例,并有自己的包管理平台Wapm
  • SSVM 这是一个相对小众的运行时,对云、AI 以及区块链有针对性的优化
  • WasmEdge WasmEdge是一个轻量级高性能虚拟机,应用于 severless 云函数、SaaS、区块链智能合约、物联网、汽车实时软件应用等多种场景

WASM虚拟机的优势

1. 快速、高效、可移植:通过利用常见的硬件能力,WASM代码在不同平台上能够以接近本地速度运行。

2. 可读、可调试:WASM是低阶语言,但允许通过人工来写代码、看代码以及调试代码。

3. 保持安全:WASM被限制运行在一个安全的沙箱执行环境中。像其他网络代码一样,它遵循浏览器的同源策略和授权策略。

4. 不破坏网络:WASM的设计原则是与其他网络技术和谐共处并保持向后兼容。

虽然 Wasm 在浏览器中高度依赖于 JavaScript 和 Wasm 运行时之间的桥梁,但非营利性组织字节码联盟(Cosmonic、Fermyon 和 Suborbital 等都是其成员)一起参与研发,希望为 Wasm 引入系统绑定。Wasm 系统接口(WASI)就是典型案例,其添加了能够与文件系统、环境变量、时钟和随机数生成器等系统资源进行交互的标准化支持。

WASI

WASI是一个新的API体系, 由Wasmtime项目设计, 目的是为WASM设计一套引擎无关(engine-indepent),面向非Web系统(non-Web system-oriented)的API标准. 目前, WASI核心API(WASI Core)在做覆盖文件,网络等等模块的API, 离实用还是有很长路要走.

WASM与Runtime

WebAssembly和WASI都是相当新的东西,因此在容器生态系统上运行Wasm工作负载的标准还没有确定。本文只介绍一种解决方案,当然还有其他可行的方案,例如将Linux容器运行时与Wasm兼容的组件替换。比如,使用Krustlet替代原生的kubelet,这种方法的局限性在于,用户必须在Linux容器运行时和Wasm运行时之间进行选择;另一种解决方案是使用带有Wasm运行时的镜像并调用编译后的二进制文件,但这种方法会使容器镜像随着运行时而膨胀,如果在低容器运行时上调用Wasm运行时,就不一定需要这种方法。

本文将介绍如何通过配置,让OCI运行时运行Linux容器和wasi兼容的工作负载。

低级运行时Crun

通过现有的低级别OCI运行时实现调用Linux容器和Wasm容器,就可以很容易地解决上面讨论的一些问题。这避免了诸如依赖容器镜像来承载Wasm运行时或向仅支持Wasm容器的基础设施引入新层等问题。

其中一个可以处理该任务的容器运行时:Crun

Crun速度快,占用内存少,是一个完全符合oci标准的容器运行时,可以作为现有容器运行时的替代品。最初编写Crun是为了运行Linux容器,但它也提供了以host方式在容器沙盒中运行任意扩展的程序的能力。

下面是用Crun替换现有运行时的一种不正规的方式,其只是为了展示Crun可以替换现有的OCI运行时。

代码语言:javascript
复制
$ $ mv /path/to/exisiting-runtime /path/to/existing-runtime.backup
$ cp /path/to/crun /path/to/existing-runtime

其中一个处理程序是crun-wasm-handler,将配置的容器镜像(Wasm 兼容镜像)集成到crun sandbox从而成为现有的Wasm运行系统的一部分。通过这种方式,终端用户不需要自己维护Wasm运行时。

crun与wasmedge、wasmtime和wasmer进行了集成,以支持开箱即用的功能。crun可以通过检测镜像是否包含Wasm/WASI工作负载,以动态调用这些运行时。

有关使用Wasm/WASI支持构建crun的详细信息,请参见GitHub上的crun库。

用户可以在Podman和Kubernetes上使用crun作为底层的OCI运行时来创建和运行与平台无关的Wasm镜像。

Buildah构建镜像

Wasm/WASI兼容的映像是特殊的。它们包含一个注释(annotation),可以帮助像crun这样的OCI运行时区分linux一般镜像还是具有Wasm/WASI工作负载的镜像。然后,按需调用处理程序。

可以使用任何容器镜像构建工具,以创建Wasm镜像,但在本文中,使用Buildah。

1. 编译.wasm模块。

2.用.wasm模块准备一个Dockerfile。

代码语言:javascript
复制
FROM scratch
COPY hello.wasm /
CMD ["/hello.wasm"]

3. 使用Buildah构建Wasm镜像,并打上module.wasm.image/varian=compat的annotation

代码语言:javascript
复制
$ buildah build --annotation "module.wasm.image/variant=compat" -t mywasm-image

构建完镜像并将容器引擎配置为crun,crun将自动执行所需的工作并运行由配置的Wasm处理程序提供的工作负载。

Podman运行WASM

Crun是Podman的默认OCI运行时。Podman可以利用大多数crun特性,包括crun Wasm处理程序。一旦构建了Wasm 兼容镜像,Podman就可以像使用其他容器镜像一样使用它们:

代码语言:javascript
复制
$ podman run mywasm-image:latest

Podman使用crun的Wasm处理程序运行mywasm-image:latest,并返回执行的输出。

代码语言:javascript
复制
hello world from the webassembly module !!!!

WASM与CRI

下面是如何配置两个常用的容器运行时:

CRI-O

cri-o是一个轻量级的CRI运行时,它支持OCI,并提供镜像的管理、容器进程管理、监控日志及资源隔离等工作。

cri-o的通信地址默认是在/var/run/crio/crio.sock。

配置

1. 通过编辑/etc/crio/crio.conf的配置,配置crio使用crun而不是runc。Red Hat OpenShift文档包含关于配置crio的更多细节。

2. 用sudo systemctl Restart crio重新启动crio。

3.CRI-O自动将pod注释传播到容器spec。

Containerd

containerd应该是目前最流行的CRI运行时。它以插件的方式实现CRI,默认是启用的。它默认在unix套接字上监听消息。

从1.2版本开始,它通过 runtime handler来支持多种低级运行时。运行时处理程序是通过CRI中的字段传递,根据该运行时处理程序,containerd运行shim的应用程序来启动容器。这可以用来运行 runc及其他的低级运行时的容器,如 gVisor、Kata Containers等。在Kubernetes API中通过RuntimeClass进行运行时配置。

配置

1. Containerd支持通过在/etc/containerd/config.toml中定义的自定义配置切换容器运行时。

2. 通过确保运行时二进制文件指向crun,将containd配置为使用crun。更多细节可在包含的文档中找到。

3. 配置containd允许列出Wasm注释,这样它们就可以通过在配置中设置pod_annotations来传播到OCI规范:pod_annotations = ["module.wasm.image/ variable .*"]。

4. 使用sudo systemctl start containerd重新启动容器。

5. 现在,containd应该将wasmpod注释传播到容器。

下面是一个Kubernetes pod规范的例子,可以同时使用crio和containerd:

代码语言:javascript
复制
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-wasm-workload
  namespace: mynamespace
  annotations:
    module.wasm.image/variant: compat
spec:
  containers:
  - name: wasm-container
    image: myrepo/mywasmimage:latest

相关问题

CRI在Kubernetes 1.5中引入,作为kubelet和容器运行时之间的桥梁。社区希望Kubernetes集成的高级容器运行时实现CRI。该运行时处理镜像的管理,支持Kubernetes pods,并管理容器,因此根据高级运行时的定义,支持CRI的运行时必须是一个高级运行时。低级别的运行时并不具备上述功能。

在许多情况下,Pod带有sidecar。这意味着,当部署包含sidecar且sidecar容器不包含Wasm entry point时,crun的Wasm集成是没有用的,例如使用服务网格(如Linkerd、Gloo和Istio)的基础设施或网络代理(如Envoy)。

当然我们可以通过为Wasm处理程序添加两个annotation来解决这个问题:compat-smart和was-smart。这些注释充当选择开关,只在容器需要时切换Wasm运行时。因此,当使用sidecars运行部署时,只有包含有效Wasm工作负载的容器才由Wasm处理程序执行。常规容器被视为常规容器,并委托给主机Linux容器运行时。

因此,在构建容器镜像时,需要使用的annotation是module.wasm.image/variant=compat-smart而不是module.wasm.image/variant=compat。

由于笔者时间、视野、认知有限,本文难免出现错误、疏漏等问题,期待各位读者朋友、业界专家指正交流。

参考文献

1.https://www.528btc.com/college/58442.html

2.https://insujang.github.io/2019-10-31/container-runtime/

3.https://github.com/cri-o/cri-o

4. https://opensource.com/article/22/10/wasm-containers

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-12-06,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 DCOS 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com