1 回答

TA貢獻1873條經驗 獲得超9個贊
首先是一個快速免責聲明,我沒有使用這個 binfmt 技巧來運行 go 腳本。我想它可能會起作用,但我只是go run
在我想即時運行某些東西時使用。
這里面有很多東西要解開。容器隔離在隔離環境中運行具有共享內核的應用程序。命名空間、cgroup 和安全設置旨在防止一個容器影響其他容器或主機。
為什么這很重要?因為/proc/sys/fs/binfmt_misc
正在與內核交互,并且將更改推送到內核將被視為容器逃逸,因為您正在修改底層主機。
接下來要介紹的是構建映像與運行容器。當您使用 Dockerfile 構建映像時,您正在定義映像文件系統和一些元數據(標簽、入口點、公開端口等)。每個 RUN 命令根據上一步的結果在臨時容器內執行該命令,當命令完成時,它會捕獲對容器文件系統的更改。當您掛載另一個文件系統時,這不會更改底層容器文件系統,因此即使可以,掛載命令在映像構建期間也是一個 noop。
因此,如果這是可能的,您需要在容器內而不是在構建期間執行此操作,該容器將需要獲得特權,因為執行諸如掛載文件系統和修改 /proc 之類的操作需要通常不授予容器的訪問權限,并且您將在此過程中修改主機內核。您需要讓容器入口點運行掛載并注冊 binfmt_misc 條目,并弄清楚如果該條目已經設置/注冊了該怎么辦,但可能是另一個容器中的不同目錄。
順便說一句,在處理 binfmt_misc 和容器時,F 標志非常重要,盡管在您的用例中,重要的是您沒有它。通常,您需要 F 標志,以便在主機文件系統上找到二進制文件,而不是在容器文件系統命名空間中搜索。binfmt_misc 和容器的典型用例是將主機配置為能夠運行不同架構的容器,例如 Docker Desktop 可以運行 amd64、arm64 和許多其他使用它的平臺。
最后,如果您想一次性運行容器以將 go 命令作為腳本運行,我會跳過 binfmt misc 技巧并創建一個執行 a 的入口點go run
。但是,如果您將容器用于長時間運行的進程,您希望定期將 go 文件作為腳本運行,則需要在容器中執行此操作,并且作為能夠逃逸到主機的特權容器.
- 1 回答
- 0 關注
- 133 瀏覽
添加回答
舉報