寫Go的人容易有個錯覺:代碼能跨平臺編譯,程序就能到處跑。我搞了個迷你Docker運行時之后才發現——太天真了。
事情是這樣的。我用Go寫了個玩具級容器運行時,支持run、ps、logs、stop這些基礎命令。Linux上跑得挺順,切換到macOS編譯,也沒報錯。但一運行就傻眼:容器根本起不來。
![]()
問題不在Go,在操作系統。容器運行時依賴的是Linux內核特性——namespace隔離、cgroup v2資源控制、mount掛載隔離、veth虛擬網橋、iptables NAT規則。macOS內核是XNU,不是Linux,這些底層機制一個都對不上。
這就引出了第二個問題:macOS用戶怎么玩Linux容器?
我試了Lima。簡單說,它在macOS上啟動一個Linux虛擬機,然后把你的命令透傳進去執行。我的"迷你Docker"實際跑在Lima的Linux環境里,macOS這邊只是個入口。架構不復雜,但踩坑不少。
第一個教訓是區分"語言可移植"和"運行時可移植"。Go編譯成macOS二進制沒問題,但程序發起的syscall如果目標系統不支持,照樣掛。容器運行時本質是操作系統編程,不是純應用層代碼。
第二個教訓關于設計邊界。Docker Desktop在macOS上也是類似套路——背后藏了個Linux VM。但Docker把細節包得很干凈,用戶無感知。我自己實現時,每個環節都暴露在外:rootfs怎么準備、namespace怎么創建、網絡棧怎么搭,全得手動捋一遍。
這讓我重新理解Docker那行簡單命令背后的工作量。docker run alpine echo hello背后藏著鏡像解析、文件系統層疊、cgroups配置、日志管道、元數據管理、清理邏輯……官方文檔說Docker是"開發、交付、運行應用的開源平臺",自己造一遍輪子才知道這描述有多精簡。
最后跑了個簡單benchmark:同樣的容器操作,原生Linux vs Lima虛擬機里的Linux,啟動延遲差了大約15-20%。不算離譜,但敏感場景得心里有數。
這個項目不是為了替代Docker,是為了看清Docker的底褲。現在我知道底褲長什么樣了——也明白為什么macOS跑容器總得有個Linux墊著。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.