本文會介紹 Bazel 中的沙箱機制和沙箱功能偵錯。 環境。
「沙箱」是一種權限限制策略,可將程序 或系統中的資源至於 Bazel,這代表系統會限制 系統存取權。
Bazel 的檔案系統沙箱會在僅工作目錄中執行處理程序 包含已知的輸入內容,因此編譯器和其他工具不會看到來源 使用者不得存取這些檔案,除非他們知道這些檔案的絕對路徑。
沙箱機制無法以任何方式隱藏主機環境。程序可自由地 存取檔案系統中的所有檔案。但在支援使用者的平台上 命名空間,程序無法修改工作目錄以外的任何檔案。 這可確保建構圖表沒有隱藏依附元件 會影響版本的可重現性
具體來說,Bazel 會為每個動作建構 execroot/
目錄。
做為動作在執行時間execroot/
包含動作的所有輸入檔案,且可做為任何
輸出內容Bazel 接著會使用作業系統提供的技術
Linux 和 macOS 上的 sandbox-exec
容器,以便限制在
execroot/
。
採用沙箱機制的原因
如未宣告動作沙箱,Bazel 無法得知工具是否使用未宣告的 (在該檔案的依附元件中,沒有明確列出的檔案) 動作)。當其中一個未宣告的輸入檔案變更時,Bazel 仍會 認為建構是最新版本,不會重新建立動作。這可以 進而產生錯誤的漸進式建構作業
若是以不正確的方式重複使用快取項目,將會在遠端快取期間發生問題。A 罩杯 如果共用快取中有錯誤的快取項目,會影響專案的每位開發人員, 並清除整個遠端快取並非可行的解決方案。
沙箱機制會模仿遠端執行的行為 (如果建構能順利運作) 也支援遠端執行藉由 遠端執行上傳所有必要檔案 (包括本機工具),您可以 相較於 2018 年, 不必在每次安裝時 來試用新的編譯器,或變更現有工具。
採用的沙箱策略
利用
策略標記。使用 sandboxed
策略會讓 Bazel 從下列一種沙箱實作項目中選擇一種
偏好作業系統專屬的沙盒,而不是普通的通用沙箱。
永久工作站會在您通過測試時,在一般沙箱中執行
--worker_sandboxing
旗標。
local
(又稱為 standalone
) 策略並非執行任何類型的沙箱作業。
它只會執行動作的指令列,並將工作目錄設定為
工作區的執行者
processwrapper-sandbox
是不需要任何測試機制的沙箱策略
「進階」功能 - 立即適用於任何現成的 POSIX 系統,這項服務
會建立沙箱目錄,包含指向原始版本的符號連結
來源檔案,使用工作目錄集執行動作的指令列
移至這個目錄 (而非 execroot),再移動已知的輸出構件
並刪除沙箱。這樣一來,
操作,導致您誤以為
釋放的 execroot 以及未知的輸出檔案
linux-sandbox
更進一步,奠基於
processwrapper-sandbox
。與 Docker 的功能類似
Linux 命名空間 (User、掛接、PID、網路和 IPC 命名空間) 以便隔離
動作。也就是說,這麼做會將整個檔案系統設為唯讀,
,因此該動作不會意外修改
主機檔案系統這可避免錯誤測試等情況意外觸發
-rf 是您的 $HOME 目錄。或者,您也可以防止動作
存取網路linux-sandbox
會使用 PID 命名空間防止動作
偵測其他處理程序及穩定終止所有程序 (即使是 Daemon 也不例外)
延伸至結尾。
darwin-sandbox
很類似,但適用於 macOS。使用 Apple 的「sandbox-exec
」工具
執行的實作效果大致與 Linux 沙箱相同
linux-sandbox
和 darwin-sandbox
都不適用於「巢狀」
因作業平台所提供機制的限制
有些人會將 Cloud Storage 視為檔案系統
但實際上不是由於 Docker 也會使用 Linux 命名空間來發揮容器神奇效果
無法在 Docker 容器中執行 linux-sandbox
,除非您使用
docker run --privileged
。在 macOS 上,您無法在 sandbox-exec
已加上沙箱的處理程序因此,在這類情況下
會自動改回使用 processwrapper-sandbox
這樣會發生建構錯誤,例如避免不小心使用
執行策略較不嚴格的執行策略 — 明確修改執行清單
Bazel 嘗試使用的策略 (例如 bazel build
--spawn_strategy=worker,linux-sandbox
)。
動態執行通常需要在本機執行時採用沙箱機制。如要停用,
傳遞 --experimental_local_lockfree_output
標記。動態執行,不發出任何通知
沙箱的永久工作站。
採用沙箱機制的缺點
沙箱作業需要額外的設定及拆解成本。這筆費用有多大 實際速度取決於許多因素,包括構建形狀 也能確保主機 OS 的效能對 Linux 來說,採用沙箱機制的建構程序 因此運作速度會減慢一些設定
--reuse_sandbox_directories
可 可減少設定及成本沙箱機制實際上會有效停用工具的所有快取。你可以 使用永久工作站即可減少這種情況, 以及效能低弱的沙箱保證成本
「多重工作站」需要明確的工作站支援 沙箱模式不支援多工沙箱的工作站將 動態執行下的單面工作站,可能會耗用額外的記憶體。
偵錯
請按照下列策略對沙箱機制問題進行偵錯。
已停用的命名空間
在某些平台上,例如
Google Kubernetes Engine
叢集節點或 Debian,使用者命名空間會預設為停用,這是因為
安全疑慮。如果 /proc/sys/kernel/unprivileged_userns_clone
檔案
且包含 0,您可以執行下列指令來啟用使用者的命名空間:
sudo sysctl kernel.unprivileged_userns_clone=1
規則執行失敗
由於系統設定,沙箱可能會無法執行規則。如果看到
類似 namespace-sandbox.c:633: execvp(argv[0], argv): No such file or
directory
的訊息,請嘗試使用 --strategy=Genrule=local
停用沙箱:
genrules,--spawn_strategy=local
則適用於其他規則。
建構失敗的詳細偵錯資訊
如果建構失敗,請使用 --verbose_failures
和 --sandbox_debug
Bazel 會顯示建構失敗時的確切執行指令,包括
用來設定沙箱
錯誤訊息範例:
ERROR: path/to/your/project/BUILD:1:1: compilation of rule
'//path/to/your/project:all' failed:
Sandboxed execution failed, which may be legitimate (such as a compiler error),
or due to missing dependencies. To enter the sandbox environment for easier
debugging, run the following command in parentheses. On command failure, a bash
shell running inside the sandbox will then automatically be spawned
namespace-sandbox failed: error executing command
(cd /some/path && \
exec env - \
LANG=en_US \
PATH=/some/path/bin:/bin:/usr/bin \
PYTHONPATH=/usr/local/some/path \
/some/path/namespace-sandbox @/sandbox/root/path/this-sandbox-name.params --
/some/path/to/your/some-compiler --some-params some-target)
您現在可以檢查產生的沙箱目錄,並查看 Bazel 有哪些檔案 並再次執行指令,看看其運作方式。
請注意,使用 Bazel 並不會刪除沙箱目錄
--sandbox_debug
。除非您正在主動偵錯,否則應停用
--sandbox_debug
,因為它會隨著時間填滿磁碟。