本頁資訊旨在協助 Bazel 使用者編寫自訂建構作業和測試規則,以便瞭解在遠端執行作業環境下使用 Bazel 規則的需求。
遠端執行可讓 Bazel 在獨立的平台 (例如資料中心) 上執行動作。Bazel 會使用 gRPC 通訊協定執行遠端執行。您可以嘗試使用 bazel-buildfarm 遠端執行,這個開放原始碼專案旨在提供分散式遠端執行平台。
本頁面在提及不同環境類型或平台時,會使用下列術語:
- 主機平台:Bazel 所在的位置。
- 執行平台:Bazel 動作的執行位置。
- 「Target Platform」(目標平台):建構輸出內容 (和某些動作) 的執行位置。
總覽
為遠端執行作業設定 Bazel 建構作業時,您必須按照本頁說明的指示操作,確保建構作業在遠端執行時不會發生錯誤。這是因為遠端執行作業的性質所致,亦即:
隔離的建構動作。建構工具不會保留狀態,且依附元件無法外洩。
多種執行環境。本機建構設定不一定適合遠端執行環境。
本頁說明為遠端執行實作自訂 Bazel 建構及測試規則時可能發生的問題,以及如何避免這些問題。其中涵蓋下列主題:
透過工具鍊規則叫用建構工具
Bazel 工具鍊規則是一種設定提供者,可告知建構規則要使用哪些建構工具 (例如編譯器和連接器),以及如何使用規則建立者定義的參數來設定這些工具。工具鍊規則可讓建構和測試規則透過與遠端執行作業相容的可預測、預先設定方式叫用建構工具。例如,使用工具鍊規則,而不是透過 PATH
、JAVA_HOME
或其他未在遠端執行環境中設為相等 (或完全不會) 的本機變數叫用建構工具。
目前 Bazel 適用的工具鍊規則適用於 Scala、Rust 和 Go 的建構與測試規則,而新的工具鍊規則也正在支援其他語言與工具,例如 bash。如果規則使用的工具沒有工具鍊規則,請考慮建立工具鍊規則。
管理隱含依附元件
如果建構工具可以存取所有建構動作的依附元件,則遠端執行時,這些動作就會失敗,因為每個遠端建構動作會與其他遠端建構動作分開執行。部分建構工具會保留建構動作和存取依附元件,但未明確納入工具叫用的依附元件,這會導致遠端執行的建構動作失敗。
舉例來說,當 Bazel 指示有狀態編譯器在本機建構 foo 時,編譯器會保留 foo 建構輸出內容的參照。當 Bazel 指示編譯器建構取決於 foo 的 bar,而沒有明確指出 BUILD 檔案中的依附元件納入編譯器叫用時,只要同一個編譯器執行個體同時執行這兩個動作 (通常是在本機執行),動作就會成功執行。 不過,在遠端執行情境中,每個建構動作都會執行一個獨立的編譯器執行個體,因此編譯器狀態和 bar 在 foo 上的隱含依附元件將會遺失,且建構失敗。
為協助偵測並解決這些依附元件問題,Bazel 0.14.1 提供本機 Docker 沙箱,其中包含與遠端執行相同的依附元件限制。使用沙箱找出並解決與依附元件相關的建構錯誤,以便為遠端執行作業做好準備。詳情請參閱「使用 Docker Sandbox 排解 Bazel 遠端執行問題」。
管理平台依附的二進位檔
一般來說,在主機平台建構的二進位檔因依附元件不相符,而無法在任意遠端執行平台上安全執行。舉例來說,Bazel 提供的 SingleJar 二進位檔會以主機平台為目標。不過,如要進行遠端執行,則必須在建構程式碼的過程中一併編譯 SingleJar,以便指定遠端執行平台。(請參閱目標選取邏輯)。
請勿以原始碼傳送建構作業所需的建構工具二進位檔,除非您確定這些二進位檔會在執行平台中安全地執行。建議改用下列方法:
提供或外部參照工具的原始碼,以便為遠端執行平台建構工具。
如果工具鍊容器夠穩定,請將其預先安裝到遠端執行環境 (例如工具鍊容器) 中,並使用工具鍊規則在建構作業中執行該工具。
管理設定樣式的 WORKSPACE 規則
Bazel 的 WORKSPACE
規則可用於探測主機平台,以便取得建構作業所需的工具和程式庫。如果是本機建構作業,也會使用 Bazel 的執行平台。如果建構作業明確依附於本機建構工具和成果,如果遠端執行平台與主機平台不相同,則在遠端執行期間就會失敗。
WORKSPACE
規則執行的下列動作與遠端執行不相容:
建構二進位檔。如果使用
WORKSPACE
規則執行編譯動作,則會產生與遠端執行平台不相容的二進位檔。安裝
pip
套件。透過WORKSPACE
規則安裝的pip
套件需要在主機平台上預先安裝依附元件。專為主機平台打造的這類套件如果與主機平台不同,將與遠端執行平台不相容。與本機工具或構件的符號連結。若對透過
WORKSPACE
規則建立的主機平台安裝的工具或程式庫有符號連結,將會導致遠端執行平台上的建構作業失敗,因為 Bazel 無法找到這些符號。請改用標準建構動作建立符號連結,以便從 Bazel 的runfiles
樹狀結構存取符號連結的工具和程式庫。請勿使用repository_ctx.symlink
對外部存放區目錄以外的目標檔案符號連結。簡化主機平台。請避免在 Bazel
runfiles
樹狀結構外建立檔案、建立環境變數以及類似的動作,因為這些檔案可能會在遠端執行平台上出現非預期的行為。
您可以使用 Workspace 規則記錄找出潛在的非密封行為。
如果外部依附元件執行依附於主機平台的特定作業,您應按照以下方式在 WORKSPACE
和建構規則之間拆分這些作業:
平台檢查和依附元件列舉。這些作業可透過
WORKSPACE
規則安全地在本機執行,這些規則可以檢查已安裝哪些程式庫、下載必須建構的套件,以及準備編譯所需的構件。針對遠端執行,這些規則也必須支援使用預先檢查構件,提供通常在主機平台檢查期間取得的資訊。預先檢查的成果可讓 Bazel 描述依附元件,就像在本機上一樣。為此,請使用條件陳述式或--override_repository
標記。產生或編譯目標專屬構件和平台異動。這些作業必須透過一般建構規則執行。為外部依附元件產生目標專屬構件的動作必須在建構期間執行。
如要更輕鬆地為遠端執行產生預先檢查的成果,您可以使用 WORKSPACE
規則來輸出產生的檔案。您可以在每個新的執行環境中 (例如每個工具鍊容器內) 執行這些規則,然後查看原始碼存放區中遠端執行建構作業的輸出內容來參照。
舉例來說,針對 TensorFlow 的 cuda
和 python
規則,WORKSPACE
規則會產生下列 BUILD files
。針對本機執行作業,系統會使用檢查主機環境產生的檔案。針對遠端執行,環境變數上的條件陳述式可讓規則使用已檢查到存放區的檔案。
BUILD
檔案會宣告 genrules
可在本機和遠端執行,並執行先前透過 repository_ctx.symlink
完成的必要處理作業,如這裡所示。