針對遠端執行調整 Bazel 規則

回報問題 查看來源 Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

本頁適用於編寫自訂建構和測試規則的 Bazel 使用者,他們想瞭解遠端執行環境中 Bazel 規則的相關規定。

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

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

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

總覽

為 Bazel 建構作業設定遠端執行時,請務必遵循本頁面所述的準則,確保建構作業能順利遠端執行。這是因為遠端執行的性質,也就是:

  • 獨立建構動作。建構工具不會保留狀態,且依附元件無法在建構工具之間外洩。

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

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

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

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

目前 Bazel 建構和測試規則的工具鍊規則適用於 ScalaRustGo,其他語言和工具 (例如 bash) 的新工具鍊規則也正在開發中。如果規則使用的工具沒有工具鍊規則,請考慮建立工具鍊規則

管理隱含依附元件

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

舉例來說,當 Bazel 指示有狀態的編譯器在本機建構 foo 時,編譯器會保留對 foo 建構輸出的參照。接著,當 Bazel 指示編譯器建構依附於 foobar 時,只要在 BUILD 檔案中明確指出該依附元件,並納入編譯器呼叫中,動作就會順利執行 (通常是本機執行)。不過,由於在遠端執行情境中,每個建構動作都會執行個別的編譯器例項,因此編譯器狀態和 barfoo 的隱含依附元件會遺失,建構作業也會失敗。

為協助偵測及排除這些依附元件問題,Bazel 0.14.1 提供本機 Docker 沙箱,依附元件的限制與遠端執行作業相同。使用沙箱找出並解決與依附元件相關的建構錯誤,為遠端執行建構作業做好準備。詳情請參閱「Troubleshooting Bazel Remote Execution with Docker Sandbox」。

管理依附平台的二進位檔

一般來說,由於依附元件可能不相符,在主機平台上建構的二進位檔無法在任意遠端執行平台上安全執行。舉例來說,Bazel 提供的 SingleJar 二進位檔會以主機平台為目標。不過,如果是遠端執行,SingleJar 必須在建構程式碼的過程中編譯,才能以遠端執行平台為目標。(請參閱目標選取邏輯)。

除非確定建構工具的二進位檔可在執行平台安全執行,否則請勿將建構工具的二進位檔與來源程式碼一併出貨。建議改用下列任一方法:

  • 運送或外部參照工具的原始碼,以便為遠端執行平台建構工具。

  • 如果工具夠穩定,請預先將工具安裝到遠端執行環境 (例如工具鍊容器),並使用工具鍊規則在建構作業中執行工具。

管理設定樣式的工作區規則

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 完成的必要處理作業,如這裡所示。