作者:Asen Alexandrov,Wasm Labs 工程师
文中的我们均指作者或 Wasm Labs。由于文章内容翔实、篇幅较长我们将分成上下两篇分享,上篇将注重在概念阐释,如 Wasm 是什么,Wasm 与 Docker 的关系是什么。下篇文章将更具实践性,将以 PHP 为例带领大家实践 Docker + Wasm。
最近,Docker 宣布与 WasmEdge[3] 合作支持 WebAssembly[4]。
本文将解释什么是 WebAssembly(Wasm),为什么它与 Docker 生态相关,并提供一些实践示例供大家尝试。我们假设你已经熟悉 Docker 工具。我们将使用我们在 PHP 的 WebAssembly 端口[5]上做的工作来演示如何构建 PHP 解释器,将其打包为 OCI 镜像的一部分,并使用 Docker 运行它。
请注意,本文专注动手经验,而不是讨论技术细节。
WebAssembly 是什么?为什么选它?
本节是对 WebAssembly 的基本介绍。已经熟悉 Wasm 的小伙伴,可以快速重温一下,下篇文章将介绍更多实践。
什么是 WebAssembly?
WebAssembly 是一种定义二进制指令格式的开放标准,它支持从不同的源语言创建可移植的二进制可执行文件。这些二进制文件可以在各种环境中运行。它起源于 Web,并得到各大主流浏览器的支持。
Wasm 如何在浏览器中工作?
浏览器引擎集成了一个 Wasm 虚拟机,通常称为 Wasm 运行时,可以运行 Wasm 二进制指令。编译器工具链(如 Emscripten)可以将源代码编译为 Wasm 目标。这允许将现有的应用程序移植到浏览器,并直接与在客户端 Web 应用程序中运行的 JS 代码通信。
这些技术能让传统的桌面应用程序在浏览器中运行。现在它们可以在任何装了浏览器的设备上运行。一些著名的例子包括 Google Earth[6] 和用于计算机视觉的 Open CV[7]库。
Wasm 如何在服务器上运行?
除了浏览器,也有可以在浏览器之外运行的 Wasm 运行时,包括 Linux、Windows 和 macOS 等传统操作系统。因为无法依赖可用的 JavaScript 引擎,所以他们使用不同的接口与外界通信,例如 WASI(WebAssembly 系统接口[8])。这些运行时允许 Wasm 应用程序以与 POSIX 类似(但不完全相同)的方式与其 host 系统交互。WASI SDK 和 wasi-libc 等项目帮助人们将现有的兼容 POSIX 的应用程序编译为 WebAssembly。
你只需将应用程序编译成 Wasm 模块一次,然后这个同样的二进制文件就可以在任何地方运行。
Wasm 有什么了不起的地方?
下面这些特性让 Wasm 在浏览器大放异彩,也使得它用在服务端开发颇具优势:
开放——它是业界广泛采用的标准。与过去的浏览器争夺战相反,各大公司正积极合作,实现 WASI 和 WebAssembly 应用程序的标准化。
快速——它可以通过大多数运行时的 JIT/AOT 能力提供类似原生的速度。与启动 VM 或启动容器不同的是,它没有冷启动。
安全——默认情况下,Wasm 运行时是沙箱化的,允许安全访问内存。基于能力的模型确保 Wasm 应用程序只能访问得到明确允许的内容。软件供应链更加安全。
可移植——几个主要的 Wasm 运行时支持大多数 CPU(x86、ARM、RISC-V)和大多数操作系统,包括 Linux、Windows、macOS、Android、ESXi,甚至非 Posix 操作系统。
高效——最小的内存占用和最低的 CPU 门槛就能运行 Wasm 应用程序。
支持多语言——40 多种编程语言可以编译成 Wasm,有现代的、不断改进的工具链。
服务器平台发展的下一步是什么?
也许你已经看过 Solomon Hykes (Docker的创始人之一)这句话[9]:
如果在2008年已经有了 WASM + WASI,我们根本不需要创建 Docker。Wasm 就有这么重要。服务端的 WebAssembly 是计算的未来。
事实上,WASM+WASI 似乎的确是服务端软件基础设施发展的下一步。
最早,我们有物理硬件可以使用。我们会给机房里每个服务器精心安装操作系统和应用程序,并一一维护。
然后随着 VMware 开创的 VM 的采用,一切变得更容易了。人们可以跨硬件机器复制、克隆和移动虚拟机。但这仍然需要在 VM 中安装操作系统和应用程序。
随后出现了由 Docker 推广的容器,这使得在最小打包的上下文下运行应用程序配置变得更加容易,而不会影响主机操作系统上的任何其他应用程序。但是,仍然需要分发与其运行时和必要的库捆绑在一起的应用程序。安全边界由 Linux 内核提供。
现在有了 WebAssembly。它的技术特性和可移植性使得分发应用程序成为可能,无需 ship 操作系统级别的依赖项,并且可以在严格的安全约束下运行。
鉴于所有这些,开发者通常将 WebAssembly 视为容器的“继承者”,以及基础设施部署的自然而然的下一步。
然而,另一种看待 WebAssembly 的方式是将其作为 Docker 工具的另一个“后端”选择。可以使用相同的命令行工具和工作流,替代 Linux 容器,使用基于 WebAssembly 的容器等同等的东西来实现。本文的其余部分探讨了这个概念,这就是标题所说的“没有容器的 Docker”。
Wasm 如何结合 Docker 运行?
Docker Desktop 现在加入了对 WebAssembly 的支持。它是通过 containerd shim 实现的,该 shim 可以使用名为 WasmEdge[10] 的 Wasm 运行时来运行 Wasm 应用程序。这意味着,现在可以在 WasmEdge 运行时(模拟容器)中运行 Wasm 应用程序,而不是用典型的 Windows 或 Linux 容器运行容器镜像中二进制文件的单独进程。
因此,容器镜像不需要包含正在运行的应用程序的操作系统或运行时上下文——单个 Wasm 二进制文件就足够了。
这在 Docker 的 Wasm 技术预览文章[11]中有详细解释。
WasmEdge 是什么?
WasmEdge[12] 是一个高性能的 WebAssembly 运行时:
是开源的,属于 CNCF[13]。
支持所有主要的 CPU 架构(x86、ARM、RISC-V)。
支持所有主要操作系统(Linux、Windows、macOS)以及其他操作系统,例如 seL4 RTOS、Android。
针对云原生和边缘应用程序进行了优化。
可扩展并支持标准和新兴技术
使用 Tensorflow、OpenVINO、PyTorch 进行人工智能推理
Tokio 的异步网络。支持微服务、数据库客户端、消息队列等。
与容器生态、Docker 和 Kubernetes 无缝集成(如本文所示!)
解释型语言呢?
到目前为止,我们只提到了 C 和 Rust 等编译语言可以编译为 WebAssembly。对于 Python、Ruby 和 PHP 等解释型语言,方法有所不同:它们的解释器是用 C 语言编写的,可以编译为 WebAssembly。然后这个解释器编译成的 Wasm 可以用来执行源代码文件,通常以 .py、.rb、.php 等结尾。一旦编译为 Wasm,任何带有 Wasm 运行时的平台都将能够运行这些解释型语言,即使实际的解释器从未为该平台原生编译过。
明天我们将介绍,如何将 PHP 解释器编译 Wasm ,并打包成 OCI 镜像,并使用内置了 WasmEdge 的 Docker Desktop 运行这个 OCI 镜像,我们也将介绍传统容器与 Wasm 容器的不同之处。
[1]
Wasm Labs @ VMware OCTO: https://wasmlabs.dev/
[2]
Docker+WebAssembly 的演讲: https://youtu.be/yo30oF1Gflo?t=7361
[3]
WasmEdge: https://wasmedge.org/
[4]
WebAssembly: https://docs.docker.com/desktop/wasm/
[5]
WebAssembly 端口: https://wasmlabs.dev/articles/php-wasm32-wasi-port/
[6]
Google Earth: https://earth.google.com/
[7]
Open CV: https://opencv.org/
[8]
WebAssembly 系统接口: https://wasi.dev/
[9]
这句话: https://twitter.com/solomonstre/status/1111004913222324225
[10]
WasmEdge: https://github.com/WasmEdge/Wasmedge
[11]
Wasm 技术预览文章: https://www.docker.com/blog/docker-wasm-technical-preview/
[12]
WasmEdge: https://github.com/WasmEdge/Wasmedge
[13]
CNCF: https://cncf.io/
编辑:黄飞
评论
查看更多