博客 / 詳情

返回

WebAssembly容器調研

“容器已成為新常態,WebAssembly 是未來。” —— CNCF 2022 年年度調查主要發現

1. 什麼是WebAssembly?

wasm是一種緊湊的二進制指令格式,由W3C管理。它是 40 多種編程語言(如 C/C++、JavaScript、Go 和 Rust)的可移植編譯目標,每一種目標彙編語言(x86、ARM)都依賴於特定的機器結構,但wasm不依賴於具體的物理機器,換句話説,wasm 是一種運行在基於堆棧的虛擬機上的字節碼格式。

基於堆棧的虛擬機:不同於寄存器架構,指令集和程序執行使用寄存器存儲操作數和中間結果,該架構使用堆棧來完成。JIT編譯器可以在把字節碼翻譯成機器碼時,將部分堆棧操作轉為寄存器操作。

字節碼:介於源碼和機器碼之間,機器碼直接與硬件相關,但字節碼與硬件平台無關。

wasm最初為了提升瀏覽器性能而設計,如今,藉助 WASI 和多種wasm運行時,wasm模塊可以在服務器端高效運行。開發者可以使用C、RUST等語言開發,通過前端編譯器編譯為 wasm 字節碼,瀏覽器端通過JS膠合代碼將其轉換成機器彙編代碼,服務器端wasm程序由 wasm運行時執行,然後打包以在不同的架構上運行,例如 Arm 和 x86。過程如下圖所示:

image.png

可用前端編譯器如下所示:

image.png

2.WebAssembly的發展歷程

重要事件如圖所示:

時間線2.png
具體的:

2015年-WebAssembly首次提出

2017年6月-WebAssembly 1.0 正式發佈

​ wasm的核心規範發佈,並在主要瀏覽器中得到支持。

2019年4月-WASI(WebAssembly System Interface)發佈

​ WASI使wasm模塊可以在非瀏覽器環境中運行。它為wasm模塊提供了訪問底層操作系統功能(如文件系統、網絡I/O)的能力。為wasm在服務器端、嵌入式設備等非瀏覽器環境中的應用鋪平道路。

2019年11月-Fastly 宣佈 WebAssembly Edge Compute 支持

​ fastly 宣佈其邊緣計算平台支持 WebAssembly,使開發者能夠將 Wasm 部署到全球的邊緣節點。推動了 Wasm 在邊緣計算中的應用。

2019年8月 - WAMR首次發佈

​ WAMR (WebAssembly Micro Runtime)是一個輕量級 WebAssembly 運行時,專為資源受限的設備設計。這是 WebAssembly 在嵌入式設備和物聯網領域應用的一個關鍵進展。

2020年4月-Krustlet 項目發佈

​ Krustlet是K8s中的一個節點實現,它使用wasm而非傳統的Linux容器。Krustlet允許k8s調度和管理wasm模塊,推動了wasm與容器技術的融合。

2020年9月-wasmtime 1.0 發佈

​ wasmtime達到1.0版本,標誌着其穩定性和成熟度,成為服務器端wasm應用的常用運行時。

2020年9月- WebAssembly OCI Image Spec發佈

​ 定義如何將wasm模塊打包為OCI(Open Container Initiative)鏡像。這一規範為wasm模塊的構建、拉取、發佈和執行提供了標準化的方式,使wasm可以像容器鏡像一樣被處理和管理

2020年 - WAMR 集成進 Zephyr RTOS

WAMR 被集成到 Zephyr 實時操作系統(RTOS)中,開發者能夠在嵌入式設備上運行 WebAssembly 模塊。這個里程碑標誌着 WebAssembly 在嵌入式設備上更廣泛的適用性。

2021年3月-wasmEdge 發佈

​ wasmEdge是一個專為邊緣計算和物聯網設計的輕量級wasm運行時,優化了 Wasm 在資源受限環境中的性能,推動了wasm容器生態。

2021年-WAGI(WebAssembly Gateway Interface) 發佈

​ WAGI 提供微服務網關接口,允許開發者使用wasm處理http請求。使用的接口是CGI。

2022年10月-Docker 實驗性支持 WebAssembly
​ 此舉將 Wasm 融入到現有的容器化工作流中。

