使用 Docker Sandbox 解決 Bazel Remote Execution 的問題

回報問題 查看原始碼 夜間 7.2 7.1 7.0 6.5 6.4

在本機執行的 Bazel 建構作業在遠端執行時可能會失敗 不會影響本機版本的限制和要求。最常見的 請參閱為 Remote Execution 調整 Bazel 規則一文,瞭解這類失敗的原因。

本頁說明如何找出並解決 發生在遠端執行時,必須使用 Docker 沙箱功能 限制等同於遠端執行作業。這樣一來 不必使用遠端執行服務,即可對建構作業進行疑難排解。

Docker 沙箱功能會模仿遠端執行的限制 如下:

  • 建構動作在工具鍊容器中執行。您也可以使用相同的 工具鍊容器,以便在本機或透過服務遠端執行建構作業 支援容器化遠端執行

  • 沒有任何多餘的資料超出容器邊界。僅限明確 宣告的輸入和輸出會進入並離開容器,而且只有在 相關聯的建構動作已成功完成

  • 每個動作都會在新的容器中執行。全新的不重複容器 每個衍生的建構動作

您可以使用下列其中一種方法排解這些問題:

  • 原生疑難排解。透過這個方法 Bazel 及其建構動作會在本機電腦中原生執行。Docker 沙箱功能對建構作業的相關限制不等於遠端裝置 不過,此方法不會偵測本機工具、狀態和 資料外洩到建構作業中,導致遠端執行發生問題。

  • 排解 Docker 容器中的問題。 透過此方法,Bazel 及其建構動作會在 Docker 容器中執行 可偵測出來自於何處 除了對機器設下限制 和遠端執行的大小相同這個方法可以深入分析 自動建構。這個方法仍在實驗階段 並未受到正式支援

必要條件

開始排解問題前,請先完成以下步驟 (如果還未這個步驟):

  • 安裝 Docker 並設定執行所需的權限。
  • 安裝 Bazel 0.14.1 以上版本。較舊版本不支援 Docker 沙箱功能。
  • 新增 bazel-toolchains 存放區已固定為最新版本,並附加至建構作業的 WORKSPACE 檔案 ,詳情請參閱這篇文章
  • .bazelrc 檔案中新增標記以啟用這項功能。在 該檔案的根目錄 (如果不存在)。下方旗標 為參考範例請參閱最新功能 .bazelrc 找到 bazel-toolchains 存放區中的檔案,然後複製已定義的標記值 來檢查設定 docker-sandbox
# Docker Sandbox Mode
build:docker-sandbox --host_javabase=<...>
build:docker-sandbox --javabase=<...>
build:docker-sandbox --crosstool_top=<...>
build:docker-sandbox --experimental_docker_image=<...>
build:docker-sandbox --spawn_strategy=docker --strategy=Javac=docker --genrule_strategy=docker
build:docker-sandbox --define=EXECUTOR=remote
build:docker-sandbox --experimental_docker_verbose
build:docker-sandbox --experimental_enable_docker_sandbox

如果您的規則需要其他工具,請執行下列操作:

  1. 使用 Dockerfile 安裝工具,建立自訂 Docker 容器 和建構 映像檔會 部署於本機執行

  2. 將上述 --experimental_docker_image 標記的值替換為 自訂容器映像檔的名稱

原生疑難排解

這個方法會直接在本機執行 Bazel 及其所有建構動作 讓您在執行這項作業時 遠端執行。

不過,使用這個方法時,安裝於本機的工具、二進位檔和資料可能會外洩 放入建構中,特別是使用設定樣式的 WORKSPACE 規則時。 這類外洩情形會導致遠端執行發生問題。如要偵測,請排解 Docker 容器中的問題 除了原生疑難排解之外

步驟 1:執行建構作業

  1. --config=docker-sandbox 標記新增至執行的 Bazel 指令 建構。例如:

    bazel --bazelrc=.bazelrc build --config=docker-sandbox target
    
  2. 執行版本,然後等待建構完成。建構作業最多可執行四個 則作業速度會比平常慢。

