翻译自科技红人 Nigel Poulton 的博文 👉 https://nigelpoulton.com/getting-started-with-docker-and-wasm/
轻松体验 Docker + Wasm ——编写一个应用,将其编译为 Wasm,将其打包为 OCI 镜像,将之存储在 Docker Hub 中,再使用 Docker 运行。
Docker 最近发布了支持 WebAssembly 的 Docker Desktop 技术预览版[1]。他们还宣布了 Docker Hub 对 WebAssembly artifacts[2] 的支持。
因为我觉得 WebAssembly 非常有意思,所以我想我应该把它们都试一试,然后写一篇文章来帮助其他同样想体验 Docker + Wasm 的人。
WebAssembly (又称 Wasm) 创建非常小、非常快的二进制文件,这些二进制文件在任何地方的安全沙箱中执行,只要有一个 WebAssembly Runtime。说实话……它们比容器更小、更快、更安全,而且更加跨平台—— 这话是我说的,我承认我是容器的超级粉丝。
关于体积大小的例子……Michael Yuan 最近分享了有着完整的 HTTP 服务器 + MySQL 客户端“app服务器”[3],只有 2MB!其他人也分享了 Size 更小的 Example。
无论如何,WebAssembly 正成为云原生领域的一件大事[4],而 Docker 也想在此有一席之地。
我将一步一步带领你编写一个 hello world Wasm 应用,将其打包为 OCI 镜像以及推送到 Docker Hub,并使用 Docker 运行它。如果你想跟我一起做,你需要做下面两个准备,但如果你只是想阅读,那也没关系。
可以从此页面[5]上的链接安装 Docker Desktop 技术预览版,并从这里[6]安装 Rust。Docker Desktop 和 Rust 安装后,我们将完成以下步骤:
下文的所有任务都将使用命令行执行。你会需要 Docker Desktop 和 Rust 。
运行下面的 rustup
命令,安装 wasm32-wasi target。这样 Rust 就可以将源代码编译成 Wasm 二进制文件。
rustup target add wasm32-wasi
如果你运行 rustup target list
,发现 wasm32-wasi (installed) 出现在列表里, Rust 就配置好了,你就可以创建这个app了。
运行以下命令来构建一个简单的 Rust app。它将创建一个简单的 Hello World 应用 hello-docker/src/main.rs
。
cargo new hello-docker
检查 hello-docker/src/main.rs
文件并更改打印到屏幕上的文字。我更改为打印“Hello, Docker Hub!” 了。如下。
fn main() {
println!("Hello, Docker Hub!");
}
此时,Rust app 已编写好,并可以编译为 Wasm 二进制文件了。
运行以下 cargo
命令将 Rust app 为 wasm32-wasi 二进制文件。这将创建一个 Wasm 字节码二进制文件,它可以在任何有 WebAssembly 运行时的系统上运行。
cargo
命令作为 Rust 的一部分已经安装。它还知道在哪里可以找到源代码以及如何将其编译为 Wasm 二进制文件。
cargo build --target wasm32-wasi --release
该命令将 hello-docker.wasm
Wasm 二进制文件输出到 hello-docker/target/wasm32-wasi/release
文件夹中。
我们将在接下来的步骤中借助 Docker 执行它。然而,在此之前,我们会将其构建到 OCI 镜像中,以便它可以存储在 Docker Hub 中并由 Docker 执行。
Docker 可以将 Wasm 模块打包到 OCI 镜像中( Docker 镜像的别名)。
现在执行此操作的方式感觉有点过时,我希望将来会有所改变。但是,你从一个临时基础镜像开始,复制 Wasm 模块,并将程序设置为作为 Wasm 二进制文件执行。
以下的 Dockerfile
对此进行了描述。在你的当前目录中创建它(你应该在你的 hello-docker
目录中)。
FROM scratch
COPY ./target/wasm32-wasi/release/hello-docker.wasm /hello-docker.wasm
ENTRYPOINT [ "hello-docker.wasm" ]
创建 Dockerfile[7] 后,运行以下命令来构建镜像。该命令假定你与 Dockerfile 位于同一目录中。
docker buildx build --platform wasi/wasm32 -t docker-wasm:0.1 .
--platform wasi/wasm32
flag 将镜像的目标操作系统设置为 wasi 并将目标架构设置为 wasm32。-t docker-wasm:0.1
标记/命名镜像“docker-wasm:0.1”,最后的句点告诉 Docker 使用当前目录中的 Dockerfile。
运行以下命令以验证新镜像是否存在。
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker-wasm 0.1 6b43e0bdf164 2 mins 501kB
此时 Wasm app 被打包在了一个 OCI 镜像。
这是一个可选步骤。如果你不打算使用 Docker Hub,请跳过。但是,如果执行此步骤,则需要一个 Docker ID[8]。它们是免费的,如果想认真学习和使用 Docker,它们就很重要。
运行以下命令以使用你自己的 Docker ID 标记镜像,以便你可以将其推送到自己的 Docker Hub 存储库。我的 Docker ID 是 nigelpoulton,所以我将运行下面的命令。
docker image tag docker-wasm:0.1 nigelpoulton/docker-wasm:0.1
使用标记有你的 Docker ID 的镜像,运行以下命令将其推送到 Docker Hub。请记住替换成自己的 Docker ID。我第一次尝试时失败了,我不得不执行手动 docker login
并再次运行命令。
docker image push nigelpoulton/docker-wasm:0.1
6b43e0bdf164: Pushed
33b9d7fa88a0: Pushed
4c601df9af6e: Pushed
0.1: digest: sha256:6b43...31f8, size: 526
此时 Wasm 应用被打包为 OCI 镜像并托管在 Docker Hub 上。注意 OS/ARCH
和 SIZE
字段。
在撰写本文时,你需要 Docker Desktop 的技术预览版才能完成此步骤。你可以在这篇文章[9]中找到下载链接。
运行以下命令告诉 Docker 运行打包在 OCI 镜像中的 Wasm app。为了可读性,它是一个打包在多行上的单个命令。
docker container run --rm --name=dockerwasm \
--runtime=io.containerd.wasmedge.v1 \
--platform=wasi/wasm32 \
nigelpoulton/docker-wasm:0.1
flag 是 Docker 如何告诉 containerd[10] 使用 runwasi containerd shim[11] ,它使用 WasmEdge[12] 运行打包在镜像中 Wasm 模块。
输出如下。
Hello, Docker Hub!
恭喜。你成功使用 Docker 构建、共享和运行了 Wasm app!
现在还是非常早期的阶段,写作本文时(2022 年 11 月),有些内容也许会过时。实现细节会有变化,一些 CLI flag 也会改变。例如,--platform=wasi/wasm32
已经计划更改为 wasi/wasm
。
然而,方向很明确,并且,开发者们能轻松用熟悉的 Docker 工具和技能创建 WebAssembly app,这意义重大。
我也确信这只是 Docker 和 Wasm 宏伟前景的很小一步!
Docker Desktop 技术预览版: https://www.docker.com/blog/docker-wasm-technical-preview/
[2]Docker Hub 对 WebAssembly artifacts: https://www.docker.com/blog/announcing-docker-hub-oci-artifacts-support/
[3]分享了有着完整的 HTTP 服务器 + MySQL 客户端“app服务器”: https://github.com/second-state/microservice-rust-mysql
[4]云原生领域的一件大事: https://nigelpoulton.com/webassembly-the-future-of-cloud-computing/
[5]此页面: https://www.docker.com/blog/docker-wasm-technical-preview/
[6]这里: https://www.rust-lang.org/tools/install
[7]Dockerfile: https://docs.docker.com/engine/reference/builder/
[8]Docker ID: https://hub.docker.com/signup
[9]这篇文章: https://www.docker.com/blog/docker-wasm-technical-preview/
[10]containerd: https://containerd.io/
[11]runwasi containerd shim: https://github.com/second-state/runwasi
[12]WasmEdge: https://wasmedge.org/
关于 WasmEdge
WasmEdge 是轻量级、安全、高性能、符合 OCI 标准的 WebAssembly Runtime。目前是 CNCF 沙箱项目。WasmEdge 被应用在 SaaS、云原生,service mesh、边缘计算、边缘云等领域。