Docker サンドボックスを使用した Bazel リモート実行のトラブルシューティング

<ph type="x-smartling-placeholder"></ph> 問題を報告する <ph type="x-smartling-placeholder"></ph> ソースを表示 夜間 · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

ローカルで成功した Bazel ビルドが、リモートで実行すると失敗することがある ローカルビルドに影響を与えない制限や要件を 実装する必要があります最も一般的なのは このようなエラーの原因については、リモート実行用の Bazel ルールの適用をご覧ください。

このページでは、発生しがちな一般的な問題を特定して解決する方法について説明します。 Docker サンドボックス機能を使用したリモート実行で リモート実行の場合と同じ制約がビルドにも適用されます。これにより、 を使用してビルドのトラブルシューティングを行うことができます。

Docker サンドボックス機能は、リモート実行の制限を模倣します。 次のようになります。

  • ビルド アクションをツールチェーン コンテナで実行する。同じ ツールチェーン コンテナを使用して、ビルドをローカルでも、サービス経由でリモートで実行 コンテナ化されたリモート実行をサポートします。

  • 無関係なデータがコンテナの境界を越えない。明示的に 宣言された入力と出力がコンテナを出入りし、 関連するビルド アクションが正常に完了します。

  • 各アクションは新しいコンテナで実行されます。新しい固有のコンテナは、 各ビルド アクションに対して作成されます。

で確認できます。

これらの問題のトラブルシューティングは、次のいずれかの方法で行うことができます。

  • ネイティブのトラブルシューティング。この方法では Bazel とそのビルド アクションは、ローカルマシンでネイティブに実行されます。Docker サンドボックス機能によって、リモートビルドと同様の制限がビルドに課せられる 実行されます。ただし、この方法ではローカルのツール、状態、 データがビルドに漏れて、リモート実行で問題が発生します。

  • Docker コンテナのトラブルシューティング。 この方法では、Bazel とそのビルド アクションを Docker コンテナ内で実行します。 ローカル サービスからのツール、状態、データ漏洩を検出できます。 ビルドへの制限に加えて、ビルドへの制限も 実行する場合とほぼ同じです。この方法では その一部は失敗してもビルドに失敗します。この方法は試験運用版です サポートされていません

前提条件

トラブルシューティングを開始する前に、次のことをまだ行っていない場合は、次のことを行います。

  • Docker をインストールし、実行に必要な権限を構成します。
  • Bazel 0.14.1 以降をインストールします。それより前のバージョンは Docker サンドボックス機能が用意されています。
  • bazel-ツールチェーン を追加する 最新のリリース バージョンに固定されたリポジトリ(ビルドの WORKSPACE ファイル内) 詳しくはこちらをご覧ください。
  • .bazelrc ファイルにフラグを追加して、この機能を有効にします。ファイルを作成する場所 Bazel プロジェクトのルート ディレクトリが存在しない場合は、ルート ディレクトリに配置します。下のフラグ は参考サンプルです。最新情報については、 .bazelrc bazel-ツールチェーン ファイルを config 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. 実行する Bazel コマンドに --config=docker-sandbox フラグを追加します。 使用できます。例:

    bazel --bazelrc=.bazelrc build --config=docker-sandbox target
    
  2. ビルドを実行し、完了するまで待ちます。ビルドは最大で 4 つの Docker サンドボックス機能が原因で、通常よりも遅くなりました。

次のエラーが発生することがあります。

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

その場合は、--experimental_docker_verbose フラグを使用してビルドを再度実行します。 このフラグは、詳細なエラー メッセージを有効にします。このエラーは通常、次の場合に発生します。 Docker のインストールの失敗、または Docker コンテナを実行する権限の できます。Docker ドキュメントを確認する をご覧ください。問題が解決しない場合は、Docker コンテナのトラブルシューティングに進んでください。

ステップ 2: 検出された問題を解決する

最も一般的な問題とその回避策は次のとおりです。

  • Bazel runfiles ツリーで参照されるファイル、ツール、バイナリ、リソースは、 欠落しています。.影響を受けるターゲットのすべての依存関係が、 明示的に宣言する必要があります。詳しくは、 暗黙的な依存関係の管理 をご覧ください。

  • 絶対パスまたは PATH で参照されるファイル、ツール、バイナリ、リソース 変数がありません。必要なツールがすべて ツールチェーン ルールを使用して、ツールチェーン コンテナが正しく 不足しているリソースを指す依存関係を宣言します。詳しくは、 ツールチェーン ルールを使用したビルドツールの呼び出し をご覧ください。

  • バイナリの実行が失敗する。ビルドルールの 1 つがバイナリを参照している 実行環境(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 つのアクションのみが実行されます。

この方法では、ホストにインストールされているツールをきめ細かく制御できます。 できます。ビルドの実行とその実行を 必要最小限のビルド アクションを実行するよう ビルドにローカル実行環境への依存関係があるかどうかも確認します。

ステップ 1: コンテナをビルドする

  1. Docker コンテナを作成し、Bazel をインストールする Dockerfile を作成します。 最小限のビルドツールを使用できます。

    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

このコマンドは、コンテナを root として実行し、Docker ソケットをマッピングして、マウント /tmp ディレクトリ。これにより、Bazel は他の Docker コンテナを生成し、 /tmp の下のディレクトリを使用して、それらのコンテナとファイルを共有する。ソース コードはコンテナ内の /src にあります。

このコマンドは、debian:stretch ベースコンテナから意図的に開始されます。 として使用される rbe-ubuntu16-04 コンテナと互換性のないバイナリが含まれています ツールチェーン コンテナ。ローカル環境からのバイナリがコンピュータに ツールチェーン コンテナを使用すると、ビルドエラーが発生します。

ステップ 3: コンテナをテストする

Docker コンテナ内から次のコマンドを実行してテストします。

docker ps
bazel version

ステップ 4: ビルドを実行する

以下のようにビルドを実行します。出力ユーザーは root であるため、 ホスト内から同じ絶対パスでアクセスできるディレクトリ Bazel が実行されるコンテナ(Docker が生成したツールチェーン コンテナから取得) Bazel のビルド アクションが実行されているサンドボックス機能、および ホストとアクション コンテナが実行されるマシンです。

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

ステップ 5: 検出された問題を解決する

ビルドエラーは、次のように解決できます。

  • 「ディスク容量が不足しています」というエラーでビルドが失敗した場合この値を増やすには --memory=XX フラグ(XX)を指定してホストコンテナを起動します。 割り当てられたディスク容量(GB)です。これは試験運用版であり、 予期しない動作が発生します。

  • 分析フェーズまたは読み込みフェーズでビルドが失敗した場合は、 WORKSPACE ファイルで宣言されているビルドルールが 実行することもできます。リモート実行用の Bazel ルールの適応をご覧ください。 をご覧ください。

  • その他の理由でビルドが失敗した場合は、ステップ 2: 検出された問題を解決するのトラブルシューティングの手順をご覧ください。