Go 將會支持裸機環境運行?
眾所周知,我們平時在寫 Go 應用程序時會先在本地環境開發,更大規模的企業會配發云環境。以此確保開發環境的效率,以及與部署環境的對齊。
部署環境需要特定的系統(Windows、Linux 等)似乎也成為了常見的共識。但其實在其他業務場景下也有不需要系統的訴求。
今天分享給大家的是 Go 針對裸機環境的新支持場景考慮。
新提案:增加裸機環境支持
提案背景
該提案《proposal: all: add bare metal support[1]》由 @Andrea Barisani 提出:
圖片
核心提議的內容是:引入一個新的 GOOS
目標值,例如 GOOS=none
(或現有的 GOOS=tamago
),允許 Go 應用程序在沒有底層操作系統支持的環境中運行,即所謂 “裸機” 運行模式。
這相當于做到了以下事項:
- 在沒有 Linux、Windows、macOS 等 OS 系統下,Go 應用程序也可以運行;
- Go 程序通過定義一組與底層硬件相關的函數,由 Go runtime 與外部驅動(也是 Go 實現)共同支持運行;
- 不依賴操作系統 syscall,完全在 runtime 和硬件之間運行。
摘 TamaGo 項目果子
可能有了解的同學一看,這表示是個大需求。畢竟以前 Go 一直都是支持帶環境的,沒有支持過裸機運行環境。開發工作量和涉及的影響面也未免太多了。
實際上這個提案是個摘果子的活,開源項目 TamaGo[2] 已經面向該需求已經經歷了多年開發。
目前具備一定的成果和成熟度:
- Go 標準庫兼容性良好,通過了大部分分發測試;
- 跨平臺支持完善:支持 amd64、arm、riscv64;
- 網絡棧通過注入 SocketFunc,可自定義虛擬網絡,甚至用于 js/wasip1;
- 支持用戶態執行(以 Go app 形式運行在沙箱環境中);
- 不再局限于 ARM,擴展到了 KVM 環境的 microVM,如 Firecracker、Cloud Hypervisor;
- 變更對 Go 官方發行版幾乎無侵入性(硬件驅動與構建系統保持外部化)。
可能存在的問題
社區反饋中,Google 內 Go 團隊成員 @Michael Pratt 對 Go 裸機運行(bare metal Go)感到很興奮。
也指出了以下幾點主要的兼容性挑戰:
- 問題 1:為 runtime 提供穩定的 API
- 問題 2:可用于實現 runtime API 的語言子集
問題 1:為 runtime 提供穩定的 API
- Go 的 兼容性承諾(Go 1 Compatibility Promise) 要求 runtime 依賴的 API 是長期穩定的;
- 當前提案中定義的 tamago runtime API 大致可行,但 go:linkname 機制需要更好的替代;
- 社區中也有人希望類似 API 能用于在最小化 WASM 運行時上運行 Go(如不支持 WASI 的環境),因此該 API 也應適用于 GOOS=none GOARCH=wasm。
問題 2:可用于實現 runtime API 的語言子集
- Go runtime 本身用的是一套“不完全定義”的 Go 子集,具有一定特殊性;
- 在標準編譯器下,某些微小的變化(例如啟發式加了一個內存分配)可能會
- 導致在不可分配位置出錯,但目前因為 runtime 是官方源碼,可以一起調整;
- 一旦開啟
GOOS=none
,任何runtime
的變動都不能破壞對已有裸機實現的兼容,因此:可能需要定義一套“穩定、安全”的 Go 語言子集,用于實現裸機所需的這些底層 API; - 這是一個很大的工作量。
對 Go 的發展意義和價值
- 使 Go 成為裸機開發語言:無需 C 或匯編,完整 Go 開發體驗;
- 構建最小化系統:比如可信執行環境(TEE)、引導加載器(如 go-boot);
- 沙箱與虛擬化創新:可用于構建 Soft Isolation VM、serverless 運行時;
- Go runtime 的可插拔性增強:提升多平臺抽象能力;
總結
從本文分析的結果來看,如果 Go 支持裸機環境,將會進一步提高其在新領域的優勢和實踐的機會。
但是結合 Go 團隊維護成員的結論來看,將裸機支持合入 master 分支前仍然存在的兩個關鍵工程難題:分別是:
- 如何為裸機提供一個長期維護、穩定的運行時接口(API);
- 如何保障這些接口的實現不會因 Go 語言或編譯器變更而“突然失效”。
這些問題都需要通盤考慮并做出一些基本的解決方案。雖然很希望 Go 可以進一步擴大輻射范圍,但可能我們還是需要再等等。
參考資料
[1] proposal: all: add bare metal support: https://github.com/golang/go/issues/73608
[2] TamaGo: https://github.com/usbarmory/tamago