この記事では、Bazel でのサンドボックス化、sandboxfs
のインストール、デバッグについて説明します
サンドボックス環境を維持します
サンドボックス化は、プロセスを分離する権限制限戦略です。 システム内のリソース間で実行可能です。Bazel の場合、これはファイルへのアクセスを 許可します。
Bazel のファイル システム サンドボックスは、作業ディレクトリでのみプロセスを実行します。 既知の入力が含まれるため、コンパイラやその他のツールがソースを認識しない ユーザーがアクセスすべきでないファイルを定義します。
サンドボックス化しても、ホスト環境が隠れることは一切ありません。プロセスは自由に ファイル システム上のすべてのファイルにアクセスできます。ただし、ユーザー サポートと 作業ディレクトリの外部にあるファイルを変更できません。 これにより、ビルドグラフに隠れた依存関係がなくなり、 影響する場合があります。
具体的には、Bazel はアクションごとに execroot/
ディレクトリを構築します。
このディレクトリは、実行時にアクションの作業ディレクトリとして機能します。execroot/
アクションへのすべての入力ファイルが含まれ、アクションのコンテナ
生成します。次に、Bazel はオペレーティング システムが提供する手法を使用します。
Linux ではコンテナ、macOS では sandbox-exec
を使用します。
execroot/
。
サンドボックス化する理由
アクション サンドボックスを使用しないと、ツールが宣言されていないものを使用しているかどうかを Bazel で判断できません。 入力ファイル(依存関係リストに明示的にリストされていないファイル)を アクション)。宣言されていない入力ファイルのいずれかが変更されても、Bazel は ユーザーが、ビルドが最新であり、アクションを再構築しないと考えています。これにより、 増分ビルドが正しく行われません。
キャッシュ エントリを誤って再利用すると、リモート キャッシュ中に問題が発生します。 共有キャッシュ内の不正なキャッシュ エントリは、プロジェクトのすべてのデベロッパーに影響します。 リモート・キャッシュ全体のワイプは現実的な解決策ではありません。
サンドボックス化はリモート実行の動作を模倣する - ビルドが正常に動作する場合 リモート実行にも対応する可能性があります。作成することにより、 必要なすべてのファイル(ローカル ツールを含む)をリモート実行でアップロードできます。 メンテナンス コストを大幅に削減 クラスタのすべてのマシンにツールをインストールし、 新しいコンパイラを試したり、既存のツールに変更を加えたりしたい場合。
どのようなサンドボックス戦略を採用するか
使用するサンドボックスの種類は、必要に応じて、
戦略フラグ。sandboxed
の使用
Bazel は、以下に示すサンドボックス実装のいずれかを選択します。
密閉性の低い一般的なサンドボックスよりも、OS 固有のサンドボックスを優先します。
次の条件を満たすと、永続ワーカーは汎用サンドボックスで実行されます。
--worker_sandboxing
フラグを指定します。
local
(別名 standalone
)戦略は、サンドボックス化を行いません。
アクションのコマンドラインを単に実行するだけで、作業ディレクトリを
「execroot」です。
processwrapper-sandbox
は、何も必要としないサンドボックス戦略です。
"高度"すぐにあらゆる POSIX システムで動作するはずです。これは、
オリジナルのディレクトリを指すシンボリック リンクで構成されるサンドボックス ディレクトリを構築します。
作業ディレクトリを設定してアクションのコマンドラインを
execroot ではなくこのディレクトリに移動し、既知の出力アーティファクトを
サンドボックスから execroot に移動し、サンドボックスを削除します。これにより
宣言されていない入力ファイルを誤って使用することを防止できます。
execroot を不明な出力ファイルで埋める
linux-sandbox
はさらに一歩進んで、
processwrapper-sandbox
。内部で Docker が行っていることと同様に、Docker は
隔離する Linux 名前空間(ユーザー、マウント、PID、ネットワーク、IPC の名前空間)
アクションを実行します。つまり、ファイル システム全体が読み取り専用になりますが、
サンドボックス ディレクトリに書き込まれるため、誤って変更されるのを防ぎます。
作成されます。これにより、バグのあるテストが誤って
$HOME ディレクトリの -rf を実行すると、必要に応じて、この操作の実行を
ファイアウォールルールがありますlinux-sandbox
は PID 名前空間を使用してアクションを防止
他のプロセスの確認を防ぎ、すべてのプロセス(デーモンも
(アクションによって生成されます)の最後にあります。
darwin-sandbox
も同様ですが、macOS 用です。Apple の sandbox-exec
ツールを使用する
Linux サンドボックスとほぼ同じ機能を実現できます。
linux-sandbox
と darwin-sandbox
はどちらも「ネストされた」で機能しない
使用すると、運用環境によって許容されるメカニズムに制限が
支援しますDocker はコンテナ マジックにも Linux 名前空間を使用するため、
Docker コンテナ内で linux-sandbox
を簡単に実行することはできません。ただし、
docker run --privileged
。macOS の場合、sandbox-exec
を
安全に処理できますしたがって、そのような場合、Bazel は
自動的に processwrapper-sandbox
を使用するようフォールバックします。
Compute Engine で誤ってビルドしないようにするには、
あまり厳格でない実行戦略 — 実行リストを明示的に変更する
Bazel が使用しようとするストラテジー(例: bazel build
--spawn_strategy=worker,linux-sandbox
)。
通常、動的実行には、ローカル実行のサンドボックス化が必要です。オプトアウトするには、
--experimental_local_lockfree_output
フラグを渡します。暗黙的な動的実行
永続ワーカーをサンドボックス化します。
サンドボックスの欠点
サンドボックス化すると、セットアップと破棄のコストが追加で発生します。費用の額 ビルドの形状や構成など、さまざまな要因によって パフォーマンスが向上します。Linux では、サンドボックス化されたビルドが 数パーセント遅くなります。
--reuse_sandbox_directories
を設定すると、 セットアップと破棄のコストを削減できますサンドボックス化により、ツールが保持しているキャッシュは実質的に無効になります。Google Chat では 永続ワーカーを使用してこの問題を軽減します。 脆弱なサンドボックスの保証の代償が引き起こされます。
Multiplex ワーカーではワーカーの明示的なサポートが必要 サンドボックス化します多重化サンドボックスをサポートしていないワーカーは、 単一プレックス ワーカーが動的実行されるので、余分なメモリが消費される可能性があります。
Sandboxfs
sandboxfs
は FUSE ファイル システムであり、デバイスの任意のビューを公開する
ファイル システムにアクセスすることで、パフォーマンスが向上します。Bazel は sandboxfs
を使用して次の処理を行います。
アクションごとに即座に execroot/
を生成し、
必要ありません。なお、execroot/
内でさらに I/O を実行すると、
FUSE のオーバーヘッドにより遅くなります。
sandboxfs をインストールする
次の手順で sandboxfs
をインストールし、Bazel でビルドを実行します。
説明します。
ダウンロード
ダウンロードとインストール
sandboxfs
バイナリが PATH
になるように sandboxfs
にします。
Run sandboxfs
- (macOS のみ)OSXFUSE をインストールします。
(macOS のみ)次を実行します。
sudo sysctl -w vfs.generic.osxfuse.tunables.allow_other=1
この作業は、インストール後と再起動のたびに行う必要があります。 macOS のコア システム サービスは sandboxfs を通じて動作します。
--experimental_use_sandboxfs
を使用して Bazel ビルドを実行します。bazel build target --experimental_use_sandboxfs
トラブルシューティング
検索結果として darwin-sandbox
や linux-sandbox
ではなく local
が表示される場合
アノテーションが付けられている場合、サンドボックス化が
無効です。--genrule_strategy=sandboxed --spawn_strategy=sandboxed
を渡す
有効にします。
デバッグ
サンドボックスの問題をデバッグするには、以下の戦略に従ってください。
無効な名前空間
たとえば
Google Kubernetes Engine
ユーザー名前空間は、クラスタノードまたは Debian ではデフォルトで
懸念を軽減できます/proc/sys/kernel/unprivileged_userns_clone
ファイルが
0 が含まれる場合、ユーザーの名前空間を有効にするには、次のコマンドを実行します。
sudo sysctl kernel.unprivileged_userns_clone=1
ルール実行の失敗
システム設定が原因で、サンドボックスがルールを実行できない可能性があります。検索結果が
namespace-sandbox.c:633: execvp(argv[0], argv): No such file or
directory
のようなメッセージが表示された場合は、次の期間で --strategy=Genrule=local
を使用してサンドボックスを無効にしてみてください
genrules と、その他のルールには --spawn_strategy=local
を使用します。
ビルドエラーの詳細なデバッグ
ビルドが失敗した場合は、--verbose_failures
と --sandbox_debug
を使用して以下を行います。
Bazel は、ビルドが失敗したときに実行された正確なコマンドを、
サンドボックスを設定します
エラー メッセージの例
ERROR: path/to/your/project/BUILD:1:1: compilation of rule
'//path/to/your/project:all' failed:
Sandboxed execution failed, which may be legitimate (such as a compiler error),
or due to missing dependencies. To enter the sandbox environment for easier
debugging, run the following command in parentheses. On command failure, a bash
shell running inside the sandbox will then automatically be spawned
namespace-sandbox failed: error executing command
(cd /some/path && \
exec env - \
LANG=en_US \
PATH=/some/path/bin:/bin:/usr/bin \
PYTHONPATH=/usr/local/some/path \
/some/path/namespace-sandbox @/sandbox/root/path/this-sandbox-name.params --
/some/path/to/your/some-compiler --some-params some-target)
生成されたサンドボックス ディレクトリを調べて、Bazel でどのファイルが使用されているかを確認できるようになりました コマンドを再実行して動作を確認します。
ただし、使用しても Bazel はサンドボックス ディレクトリを削除しません。
--sandbox_debug
。積極的にデバッグを行っている場合を除き、
--sandbox_debug
。時間の経過とともにディスクがいっぱいになるため。