針對遠端執行調整 Bazel 規則

回報問題 查看原始碼 Nightly · 8.0 . 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

本頁面適用於撰寫自訂建構和測試規則的 Bazel 使用者,他們想瞭解遠端執行作業中 Bazel 規則的要求。

遠端執行功能可讓 Bazel 在其他平台 (例如資料中心) 上執行動作。Bazel 會使用 gRPC 通訊協定進行遠端執行。您可以使用 bazel-buildfarm 試用遠端執行功能,這是一項開放原始碼專案,旨在提供分散式遠端執行平台。

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

  • 主機平台:Bazel 執行的位置。
  • 執行平台:Bazel 動作執行的位置。
  • 目標平台:建構輸出內容 (和部分動作) 執行的位置。

總覽

設定 Bazel 建構作業以便遠端執行時,您必須遵循本頁面所述的規範,確保建構作業在遠端執行時不會發生錯誤。這是因為遠端執行的特性,也就是:

  • 隔離建構動作。建構工具不會保留狀態,且相依項目不會在工具之間外洩。

  • 多樣化的執行環境:本機建構設定不一定適合遠端執行環境。

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

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

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

目前已針對 ScalaRustGo 建立 Bazel 建構和測試規則的工具鍊規則,並且正在為 bash 等其他語言和工具建立新的工具鍊規則。如果規則使用的工具沒有工具鍊規則,請考慮建立工具鍊規則

管理隱含依附元件

如果建構工具可跨建構動作存取依附元件,這些動作在遠端執行時會失敗,因為每個遠端建構動作都會單獨執行。部分建構工具會保留建構動作的狀態,並存取未明確納入工具叫用作業的依附元件,這會導致遠端執行的建構動作失敗。

舉例來說,當 Bazel 指示具狀態編譯器在本機建構 foo 時,編譯器會保留對 foo 建構輸出的參照。接著,當 Bazel 指示編譯器建構依附於 foobar 時,如果未在 BUILD 檔案中明確指出該依附元件,以便納入編譯器叫用,只要同一個編譯器例項為這兩個動作執行,動作就會成功執行 (本機執行的情況通常如此)。不過,由於在遠端執行情境中,每個建構動作都會執行個別的編譯器例項,因此編譯器狀態和 barfoo 的隱含依附元件會遺失,建構作業也會失敗。

為了協助偵測及排除這些依附元件問題,Bazel 0.14.1 提供本機 Docker 沙箱,其對依附元件的限制與遠端執行作業相同。使用沙箱找出並解決依附元件相關的建構錯誤,為遠端執行作業做好準備。詳情請參閱「使用 Docker 沙箱排解 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 執行的必要處理作業,如此處所示。