由於限制和要求不會影響本機建構作業,因此在本機建構成功的 Bazel 建構作業,從遠端執行時可能會失敗。如要瞭解這類失敗最常見的原因,請參閱「為遠端執行作業調整 Bazel 規則」。
本頁說明如何使用 Docker 沙箱功能,找出並解決遠端執行作業最常見的問題。Docker 沙箱功能會對建構作業施加限制,與遠端執行作業相同。這樣一來,您就能對建構作業進行疑難排解,而不需使用遠端執行服務。
Docker 沙箱功能會模擬遠端執行的限制,如下所示:
建構動作會在工具鍊容器中執行。您可以透過支援容器化遠端執行的服務,使用相同的工具鍊容器在本機和遠端執行建構作業。
沒有多餘資料跨越容器邊界。只有明確宣告的輸入和輸出內容會進入和離開容器,而且必須在相關聯的建構動作成功完成後才會發生。
每個動作都會在新的容器中執行。系統會為每個產生的建構動作建立新的專屬容器。
您可以透過下列任一方法排解這些問題:
原生疑難排解。使用這種方法時,Bazel 和建構動作會在本機上以原生方式執行。Docker 沙箱功能會對建構作業施加與遠端執行相同的限制。不過,這個方法不會偵測到洩漏到建構作業中的本機工具、狀態和資料,這會導致遠端執行作業發生問題。
在 Docker 容器中進行疑難排解。 使用這個方法時,Bazel 和建構動作會在 Docker 容器中執行,除了施加與遠端執行相同的限制外,您還可以偵測從本機電腦洩漏到建構作業中的工具、狀態和資料。即使部分建構作業失敗,這個方法仍可提供建構作業的深入分析資訊。這個方法屬於實驗性質,並未獲得正式支援。
必要條件
開始排解問題前,請先執行下列操作 (如果尚未執行):
- 安裝 Docker 並設定執行所需的權限。
- 安裝 Bazel 0.14.1 以上版本。舊版不支援 Docker 沙箱功能。
- 按照這裡的說明,將 bazel-toolchains 存放區 (已在最新版本推出) 新增至建構作業的
WORKSPACE
檔案。 - 在
.bazelrc
檔案中新增旗標,即可啟用這項功能。如果檔案不存在,請在 Bazel 專案的根目錄中建立檔案。以下旗標為參考範例。請查看 bazel-toolchains 存放區中的最新.bazelrc
檔案,並複製為設定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
如果規則需要其他工具,請按照下列步驟操作:
使用 Dockerfile 安裝工具,並在本地建構映像檔,建立自訂 Docker 容器。
將上述
--experimental_docker_image
標記的值替換為自訂容器映像檔的名稱。
透過原生方式排解問題
這個方法會直接在本機執行 Bazel 和所有建構動作,可確認建構作業在遠端執行時是否會成功。
不過,使用這種方法時,本機安裝的工具、二進位檔和資料可能會洩漏到建構作業中,尤其是使用 configure 樣式的 WORKSPACE 規則時。這類洩漏會導致遠端執行作業發生問題;如要偵測這類問題,除了在本機排解問題外,也請在 Docker 容器中排解問題。
步驟 1:執行建構作業
將
--config=docker-sandbox
標記新增至執行建構作業的 Bazel 指令。例如:bazel --bazelrc=.bazelrc build --config=docker-sandbox target
執行建構作業,並等待完成。由於 Docker 沙箱功能,建構作業的執行速度會比平常慢四倍。
您可能會遇到下列錯誤:
ERROR: 'docker' is an invalid value for docker spawn strategy.
如果有的話,請使用 --experimental_docker_verbose
標記再次執行建構作業。
這個標記會啟用詳細的錯誤訊息。這個錯誤通常是因為 Docker 安裝有誤,或是目前使用者帳戶沒有執行 Docker 的權限。詳情請參閱 Docker 說明文件。如果問題仍未解決,請跳到「在 Docker 容器中進行疑難排解」一節。
步驟 2:解決偵測到的問題
以下是常見問題和解決方法。
Bazel 執行檔案樹狀目錄參照的檔案、工具、二進位檔或資源遺失。確認受影響目標的所有依附元件都已明確聲明。詳情請參閱「管理隱含依附元件」一文。
以絕對路徑或
PATH
變數參照的檔案、工具、二進位檔或資源遺失。確認所有必要工具都已安裝在工具鍊容器中,並使用工具鍊規則,以適當的方式宣告指向遺失資源的依附元件。詳情請參閱「透過工具鍊規則叫用建構工具」。二進位檔執行失敗。其中一項建構規則參照的二進位檔與執行環境 (Docker 容器) 不相容。詳情請參閱「管理平台專屬的二進位檔」。如果無法解決問題,請聯絡 bazel-discuss@google.com 尋求協助。
@local-jdk
中的檔案遺失或導致錯誤。本機電腦上的 Java 二進位檔會洩漏到建構作業中,且與建構作業不相容。請在規則和目標中使用java_toolchain
,而非@local_jdk
。如需進一步協助,請來信至 bazel-discuss@google.com。其他錯誤。如需協助,請與 bazel-discuss@google.com 聯絡。
在 Docker 容器中進行疑難排解
使用這種方法時,Bazel 會在主機 Docker 容器內執行,而 Bazel 的建構動作則會在 Docker 沙箱功能產生的個別工具鍊容器內執行。沙箱會為每個建構動作產生全新的工具鍊容器,且每個工具鍊容器只會執行一個動作。
這個方法可更精細地控管安裝在主機環境中的工具。將建構作業的執行程序與建構動作的執行程序分開,並將安裝的工具數量降到最低,即可驗證建構作業是否依附於本機執行環境。
步驟 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
將容器建構為
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 會在主機容器中執行,而 Bazel 的建構動作會在 Docker 沙箱功能產生的工具鍊容器中執行,主機和動作容器則會在本地電腦上執行。
bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target
步驟 5:解決偵測到的問題
您可以按照下列方式解決建構失敗問題:
如果建構作業失敗並顯示「磁碟空間不足」錯誤,您可以啟動主機容器並使用
--memory=XX
標記,藉此提高這項限制,其中XX
是以 GB 為單位的已分配磁碟空間。這項功能仍在實驗階段,可能會產生無法預測的行為。如果建構作業在分析或載入階段失敗,表示您在 WORKSPACE 檔案中宣告的一或多個建構規則與遠端執行不相容。如要瞭解可能原因和解決方法,請參閱「為遠端執行作業調整 Bazel 規則」。
如果因其他原因導致建構失敗,請參閱「步驟 2:解決偵測到的問題」一文中的疑難排解步驟。