快速上手 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 運行它。如果你想跟我一起做,你需要做下面兩個準備,但如果你只是想閱讀,那也沒關係。
-
Docker Desktop
-
Rust 編程語言
可以從此頁面 [5] 上的鏈接安裝 Docker Desktop 技術預覽版,並從這裏 [6] 安裝 Rust。Docker Desktop 和 Rust 安裝後,我們將完成以下步驟:
-
配置 Rust 將代碼編譯成 Wasm
-
編寫 app
-
將 app 編譯成 Wasm 二進制文件
-
將 app 打包成 OCI 鏡像
-
將鏡像推送到 Docker Hub
-
使用 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/ARCH
和 SIZE
字段。
使用 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