在本地成功完成的 Bazel 构建在远程执行时可能会失败, 不影响本地 build 的限制和要求。最常见的 针对远程执行调整 Bazel 规则中介绍了此类失败的原因。
本页介绍了如何识别和解决 通过使用 Docker 沙盒功能远程执行时出现,这会强制 对构建的限制等于远程执行的限制。这样,您就可以 对构建进行问题排查,而无需远程执行服务。
Docker 沙盒功能将远程执行的限制模拟为 如下:
构建操作在工具链容器中执行。您可以使用 工具链容器,可通过服务在本地和远程运行构建 支持容器化远程执行。
没有无关数据跨越容器边界。仅明确指定 声明的输入和输出进入和离开容器,且仅在 关联的构建操作成功完成。
每个操作都是在新容器中执行。一个独一无二的新容器 为每个生成的构建操作创建的。
您可以使用下列方法之一排查这些问题:
原生问题排查。通过这种方法 Bazel 及其构建操作在本地机器上以原生方式运行。Docker 沙盒功能对与远程 执行。不过,此方法不会检测本地工具、状态和 这会导致远程执行出现问题。
在 Docker 容器中进行问题排查。 通过这种方法,Bazel 及其构建操作在 Docker 容器内运行, 让您可以检测从本地 将机器添加到 build 中,以及对其施加限制 相当于远程执行的时间。通过这种方法,您可以深入了解 即使构建的某些部分失败也是如此。此方法尚处于实验阶段 且不受官方支持。
前提条件
在开始排查问题之前,请先执行以下操作(如果您尚未这样做):
- 安装 Docker 并配置运行 Docker 所需的权限。
- 安装 Bazel 0.14.1 或更高版本。较低版本不支持 Docker 测试区功能。
- 添加 bazel-toolchains
将 repo 固定到最新版本,并粘贴到 build 的
WORKSPACE
文件中 如此处所述。 - 将标志添加到
.bazelrc
文件以启用该功能。在以下位置创建文件: (如果 Bazel 项目的根目录不存在)。旗帜 是参考示例。请查看最新.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 及其所有构建操作 它可作为确认构建是否成功的可靠方法, 远程执行。
但是,如果使用此方法,本地安装的工具、二进制文件和数据可能会泄露 添加到您的 build 中,尤其是在使用配置样式的工作区规则时。 此类泄露会导致远程执行出现问题;在 Docker 容器中进行问题排查 您还能自行排查问题
第 1 步:运行构建
将
--config=docker-sandbox
标志添加到要执行的 Bazel 命令中 。例如:bazel --bazelrc=.bazelrc build --config=docker-sandbox target
运行构建并等待构建完成。build 最多会运行 比平常慢 1 倍。
您可能会遇到以下错误:
ERROR: 'docker' is an invalid value for docker spawn strategy.
在这种情况下,请使用 --experimental_docker_verbose
标志再次运行构建。
此标志用于启用详细的错误消息。此错误通常是由于
Docker 安装错误或没有
当前用户账号。请参阅 Docker 文档
。如果问题仍然存在,请直接跳到在 Docker 容器中进行问题排查。
第 2 步:解决检测到的问题
以下是最常见的问题及其解决方法。
Bazel runfiles 树引用的文件、工具、二进制文件或资源 缺失。确认受影响目标的所有依赖项都已被 明确声明。请参阅 管理隐式依赖项 。
由绝对路径或
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
此命令以 root 身份运行容器,映射 Docker 套接字,
/tmp
目录中。这样,Bazel 能够生成其他 Docker 容器,
使用 /tmp
下的目录与这些容器共享文件。您的来源
代码可在容器内的 /src
下找到。
该命令刻意从 debian:stretch
基础容器开始,
包含与用作 rbe-ubuntu16-04
容器的 rbe-ubuntu16-04
容器不兼容的二进制文件
工具链容器。如果本地环境中的二进制文件泄露到
工具链容器,它们会导致构建错误。
第 3 步:测试容器
从 Docker 容器内部运行以下命令以对其进行测试:
docker ps
bazel version
第 4 步:运行构建
运行 build,如下所示。输出用户是 root,因此它对应于 可从主机内部使用相同的绝对路径访问的目录 运行 Bazel 的容器, 运行 Bazel 的构建操作的沙盒功能 主机和操作容器在哪个机器上运行。
bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target
第 5 步:解决检测到的问题
您可以按如下方式解决构建失败问题:
如果构建失败并显示“磁盘可用空间不足”您可以提高 使用标志
--memory=XX
启动主机容器,其中XX
是分配的磁盘空间 (GB)。这是一项实验性功能, 会导致不可预测的行为。如果构建在分析或加载阶段失败,会出现一个或多个 您在 WORKSPACE 文件中声明的构建规则 远程执行。请参阅针对远程执行调整 Bazel 规则 了解可能的原因和解决方法。
如果构建因任何其他原因而失败,请参阅第 2 步:解决检测到的问题中的问题排查步骤。