2023年4月-Docker宣佈支持4個wasm運行時

​ docker宣佈支持的wasm運行時總數達到4個,包括wasmeedge,spin、slight和wasmtime,它們都基於runwasi庫。

2023年7月 - WasmEdge 引入 AI 加速功能

​ WasmEdge 推出對 AI 加速的支持,針對邊緣計算場景進行了優化,允許在邊緣設備上運行 AI 模型。使其能夠運行機器學習推理任務。

2023年10月-wasmCloud1.0發佈

​ wasmCloud 引入了 waPC 協議,旨在簡化 WebAssembly guest 和 host 之間的安全通信,進一步優化wasm在邊緣設備上的應用。

截至目前,wasm生態全景圖如下所示:

image.png
wasm全景圖鏈接:https://landscape.cncf.io/?group=wasm

3.wasm安全性

wasm生態安全性可以從兩個維度看待:

  • Host 安全性 ,在運行時環境能有效保護主機系統免受惡意 wasm 代碼的侵害。
  • 二進制安全性,內置故障隔離機制防止利用其他良性wasm代碼作惡。

wasm模塊通過以下幾個特性來提高安全性:

  • 沙箱模型:wasm 運行在一個隔離的執行環境中,限制了它對宿主系統資源(如文件系統、網絡等)的直接訪問。wasm沙箱可以安全地在與其他代碼相同的進程中運行,這與軟件故障隔離(SFI)非常相似。wasm 模塊不能任意執行本地代碼,也不能直接訪問主機系統的內存。
  • 顯式權限控制:通過接口如WASI或者宿主 API,開發者可以明確控制 Wasm 模塊能夠訪問哪些資源,從而避免未經授權的資源訪問。WASI的安全模型與傳統操作系統安全模型非常不同,而且還在持續演進中。比如字節碼聯盟提出了 nanoprocess來解決應用模塊間的安全協同和信任傳遞。
  • 類型安全:wasm 運行時會執行嚴格的類型檢查和邊界檢查,以防止常見的安全漏洞,如緩衝區溢出等。

下圖是wasm沙箱的架構及特性:

圖片

wasm 提供一個沙盒化的線性內存,線性內存是一個連續的、字節可尋址的內存範圍,從偏移量 0 一直延伸到不同的內存大小。每個wasm 實例都有一個專門指定的默認線性內存。編譯器會創建分別用於調用棧、堆(動態分配內存)和靜態數據的區域用於存儲函數作用域、全局或動態生命週期的數據。

wasm 模塊可以讀取與 Wasm 模塊鏈接的符號信息,包括:導出/ 導入/ 入口點。導出符號是指 Host 可以訪問的 wasm 模塊組件,包括:函數、全局變量、內存、表。wasm 模塊導出函數、全局變量都是類型安全的。wasm 表用於交換引用信息。

wasm不允許跳轉到任意指令點。wasm 模塊中指令被分組為塊(block),分為三類塊:常規塊、條件塊、循環塊。塊內不能訪問塊外中的操作數。程序需要通過一個局部變量填充該值,以在塊內傳輸該值。Wasm會根據塊的結果類型來驗證棧狀態。

4.wasm運行時

任何能夠執行wasm文件的程序或軟件,都可以被稱為“wasm運行時(Webassembly Runtime)”,wasm的執行環境可以是瀏覽器(如Chrome、Firefox)、服務器端運行時(如wasmtime、wasmer)、或嵌入式設備上的輕量級運行時(如WAMR、 wasmEdge)。這些宿主環境提供了必要的系統接口(如文件系統訪問、網絡I/O等),是wasm模塊與外界交互的橋樑。wasm運行時提供了為wasm應用量身定製的安全、內存高效和沙盒執行環境。

從高層次上講,wasm 運行時對字節碼的執行分為三個主要步驟:

  1. 解碼:處理模塊並將其轉換為內部表示
  2. 驗證:檢查解碼後的模塊是否有效
  3. 執行:安裝並調用有效模塊

圖片

