简单介绍WebAssembly与云原生的关系

查理谈科技 2024-05-13 22:37:13

WebAssembly简介

在介绍 WebAssembly 之前,了解虚拟化的简要历史非常重要,以便更好地了解 WebAssembly 的背景。

当VMware开始虚拟化革命时,虚拟机被定位为计算单元。 这意味着您可以创建和部署与虚拟机 (VM) 兼容的软件。 基于虚拟机的方法提供了很好的隔离,因为它在软件和运行工作负载的主机(称为虚拟机管理程序)之间引入了内核边界。 尽管虚拟机很安全,但其本质上很重并且需要时间来启动。

随着云技术的进步,我们看到了基于容器(例如Docker)的虚拟化的出现,这主要是由 Linux 内核中的结构推动的。 同一主机上的容器共享 Linux 内核,但具有足够的安全机制,例如命名空间、seccomp 配置文件和 SELinux,它们为容器提供了多层安全性。

2018 年,出现了一种名为 WebAssembly 的新技术。 它由 Mozilla 创建,最初是一种基于浏览器的技术。 从那时起,开发人员就在云和服务器端应用程序上使用了它。 WebAssembly 通过在 Linux 进程中运行 Wasm 计算来允许额外级别的虚拟化。

事情从虚拟机(这是完整的操作系统)开始,然后转移到 Linux 容器(受 Linux 内核保护和隔离的 Linux 进程)。 现在有了WebAssembly,Linux 进程中的计算单元。 WebAssembly的目标是提供一个可以快速启动并适合无服务器工作负载的计算单元。

WebAssembly(也称为 Wasm)是用于可互操作计算单元的新通用字节码。 可互操作意味着计算单元应该能够在任何兼容的 Wasm 运行时上运行。 计算单元是 Wasm 模块。 基本思想是拥有一种通用且标准的字节码格式。

JavaScript、Rust、Golang 和 Java 等语言可以编译为基于 Wasm 的字节码。 一旦生成该字节码,就可以在任何 Wasm 运行时上执行。

Wasm 是一个小型且高效的基于堆栈的虚拟机,它通过将代码编译为通用字节码表示来抽象目标架构。 Wasm 基于全行业的协作努力,以获得接近汇编语言的性能和安全性。

字节码联盟(Bytecode Alliance)的成立是为了创建 WebAssembly 标准的共享实现,包括 Arm、英特尔、谷歌、微软、Mozilla 和 Fastly 等主要参与者。

Wasm 也非常适合以多租户方式运行代码,因为它内置了正确的安全原语。 由于它是在进程内启动但本身不是进程,因此它还提供了一种避免冷启动问题的方法,这是无服务器环境的典型问题。

Wasm 在以下领域越来越受欢迎:

• 在 Envoy 等网关的情况下提供数据过滤功能

• 策略引擎,例如开放策略代理

• Kubernetes 准入控制器

• Postgres 等具有支持 Wasm 的自定义扩展的数据库

Wasm 现在被视为云原生社区的前沿技术

云原生计算基金会的首席技术官 Chris Aniszczyk 表示,“任何具有扩展机制的项目都可能会利用 Wasm 来做到这一点。”

其前景和兴奋点在于便携性和速度的结合。

——Fintan Ryan,Gartner 高级分析师

与 JavaScript 相比,Wasm 资源开销低且启动时间加快,可以在内存、CPU 和存储资源受限的 IoT 设备上进行配置。

由于没有冷启动问题,可移植性和低资源消耗将使 WebAssembly 成为云和边缘无服务器部署的理想选择。

WebAssembly最初是作为基于浏览器的应用程序的沙箱技术(例如,在浏览器上运行图像处理、解码视频和音频),由于强大的沙箱功能和较低的开销,它现在已经进军服务器端技术。

Wasm 的安全功能使其非常适合防止缓冲区溢出和控制流完整性问题等安全漏洞。 Wasm 将代码和数据分开。 它有一个带类型检查的静态类型系统和一个非常结构化的控制流,旨在使编写安全编译的代码变得更容易,线性内存、全局变量和堆栈内存可以单独访问。 这些方面将在后面的章节中讨论 Wasm 如何提供简洁的机制来避免此类安全挑战。