您可能會遇到下列錯誤:

ERROR: 'docker' is an invalid value for docker spawn strategy.

否則,請使用 --experimental_docker_verbose 旗標再次執行建構。 此標記會啟用詳細錯誤訊息。這項錯誤通常是由 安裝錯誤或缺少執行 目前使用者帳戶。請參閱 Docker 說明文件 瞭解詳情如果問題仍未解決,請直接跳到在 Docker 容器中排解問題

步驟 2:解決偵測到的問題

以下是最常見的問題及解決方法。

排解 Docker 容器中的問題

透過這個方法,Bazel 會在主機 Docker 容器中執行,並且執行 Bazel 的建構作業 動作會在 Docker 產生的個別工具鍊容器中執行 沙箱功能。沙箱會為每項 建構動作,每個工具鍊容器只會執行一個動作。

此方法可對主機安裝的工具進行更精細的控制 環境。將建構作業的執行作業與執行作業的執行作業區隔開來 建構動作,並盡量減少安裝的工具 您的建構作業對於本機執行環境是否有任何依附元件。

步驟 1:建構容器

  1. 建立 Dockerfile 以建立 Docker 容器並安裝 Bazel 簡單好用的建構工具

    FROM debian:stretch
    
    RUN apt-get update && apt-get install -y apt-transport-https curl software-properties-common git gcc gnupg2 g++ openjdk-8-jdk-headless python-dev zip wget vim
    
    RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
    
    RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
    
    RUN apt-get update && apt-get install -y docker-ce
    
    RUN wget https://releases.bazel.build/<latest Bazel version>/release/bazel-<latest Bazel version>-installer-linux-x86_64.sh -O ./bazel-installer.sh && chmod 755 ./bazel-installer.sh
    
    RUN ./bazel-installer.sh
    
  2. 將容器建構為 bazel_container

    docker build -t bazel_container - < Dockerfile
    

步驟 2:啟動容器

使用以下顯示的指令啟動 Docker 容器。在指令中 以您要建立的主機上的原始碼取代路徑。

docker run -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /tmp:/tmp \
  -v your source code directory:/src \
  -w /src \
  bazel_container \
  /bin/bash

這個指令會以根層級執行容器、對應 Docker 通訊端,並進行掛接 /tmp 目錄。這可讓 Bazel 產生其他 Docker 容器 使用 /tmp 下的目錄,與這些容器共用檔案。您的來源 您可以在容器內的 /src 取得程式碼。

這個指令會刻意從符合下列條件的 debian:stretch 基礎容器中啟動: 所含的二進位檔與做為以下項目的 rbe-ubuntu16-04 容器不相容 工具鍊容器如果本機環境的二進位檔外洩到 會導致建構錯誤。

步驟 3:測試容器

從 Docker 容器中執行下列指令來進行測試:

docker ps
bazel version

步驟 4:執行版本

如下所示執行建構。輸出使用者是根目錄,因此能對應至 可透過主機內部的相同絕對路徑存取的目錄 Bazel 會在該容器中執行,也就是 Docker 產生的工具鍊容器 執行 Bazel 建構動作的沙箱功能,以及從本機執行 執行主機和動作容器的機器

bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target

步驟 5:解決偵測到的問題

您可以按照下列步驟解決建構失敗問題:

  • 如果建構失敗並顯示「磁碟空間不足」此時,您可以提高 使用旗標 --memory=XX 啟動主機容器,其中 XX 是分配的磁碟空間 (以 GB 為單位)這項功能仍在實驗階段,可能會 會導致無法預期的行為

  • 在分析或載入階段期間,如果建構作業失敗, 您在 WORKSPACE 檔案中宣告的建構規則與 遠端執行。請參閱為 Remote Execution 調整 Bazel 規則一節 找出可能原因和解決方法

  • 如因其他原因導致建構失敗,請參閱步驟 2:解決偵測到的問題中的疑難排解步驟。