wasm 運行時可分為四個部分,包括 wasm 編譯器、wasm 解釋器、運行時環境以及與底層環境的交互部分(WASI 實現或 JS 膠合代碼)。wasm 運行時還提供運行時環境,支持分配內存、執行堆棧操作、報告執行錯誤信息和其他功能。WASI是wasm運行時和底層操作系統的中間層,WASI統一了來自不同操作系統的系統調用。wasm 二進制指令的執行方式有兩種:解釋或編譯。提供兩種類型的wasm編譯器:即時(JIT)編譯器和提前(AoT)編譯器。結構如下圖所示:

image.png

主流的wasm運行時: WasmEdge 、 Wasmtime/lucet 、 Wamr、 WAVM 、Wasmer、 wasm3 、 Lunatic 、 Wasmer 和 V8 。獨立的wasm運行時,如WAMR、wasmtime和wasmEdge,可以在用高級語言編寫的程序中作為庫調用,以允許開發人員在任何可能的情況下使用各種語言執行wasm二進制文件。

特別的,在嵌入式設備上,目前支持Vxworks等實時操作系統的wasm運行時有:WAMR、WasmEdge 、Wasmer、。

常用wasm運行時基本情況如下圖所示:
image.png

wasm運行時發展面臨的主要問題之一是工具支持,工具鏈不豐富。預計在新的一年裏會有更多更友好的工具出現,比如AOT/JIT調試工具、多線程調試支持、性能監測工具、內存監測工具等。

“到2030年,WebAssembly 運行時將取代基於容器的運行時。” ——DevOps創始人

5.wasm容器化

“如果 2008 年就有 wasm+WASI,我們就不需要創建 Docker 了。” ——Docker創始人

容器:運行在宿主機上的進程,通過 Namespace(命名空間) 和 Cgroup(控制組) 技術進行隔離和限制,和主機共享內核。

圖片

5.1容器運行時

容器高級運行時:負責 CRI 的實現,管理低層容器運行時,負責容器的生命週期,包括創建、啓動、停止、銷燬等。

容器低級運行時:負責 OCI 實現,直接與操作系統內核交互,真正操作容器。兩層的執行關係如下圖所示:

CRI(Container Runtime Interface)是kubenetes等管理平台用來管理不同的容器運行時的特定接口標準。

OCI(Open Container Initiative)涉及所有與容器相關的接口標準化。

圖片

容器鏡像可以由任何符合 OCI 標準的容器運行時啓動,例如:

  • crun:用 C 編寫的高性能輕量級容器運行時
  • runc:用 Go 編寫的廣泛使用的容器運行時
  • youki:用 Rust 編寫的與 OCI 兼容的容器運行時實現

最初的 Docker是從管理到運行的完整容器系統。現在的 Docker 將運行時功能下放給了 containerd,管理容器集羣功能則交給k8s等專業的容器編排工具。Docker目前只作為容器引擎,負責構建、管理和運行容器。

5.2 wasm模塊與容器的區別

wasm模塊與傳統容器的底層邏輯並不相同,但都提供了隔離且啓動速度塊。

  • Linux 容器旨在提供操作系統級的沙盒環境。依賴host OS內核提供沙盒環境。
  • wasm在沙盒中執行字節碼,無論底層硬件如何都可以運行,天然提供內存安全和隔離性。適合跑在資源受限的環境中。

這兩種技術不是替代性,而是互補的。開發人員可以選擇將代碼編譯並運行在容器中,或直接編譯為wasm程序,在wasm運行時上運行。

5.3 wasm模塊容器化

有兩種方法可以將 Wasm 應用程序作為“容器”進行管理(下圖已標出):

image.png

相關組件解釋:

ContainerD-Shim 是一個獨立的進程,存在於每個容器實例中,介於高級容器運行時和低級容器運行時中間,為高級容器運行時(這裏是containerD)管理不同的運行時提供標準化接口。ContainerD-Shim與低級容器運行時使用 gRPC 協議通信,調用低級運行時時使用的接口依賴於所對接的低級運行時,不同的低級運行時有不同的接口和機制。

與容器生態相比,目前沒有一個官方的、像 CRI 那樣的標準接口來規範 wasm 運行時,每個 wasm 運行時都有自己獨立的 API 。

