首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >OCI容器与Wasm初体验

OCI容器与Wasm初体验

作者头像
zouyee
发布于 2023-02-06 02:40:10
发布于 2023-02-06 02:40:10
1.3K00
代码可运行
举报
文章被收录于专栏:Kubernetes GOKubernetes GO
运行总次数:0
代码可运行

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
代码运行次数:0
运行
AI代码解释
复制
$ $ 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
代码运行次数:0
运行
AI代码解释
复制
FROM scratch
COPY hello.wasm /
CMD ["/hello.wasm"]

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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
代码运行次数:0
运行
AI代码解释
复制
$ podman run mywasm-image:latest

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
代码运行次数:0
运行
AI代码解释
复制
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 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于Boost库、Jsoncpp、cppjieba、cpp-httplib等构建Boost搜索引擎
目前我们常用的搜索引擎有Google、百度、360等,这些搜索引擎都是超大型超完善的全网搜索,而本项目Boost搜索引擎只是一个非常简单的站内搜索。
_小羊_
2025/05/06
2580
基于Boost库、Jsoncpp、cppjieba、cpp-httplib等构建Boost搜索引擎
【C++|Linux|计网】构建Boost站内搜索引擎的技术实践与探索
技术栈:C/C++ C++11, STL, 标准库Boost,Jsoncpp,cppjieba,cpp-httplib ,
用户11316056
2024/12/20
2780
【C++|Linux|计网】构建Boost站内搜索引擎的技术实践与探索
【项目】基于Boost自主实现搜索引擎
  可以看出原始html文件中有很多特定的标签,为了方便我们查找与阅读,我们需要对其进行去标签化;   因为我们期望查找后返回给我们的格式是类似于百度等搜索引擎返回的格式,大致包含以下三个部分:   1. 标题   2. 内容   3. 网址URL
