針對遠端執行調整 Bazel 規則

本頁資訊旨在協助 Bazel 使用者編寫自訂建構作業和測試規則,以便瞭解在遠端執行作業環境下使用 Bazel 規則的需求。

遠端執行可讓 Bazel 在獨立的平台 (例如資料中心) 上執行動作。Bazel 會使用 gRPC 通訊協定執行遠端執行。您可以嘗試使用 bazel-buildfarm 遠端執行,這個開放原始碼專案旨在提供分散式遠端執行平台。

本頁面在提及不同環境類型或平台時,會使用下列術語:

  • 主機平台:Bazel 所在的位置。
  • 執行平台:Bazel 動作的執行位置。
  • 「Target Platform」(目標平台):建構輸出內容 (和某些動作) 的執行位置。

總覽

為遠端執行作業設定 Bazel 建構作業時,您必須按照本頁說明的指示操作,確保建構作業在遠端執行時不會發生錯誤。這是因為遠端執行作業的性質所致,亦即:

  • 隔離的建構動作。建構工具不會保留狀態,且依附元件無法外洩。

  • 多種執行環境。本機建構設定不一定適合遠端執行環境。

本頁說明為遠端執行實作自訂 Bazel 建構及測試規則時可能發生的問題,以及如何避免這些問題。其中涵蓋下列主題:

透過工具鍊規則叫用建構工具

Bazel 工具鍊規則是一種設定提供者,可告知建構規則要使用哪些建構工具 (例如編譯器和連接器),以及如何使用規則建立者定義的參數來設定這些工具。工具鍊規則可讓建構和測試規則透過與遠端執行作業相容的可預測、預先設定方式叫用建構工具。例如,使用工具鍊規則,而不是透過 PATHJAVA_HOME 或其他未在遠端執行環境中設為相等 (或完全不會) 的本機變數叫用建構工具。

目前 Bazel 適用的工具鍊規則適用於 ScalaRustGo 的建構與測試規則,而新的工具鍊規則也正在支援其他語言與工具,例如 bash。如果規則使用的工具沒有工具鍊規則,請考慮建立工具鍊規則

管理隱含依附元件

如果建構工具可以存取所有建構動作的依附元件,則遠端執行時,這些動作就會失敗,因為每個遠端建構動作會與其他遠端建構動作分開執行。部分建構工具會保留建構動作和存取依附元件,但未明確納入工具叫用的依附元件,這會導致遠端執行的建構動作失敗。

舉例來說,當 Bazel 指示有狀態編譯器在本機建構 foo 時,編譯器會保留 foo 建構輸出內容的參照。當 Bazel 指示編譯器建構取決於 foobar,而沒有明確指出 BUILD 檔案中的依附元件納入編譯器叫用時,只要同一個編譯器執行個體同時執行這兩個動作 (通常是在本機執行),動作就會成功執行。 不過,在遠端執行情境中,每個建構動作都會執行一個獨立的編譯器執行個體,因此編譯器狀態和 barfoo 上的隱含依附元件將會遺失,且建構失敗。

為協助偵測並解決這些依附元件問題,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 的 cudapython 規則,WORKSPACE 規則會產生下列 BUILD files。針對本機執行作業,系統會使用檢查主機環境產生的檔案。針對遠端執行,環境變數上的條件陳述式可讓規則使用已檢查到存放區的檔案。

BUILD 檔案會宣告 genrules 可在本機和遠端執行,並執行先前透過 repository_ctx.symlink 完成的必要處理作業,如這裡所示。