方法一(如圖:融合1)—— 在OCI運行時中作為容器鏡像

傳統容器主要運行 Linux 鏡像,隨着 wasm 的發展,wasm程序模塊正在逐步獲得容器運行時的支持,wasm 模塊(或 wasm 鏡像)可以在某些容器運行時上運行,containerd和 crun 等運行時已經增加對 wasm 的支持。

image.png

使用 OCI 運行時如 crun 。crun 根據鏡像的目標操作系統和 CPU 平台檢測 OCI 鏡像是 wasm 還是 Linux。如果鏡像的目標是 wasi/wasm,crun 將繞過 Linux 容器設置過程,只使用 WasmEdge 來運行它。

Wasm 容器的啓動速度通常比 Linux 容器更快,而且可移植性更好。例如,Linux 上“最小”的 Python 容器鏡像超過 40MB,而對應的Wasm容器鏡像不到7MB。

方法二(如圖:融合2)—— wasm運行時和OCI運行時並行

wasm運行時跳過低級容器運行時,直接被高級容器運行時管理,即wasm運行時和低級容器運行時為同一層。docker已經推出了對wasm運行時支持的預覽版,如圖所示:

image.png

當高級容器運行時 containerD 接收到鏡像時,它會檢查鏡像的目標平台,如果鏡像是 wasi/wasm,它會路由到 runwasi 執行,如果鏡像是 x86 或 arm,它會路由到 runc。

5.4 wasm沙箱容器化實例——Kuasar

沙箱容器的出現:傳統容器與宿主機系統共享內核的容器,存在着巨大安全隱患。沙箱容器將進程限制在一個封閉的沙箱環境中,防止對容器及其他系統的破壞。

2023年3月,containerd 在其 v1.7.0 版本中發佈了 Sandbox API 特性,該特性提供了一套管理沙箱的API,它的出現使得容器和沙箱的概念解耦,“容器歸容器,沙箱歸沙箱”,創建 Pod 就是創建沙箱,不再需要藉助 pasue 容器。

2023年12月,Kuasar正式成為首個多沙箱容器運行時開源項目。Kuasar基於 Rust 語言實現,屬於低階容器運行時,和高階容器運行 containerd 交互,Kuasar 主要由兩個模塊組成:

image.png

其中,Wasm Sandboxer,即WebAssembly 沙箱定義了一套新的指令集和虛擬機。所有程序必須編譯成 Wasm 指令集才能在 Wasm 虛擬機中運行,因此對應用程序有很高的要求。wasm-sandboxer 和 wasm-task 為一個獨立的進程,每當需要在沙箱中啓動容器時,wasm-task 將 fork 一個新進程,啓動一個新的 WasmEdge runtime,並在其中運行 Wasm 代碼。

6.wasm容器與容器編排

Kubernetes 可以屏蔽底層設施的差異性,可以在同一個 K8s 集羣中包含 x86、ARM 等不同體系架構的節點,可以支持 Linux,Windows 等不同的操作系統。wasm 容器可以作為工作負載被調度並運行在這些容器化平台上,可以通過 Docker、containerd 和 K8s等現有容器工具進行無縫管理。

實例:krustlet項目

krustlet(kubernetes rust kubelet),一個用rust語言實現的開源項目,krustlet是kubelet的一種實現,目標是管理和運行wasm模塊,而不是傳統的容器。在agent節點上實現與k8s API的通信,並管理該節點上容器的生命週期。

krustlet並不是要替代傳統的kubelet,而是為k8s集羣提供了一種新的工作負載類型支持,使wasm模塊可以集成到k8s等編排平台中,擴充了k8s生態系統。

7. WebAssembly應用案例

7.1 工業製造應用實例

工業製造中,各工藝階段運行在不同操作系統中,wasm用於運行各種的工業應用,可以按照時延、資源等需要在嵌入式設備、工業 PC 和車間/工廠服務器之間靈活部署與調度。

圖片

圖片

  • 銀線平台(Silverline Platform):德國博世公司,可以將大部分的工業應用程序編譯成 WebAssembly,使用 WebAssembly Micro Runtime(WAMR)開源項目作為運行引擎,提供一個統一的管理調度平台。
  • Digital Twin Assembly (dtasm):由西門子開發的一個支持數字孿生、模塊式組裝的開源項目,也使用了 WebAssembly 模塊作為仿真程序的目標格式。