大耳朵土土垚
2025/02/26
2201
【项目】基于Boost自主实现搜索引擎
【Boost搜索引擎项目】构建Boost站内搜索引擎的技术
我们使用最新的boost_1_86_0/doc/html⽬录下的html⽂件,⽤它来进⾏建⽴索引
小焱
2025/07/06
1050
【文档搜索引擎】在内存中构造出索引结构(下)
文本实质上就是字符串,我们就可以把字符串直接保存在文件中。我们就需要把内存中的索引结构变成一个“字符串”,然后写文件即可
椰椰椰耶
2024/12/20
1810
【文档搜索引擎】搜索模块的完整实现
去掉 script 的标签和内容,正则就可以写成这样:<script.*?>(.*?)</script>
椰椰椰耶
2025/01/09
3360
【文档搜索引擎】搜索模块的完整实现
【文档搜索引擎】在内存中构造出索引结构(上)
创建一个相关方法 getDocInfo。期望其能查询到相关文档信息,所以返回值为 DocInfo
椰椰椰耶
2024/12/20
1710
【文档搜索引擎】在内存中构造出索引结构(上)
【从0做项目】Java搜索引擎(2)图解索引结构
简述:在我的搜索引擎网站,用户进行关键字搜索,就可以查询到与这个关键字相关的java在线文档,(包含标题,关键字附近的简述,url),用户点击标题,即可跳转到相关在线文档,适用于JDK17版本。
三三是该溜子
2025/02/16
1630
【从0做项目】Java搜索引擎(2)图解索引结构
lucene思维导图,让搜索引擎不再难懂
以上是我们java常用的全文搜索引擎框架,很多项目的搜索功能都是基于以上4个框架完成的。
java思维导图
2018/12/21
1.6K0
lucene思维导图,让搜索引擎不再难懂
搜索引擎原理解析:从0开始实现一个搜索引擎
打开谷歌, 输入关键词, 谷歌往往可以很精准的返回你所需要的内容, 这个是怎么实现的呢?简单的思考一下就能得出一个结论:一定是关键词能极为快速和准确的命中具体的内容及地址, 但是搜索引擎的收录页面数量往往是千亿万亿级别的,从这个量级里面检索到你要的数据可以说是大海捞针一点也不夸张。那么搜索引擎是如何让你在数据的汪洋大海里捞到你想要的那根针的那?这就要说到所有的搜索引擎都离不开一个概念: 索引。
政采云前端团队
2023/12/19
1.8K0
搜索引擎原理解析:从0开始实现一个搜索引擎
一个朴素的搜索引擎实现
今天我们要使用 Lucene 来实现一个简单的搜索引擎,我们要使用上一节爬取的果壳网语料库来构建索引,然后在索引的基础上进行关键词查询。
老钱
2019/09/11
5940
一个朴素的搜索引擎实现
【从0做项目】Java搜索引擎(3)
简述:在我的搜索引擎网站,用户进行关键字搜索,就可以查询到与这个关键字相关的java在线文档,(包含标题,关键字附近的简述,url),用户点击标题,即可跳转到相关在线文档,适用于JDK17版本。
三三是该溜子
2025/02/17
2340
【从0做项目】Java搜索引擎(3)
【文档搜索引擎】缓冲区优化和索引模块小结
开机之后,首次制作索引会非常慢,但后面就会快了 重启机器,第一次制作又会非常慢 这是为什么呢?
椰椰椰耶
2025/01/09
1580
【文档搜索引擎】缓冲区优化和索引模块小结
【从0做项目】Java搜索引擎(5)
简述:在我的搜索引擎网站,用户进行关键字搜索,就可以查询到与这个关键字相关的java在线文档,(包含标题,关键字附近的简述,url),用户点击标题,即可跳转到相关在线文档,适用于JDK17版本。
三三是该溜子
2025/02/18
2520
【从0做项目】Java搜索引擎(5)
【文档搜索引擎】使用多线程优化流程
所以我们在遍历文件的时候,不能在任务布置完之后就立刻保存索引,要保证所有的任务都执行完(所有的线程把所有的文档任务处理完),才能执行 save
椰椰椰耶
2024/12/20
1670
【文档搜索引擎】使用多线程优化流程
CodeBuddy+Lucene 探索与实践日志:记录我如何从零构建桌面搜索引擎
在一次知识管理系统的开发中,我面临一个需求:为用户提供对本地文档(如 TXT、PDF、Word)的全文检索功能。这些文档分散在目录中,用户需要能像使用百度一样,快速找到包含特定关键词的文件。
熊猫钓鱼
2025/08/28
1960
CodeBuddy+Lucene 探索与实践日志:记录我如何从零构建桌面搜索引擎
12.搜索引擎的基本原理
搜索引擎由众多模块组成,包括数据采集模块、文本分析模块、索引存储模块、搜索模块,那么接下来我们依次分析每个模块的作用
AI码师
2023/12/20
2840
12.搜索引擎的基本原理
搜索引擎核心技术初探——倒排索引
数字化时代,搜索引擎已经成为我们日常生活中不可或缺的一部分,为我们提供了一个迅速而便捷的途径。 搜索引擎利用复杂的算法来实现高效的搜索,其中一个关键的技术却是倒排索引。 这个看似普通的数据结构却是搜索引擎背后的核心,负责快速、有效地定位相关信息。
windealli
2023/11/15
2.9K0
搜索引擎核心技术初探——倒排索引
搜索引擎之倒排索引浅析
上一篇文章 ElasticSearch 术语中提到了倒排索引,那么这篇文章就来讲解下什么是倒排索引,倒排索引的数据结构以及 ElasticSearch 中的倒排索引。
武培轩
2020/03/05
1.3K0
搜索引擎之倒排索引浅析
【从0做项目】Java文档搜索引擎(9)烧脑终章!
简述:在我的搜索引擎网站,用户进行关键字搜索,就可以查询到与这个关键字相关的java在线文档,(包含标题,关键字附近的简述,url),用户点击标题,即可跳转到相关在线文档,适用于JDK17版本。
三三是该溜子
2025/02/22
1900
【从0做项目】Java文档搜索引擎(9)烧脑终章!
推荐阅读
相关推荐
基于Boost库、Jsoncpp、cppjieba、cpp-httplib等构建Boost搜索引擎
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档