在底层,Wasm 运行时是一个基于堆栈的虚拟机,通过从堆栈中推送和弹出数据来在 Wasm 字节码上运行。 最接近的比较是 JVM 的工作。 一个主要区别是 JVM 字节码不是通用的(即,只有 Kotlin 和 Scala 等编程语言可以编译为 Java 字节码)。但是,几乎所有编程语言(例如 C、C++、Rust、Golang 和 JavaScript)都可以编译为 Wasm 字节码。

Wasm 目前仅支持数字数据类型,尽管有人建议添加字符串、序列、记录、变体等引用类型,以使 Wasm 模块更容易与在其他运行时运行或以不同语言编写的模块进行交互。虽然这不是限制,但其他数据类型,例如字符串,仍然可以用这些数字类型来实现,只是这使得直接编写 Wasm 有点乏味。 Wasm 模块无权访问操作系统中的 API 和系统调用。

如果您希望它与模块外部的任何内容进行交互,则必须显式导入它,因此唯一可以执行的代码是打包为模块一部分的代码。

称为 WASI(WebAssembly 系统接口)的新规范促进了与操作系统调用的交互。 WASI 规范允许可互操作的 Wasm 代码,一旦 Wasm 编译器生成字节码,就可以将其移植到任何 Wasm 运行时(即 Lucet、Wasmer 和 Node.js 等运行时)。

云中的 Wasm

在浏览器中运行 Wasm 与在云或边缘应用程序(例如,在 IoT 设备上)上运行 Wasm 存在差异。 当在浏览器上运行 Wasm 时,操作系统的接口由浏览器代表 Wasm 模块处理。 对于服务器或边缘应用程序,托管 Wasm 模块的 Wasm 运行时必须促进这一点。 系统调用的类型类似于文件系统 I/O 或网络 I/O。

一种方法是让每个托管 Wasm 运行时实现如何代表 Wasm 模块促进系统调用。 这是迄今为止的方法,但这导致了可移植性问题,因为每个运行时都会公开不同的方法供 Wasm 模块使用以进行系统调用。 WASI 规范在 Wasm 社区中不断发展以提供标准化。 它是一组模块化的系统接口,看起来像一个抽象的操作系统,具有 I/O 等低级接口和密码学等高级接口,使 WebAssembly 代码保持可移植性。 这也提供了更好的安全性,因为可以实现细粒度的访问控制。 例如,某个 Wasm 模块只能访问某些文件,而不能访问整个文件系统。 这大大减少了源自特定 Wasm 模块的可能攻击面,即使它是恶意的。

许多运行时都支持在云和边缘运行基于 Wasm 的工作负载。 Node.js 是一个重要的参与者,其 V8 运行时支持通过在 JavaScript 代码中加载 Wasm 模块来执行它们。 字节码联盟有三个运行时。 两个(Wasmtime 和 Fastly 的 Lucet)最近合并,使用提前编译来优化边缘计算以减少延迟。 它是在 Wasmtime 之上重写的。 WAMR,即微运行时,适用于资源有限的嵌入式设备; 这仍然是一个单独的运行时。

还有其他运行时,例如 Wasmer 和 TeaVM(用于 Java 字节码到 Wasm)。 随着社区的发展,运行时数量的增加,关注这些运行时的性能方面变得很重要。 有一组基准测试可以衡量 Wasm 运行时性能的不同方面。

WebAssembly 用例

WebAssembly 有很多用例:

• 新建/多平台开发

• 无服务器开发

• 用 Wasm 编写的用于触发器的数据库插件

• 在 WebContainers 等浏览器中为 Node.js 等完整服务器提供服务

• 从仅限桌面的应用程序迁移到基于桌面和浏览器的应用程序(AutoCAD 和游戏)

• 渐进式网络应用程序

• 移动应用程序

还有许多其他用例。

0 阅读:0

查理谈科技

简介:感谢大家的关注