快速上手 Docker 最新 WebAssembly 技術預覽版

翻譯自科技紅人 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 也想在此有一席之地。

體驗 Docker 和 Wasm

我將一步一步帶領你編寫一個 hello world Wasm 應用,將其打包爲 OCI 鏡像以及推送到 Docker Hub,並使用 Docker 運行它。如果你想跟我一起做,你需要做下面兩個準備,但如果你只是想閱讀,那也沒關係。

可以從此頁面 [5] 上的鏈接安裝 Docker Desktop 技術預覽版,並從這裏 [6] 安裝 Rust。Docker Desktop 和 Rust 安裝後,我們將完成以下步驟:

  1. 配置 Rust 將代碼編譯成 Wasm

  2. 編寫 app

  3. 將 app 編譯成 Wasm 二進制文件

  4. 將 app 打包成 OCI 鏡像

  5. 將鏡像推送到 Docker Hub

  6. 使用 Docker 運行 Wasm app

下文的所有任務都將使用命令行執行。你會需要 Docker Desktop 和 Rust 。

配置 Rust 將代碼編譯成 Wasm

運行下面的 rustup 命令,安裝 wasm32-wasi target。這樣 Rust 就可以將源代碼編譯成 Wasm 二進制文件。

rustup target add wasm32-wasi

如果你運行 rustup target list ,發現 wasm32-wasi (installed) 出現在列表裏, Rust 就配置好了,你就可以創建這個 app 了。

寫 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 二進制文件了。

將 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 執行。

將 Wasm  app 構建到 OCI 鏡像中

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 鏡像。

將 Wasm 應用推送到 Docker Hub

這是一個可選步驟。如果你不打算使用 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/ARCHSIZE 字段。

使用 Docker 運行 Wasm app

在撰寫本文時,你需要 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 宏偉前景的很小一步!

參考資料

[1] 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、邊緣計算、邊緣雲等領域。

GitHub:https://github.com/WasmEdge/WasmEdge

官網:https://wasmedge.org/

Discord羣:**https://discord.gg/WCXUEBNV

文檔:https://wasmedge.org/book/en

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Z-GVl7ywdyiwUO4OVWVkeQ