WebAssembly (通常縮寫為 Wasm) 是一種為網路瀏覽器設計的低階程式語言。它旨在提供一種比傳統的 JavaScript 更快、更高效的方式來執行程式碼,以彌補 JavaScript 在效能方面的不足。透過使用二進位制格式,WebAssembly 能夠提供比傳統 JavaScript 更快的解析和執行速度。
Wasm 擴充套件到雲原生領域
然而但隨著時間的發展,它的應用範圍已經擴充套件到了雲原生領域。相比於容器和虛擬機器,WebAssembly 具有以下優勢:
- 效能和安全:隨著雲原生生態系統的發展,大家對於高效能和安全的需求日益增長。WebAssembly 以其快速、安全、沙箱化的特點,成為了一個吸引人的選擇。
- 跨平臺特性:WebAssembly 的跨平臺特性使得它非常適合雲原生環境,因為它可以在任何支援 Wasm 執行時的環境中執行,與底層硬體或作業系統均無關。
- 輕量化:相比於傳統的虛擬機器和容器技術,Wasm 提供了更輕量級的解決方案,這對於需要快速擴充套件和縮放的雲原生應用尤為重要,例如函式計算場景。
- 微服務和邊緣計算:Wasm 適合被用於微服務架構和邊緣計算場景,因為它能夠提供快速的啟動時間和更高的資源利用效率。
隨著技術的成熟和社群的發展,已經有越來越多的工具和平臺被開發出來以支援在雲原生環境中使用 WebAssembly,runwasi 便是其中之一。它是一個 Containerd 外掛,用來將 Wasm 執行時整合到 Containerd 中,以支援使用 Containerd 來建立和管理 Wasm 應用。
本文將會給大家介紹如何在 Sealos 雲作業系統中快速整合 runwasi,並使用 runwasi 來執行 Wasm 應用。
⚠️ 注意:runwasi 目前還是 Alpha 版,不建議在生產環境中使用。
runwasi 介紹
先來看一眼 runwasi 騷氣的 Logo:
在理解 runwasi 之前,我們先來明確幾個概念:
WebAssembly (Wasm) 執行時
- WebAssembly 基礎:WebAssembly 提供了一個沙箱環境,允許在其中以接近原生效能執行預編譯的二進位制程式碼。這些程式碼模組獨立於平臺,能夠在任何支援 Wasm 的環境中執行。
- Wasm 執行時:這是一個軟體棧,用於載入、驗證、編譯,並最終執行 Wasm 二進位制檔案。例如,Wasmtime 或 Wasmer 就是這樣的執行時。
Containerd 架構
Containerd
是一個達到工業標準的容器執行時,負責容器的建立、啟動、停止和管理,它的架構被設計為模組化,可以透過外掛來擴充套件其功能。這包括快照外掛、執行時外掛等。runwasi 就是其中一個快照外掛。
runwasi 的工作原理
- 作為外掛:
runwasi
作為一個Containerd
快照外掛存在,使得 Wasm 應用能夠作為容器執行。 - 載入 Wasm 應用:當
Containerd
請求啟動一個容器時,runwasi
外掛負責載入 Wasm 應用。 - Wasm 執行時整合:
runwasi
使用一個 Wasm 執行時(如 Wasmtime)來執行 Wasm 應用。這意味著它會處理 Wasm 二進位制檔案的載入、驗證和執行。 - 容器化的 Wasm 應用:透過
runwasi
,Wasm 應用在Containerd
的管理下以類似於傳統容器應用的方式執行,但實際上是在 Wasm 執行時中執行。
Sealos 整合 runwasi
下面我們來演示如何在 Sealos 雲作業系統中整合 runwasi,步驟非常簡單,只需要一條命令即可。
Sealos 提供了 3 個不同的叢集映象:labring/containerd-shim-wasmtime、labring/containerd-shim-wasmedge 和 labring/containerd-shim-wasmer,分別對應三個不同的 Wasm 執行時:WasmEdge、Wasmtime 和 Wasmer。
以 Wasmtime 執行時為例,只需執行下面這條命令就可以將 runwasi 整合到 Sealos 叢集中:
$ sealos run docker.io/labring/containerd-shim-wasmtime:v0.3.0
然後使用 Rust 編寫一個 Wasm 應用:
// hello.rs
use std::thread::sleep;
fn main() {
loop {
sleep(std::time::Duration::from_secs(5));
println!("{}", "This is from a main function from a wasm module");
}
}
編譯並執行:
$ rustup target add wasm32-wasi
$ rustc quick-start.rs --target wasm32-wasi
$ wasmtime quick-start.wasm
This is from a main function from a wasm module
這個倉庫裡已經編譯好了 wasm 檔案:https://github.com/labring-actions/wasi-image/tree/main/applications/quick-start/main
你可以克隆該倉庫,進入 applications/quick-start/main
,然後執行以下命令構建 wasi 映象並推送到 Sealos 本地映象倉庫:
$ sealos build --platform "wasi/wasm" -t sealos.hub:5000/quick-start:latest .
$ sealos push sealos.hub:5000/quick-start:latest
編寫一個 Job 配置清單:
# wasm-demo.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: wasm-demo
spec:
template:
metadata:
labels:
app.kubernetes.io/name: wasm-demo
spec:
containers:
- name: wasm-demo
image: sealos.hub:5000/quick-start:latest
runtimeClassName: runwasi-wasmtime # 修改成對應的 runtime 名字
restartPolicy: Never
建立 Job:
$ kubectl apply -f wasm-demo.yaml
檢視 demo 日誌:
$ kubectl logs jobs/wasm
This is from a main function from a wasm module