7.2 工業軟件應用實例

瀏覽器內的 WebAssembly 技術已經讓一些傳統的工業軟件可以遷移到瀏覽器上。

  • 三維家:2017年國內設計公司“三維家”自研基於 WebAssembly 的圖形引擎,融入大數據、AI 人工智能等前沿技術。
  • AUTOCAD :2021年Autodesk 公司將傳統的 AUTOCAD 軟件遷移值瀏覽器。
  • Photoshop : 2021年Adobe公司把經典的軟件 Photoshop 搬移到了瀏覽器上面。

7.3 xiaomi vela:小米公司支持wasm容器的自研系統

小米的工程師在 2021 wasm Open Day 活動中報告了《wasm & WAMR 在 AIOT 中的實踐》,介紹了小米 Vela 物聯網操作系統中對 WebAssembly 的支持與應用。

平台介紹

關於Vela(2023 年開源):Vela是小米公司基於開源實時操作系統NuttX打造的物聯網嵌入式軟件平台。vela追求和linux的源碼兼容性,代碼結構、目錄結構、標準組件都向Linux靠近。linux上的應用只需要在vela os上重新編譯就能在vela os上跑起來。

Vela OS系統架構:

image.png

關於NuttX(開源):一個在IoT、分佈式嵌入式系統、無人機系統中廣泛使用的RTOS,第一個版本由 Gregory Nutt 於 2007 年發佈。支持 8 位到64位的處理器,支持risc-v,arm,mips,x86等主流芯片平台,按照POSIX和 ANSI 標準進行設計,支持MMU和MPU,支持多線程和進程。

wasm項目

xiaomi-vela-posix-wasm-runtime 基於Vela平台的POSIX和Wasm的多語言運行時

功能點

• 以Vela平台為基礎,使用NuttX作為目標OS,使用WAMR作為Wasm虛擬機。英特爾的開源項目WebAssembly Micro Runtime(WAMR)介紹如下:

image.png

• 引擎內部優化,複用 AOT 文件中的字符串、函數指針等固定不變的資源,針對系統接口,實現輕量級的 wasi 兼容庫

• 支持C、C++、Rust和Assembly Script

技術優勢

image.png

7.4 Waft:阿里巴巴公司基於wasm的AIoT應用框架

2021年wasm Open Day 活動中阿里巴巴工程師在題為《Waft:基於 WebAssembly 的 AIoT 應用框架實踐》的彙報中介紹了基於 WebAssembly 設計的物聯網應用開發框架,提供更加平滑的用户體驗。

發展歷程

image.png

系統架構

Waft ( WebAssembly Framework for Things )是一個面向 AIoT 原子化服務的輕量應用開發框架,核心基於WAMR。Waft的核心模塊都是使用C/C++開發的,可便於做多平台的移植。

image.png

Waft容器的三個核心模塊為 Framework、Engine和 Native Services (基礎服務):

  • Framework: 作為終端的大腦,職責包括:端雲協同、包管理、場景管理、資源管理等等。
  • Engine: 頁面渲染與邏輯執行的核心模塊,包括:Runtime 虛擬機、DOM Parser 以及頁面渲染與繪製。
  • Native Services (基礎服務):提供多種高性能的原子化服務,減輕業務開發的難度與工作量。

image.png

waft選擇WAMR的原因:

image.png

應用實例:天貓精靈

硬件

image.png

軟件

image.png

如果目標系統的wasm運行時支持 標準WASI,則可以在非目標系統上將高級語言程序編譯成符合 WASI 標準的 Wasm 模塊,並直接在目標平台上的 wasm運行時中運行。

image.png

<img src="https://segmentfault.com/img/bVcPtf3/view" alt="preview" style="zoom:80%;" />

運行時需要在不同平台上實現WASI標準的適配層。例如,__wasi_path_open這樣的接口可能在不同操作系統上分別調用不同的文件系統API,而WASI的作用是將這些調用抽象成統一的接口。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.