セルフホスト型 Bare Metal Runner


セルフホスト型 Runner とは、Bencher が管理する On-Demand または Dedicated Runner を使う代わりに、 自分自身で実行・管理する Bare Metal Runner です。 runner バイナリを Bencher API サーバーに向けると、 自分自身のハードウェア上で Job を要求して実行します。

Runner のセルフホストは、次のような場合に適しています。

  • Bencher Cloud が提供していない特定のハードウェア上でベンチマークを実行したい
  • ベンチマークのワークロードを自分自身のネットワーク内やエアギャップ環境に保ちたい
  • Bencher Self-Hosted をエンドツーエンドで実行したい

このガイドでは、Runner の登録、Spec によるそのハードウェアの記述、両者の連携、 そして runner バイナリの起動までを順に説明します。 Runner、Spec、Sandbox、Job がどのように組み合わさるかの概念的な概要については、 Bare Metal の概要 を参照してください。

🐰 Firecracker のサンドボックス化には、KVM が有効で、/sys/fs/cgroup に書き込み可能な cgroup v2 階層がある Linux 5.14 以降が必要で、 Runner は root として実行する必要があります。 サンドボックス化された各 Job は、CPU コア数にかかわらず /sys/fs/cgroup/bencher の下にある専用の cgroup で実行され、cpuset、memory、pids コントローラーが有効になります。 Runner は Job のプロセスをその cgroup の cgroup.kill で終了させますが、これは古いカーネルにはありません。その場合 Runner は起動時に終了するか、--danger-allow-no-sandbox 付きで起動していれば、サンドボックス化された各 Job を失敗させます。 サンドボックス化された各 Job を動かす Firecracker プロセスは非特権ユーザーとして chroot に閉じ込められ、 その閉じ込めの構築には、KVM を有効にするだけでは得られない権限が必要です。 サンドボックスなしの Spec のみを提供する Runner は、サポートされている任意のホスト上で実行できます。

Runner を作成する

Runner は、runner バイナリを Bencher API サーバーに対して認証するリソースです。 bencher CLI、Runners REST API、 または Bencher Console で作成します。

Terminal window
bencher runner create \
--host https://api.bencher.example.com \
--name "My Runner"

Bencher は新しい Runner をそのキーとともに返します。

{
"uuid": "...",
"key": "bencher_runner_..."
}

キーは一度だけ表示されるため、安全に保管してください。 Runner を起動する際に、このキーを runner バイナリに渡します。 キーを紛失または漏洩した場合は、POST /v0/runners/{runner}/key API でローテーションします。 これにより、以前のキーは直ちに無効化されます。

Spec を作成する

Spec は、Runner が提供するハードウェアを記述します。 オペレーティングシステム、CPU アーキテクチャ、Sandbox の種類、CPU 数、メモリ、ディスク、ネットワークアクセスです。 Job は必要とする Spec を宣言し、Runner はサポートする Spec の Job のみを要求します。

bencher CLI、Specs REST API、 または Bencher Console で Spec を作成します。

Terminal window
bencher spec create \
--host https://api.bencher.example.com \
--name "Intel v1" \
--os linux \
--architecture x86_64 \
--sandbox firecracker \
--cpu 4 \
--memory 51539607552 \
--disk 137438953472

サンドボックスなしの Spec を定義するには --sandbox を省略し、 この Spec の Job にネットワークアクセスを許可する場合は --network を渡します。 メモリとディスクはバイト単位で指定します。 Spec の詳細と、Testbed が各 Report で使用された Spec をどのように記録するかについては、 Testbed と Spec を参照してください。

Spec を Runner に割り当てる

Runner Spec は、Spec を Runner に紐付けます。 1 つの Runner は複数の Spec をサポートでき、1 つの Spec は複数の Runner からサポートされ得ます。 Runner は、割り当てられた Spec の Job のみを要求します。

bencher CLI または Runner Specs REST API で Spec を Runner に追加します。

Terminal window
bencher runner spec add my-runner \
--host https://api.bencher.example.com \
--spec intel-v1

後で紐付けを解除するには、DELETE /v0/runners/{runner}/specs/{spec} API を使用します。

Runner を起動する

Runner を作成し、少なくとも 1 つの Spec を割り当てたら、 runner up でハードウェア上の runner バイナリを起動します。 API サーバーのホスト、Runner の UUID またはスラッグ、そして Runner キーを、 フラグまたは環境変数として指定します。

Terminal window
runner up \
--host https://api.bencher.example.com \
--runner my-runner \
--key bencher_runner_...
Terminal window
export BENCHER_HOST=https://api.bencher.example.com
export BENCHER_RUNNER=my-runner
export BENCHER_RUNNER_KEY=bencher_runner_...
runner up

runner バイナリは API サーバーへの単一の WebSocket 接続 を開き、 自身の Spec に一致する Job をポーリングし、それぞれを実行して結果を報告します。 接続は複数の Job にわたって開いたままになり、 新しいバージョンが利用可能になると、バイナリは Job の合間に 自身を更新します。 デフォルトでは、Runner は stable 更新チャネルに従い、 バージョン付きリリースへのみ更新します。 canary チャネルは、Bencher Cloud にデプロイされるローリング canary ビルドを追跡します。

サンドボックス化された Job を実行する Runner は root として動かす必要があるため、 上記のコマンドは root ユーザーが実行する場合、 あるいは Runner を root で起動するサービスマネージャー配下での実行を想定しています。

デフォルトでは、Runner は Sandbox のない Spec の Job をすべて拒否します。 Runner にサンドボックスなしの Job をホスト上で直接実行させるには、 --danger-allow-no-sandbox フラグ を付けて起動します。

  • runner up

    runner up

    Runner を起動し、ベンチマーク Job をポーリングして実行します。 これは セルフホスト型 Runner を運用するために使う、長時間実行コマンドです。 Runner は API サーバーへの単一の WebSocket 接続 を開き、 自身の Spec に一致する Job を要求し、それらを実行して結果を報告します。 Runner は自身のログを 1 行に 1 つのオブジェクトとして JSON 形式で stderr に書き込み、Job の出力はバイト数としてのみ記録します。

    runner up [OPTIONS]

    オプション

    --host <HOST>

    接続先の Bencher API サーバー。 デフォルトでは https://api.bencher.dev が使用されます。 BENCHER_HOST 環境変数でも設定できます。

    --runner <RUNNER>

    運用する Runner の UUID またはスラッグ。 BENCHER_RUNNER 環境変数でも設定できます。

    --key <KEY>

    Runner が作成された ときに返された Runner 認証キー (bencher_runner_...)。 BENCHER_RUNNER_KEY 環境変数でも設定できます。

    --poll-timeout <POLL_TIMEOUT>

    Job を待機する際のロングポーリングのタイムアウト (秒)。1 から 900 の範囲です。 デフォルトでは 55 が使用されます。

    --state-dir <STATE_DIR>

    Runner の永続的な状態ディレクトリ。 絶対パスである必要があります。 サンドボックスを閉じ込める jail はこのディレクトリの下に作成され、 異常終了で残った jail は、各サンドボックス Job の実行前にここから一掃されます。 各 jail はゲストのルートファイルシステム全体と microVM バイナリのコピーを保持し、 Runner は Job を一度に 1 つずつ実行するため、 このディレクトリには jail 1 つ分の実容量が必要です。 --image-cache-size を指定すると、そのサイズまで Image キャッシュも保持します。 状態ディレクトリにかかわらず、1 つのホストで実行できる Runner は一度に 1 つだけです。 root として起動した Runner は実行中ずっとロック /run/bencher/runner.lock を保持し、 root として起動した 2 つ目の Runner はそのロックを示すエラーを出して即座に終了します。root 以外の Runner はロックを開けないため、ロックなしで実行されます。 root として起動した Runner は、起動時と各サンドボックス Job の前に、Job の途中で強制終了された Runner のサンドボックスなど、/sys/fs/cgroup/bencher の下の cgroup でまだ実行中のプロセスを、その Runner の状態ディレクトリにかかわらずすべて終了させます。 専用のファイルシステムまたは tmpfs マウントがサポートされており、推奨されます。 書き込み負荷をシステムディスクから切り離せます。 作成したばかりのファイルシステムは lost+found ディレクトリを含んでいても受け付けられます。 このファイルシステムは nodev や noexec でマウントされていてはなりません。/tmp、/dev/shm、/run はよくそのようにマウントされているため、tmpfs を使う場合はこれらのオプションなしで専用にマウントしてください。 状態ディレクトリ自体を、そのようなファイルシステムを指す root 所有のシンボリックリンクにすることもできます。 たとえば /var/lib/bencher-runner を専用ディスクに向ける形です。 リンクがたどられるのは、リンクを含むディレクトリに書き込めるのが root だけで、 リンクが最終的なターゲットを直接指しており、 そのターゲットが root だけが書き込めるパス上に既に存在する場合に限られます。 ターゲットがまだ存在しないリンクは拒否されるため、先にターゲットを作成してください。 デフォルトでは /var/lib/bencher-runner が使用されます。 環境変数 BENCHER_STATE_DIR でも設定できます。

    --jail-uid <JAIL_UID>

    サンドボックスプロセスが移行する非特権ユーザー ID。 デフォルトでは 61016 が使用されます。 0 は指定できません。 このユーザー ID を所有するホスト上のプロセスはサンドボックスにシグナルを送れるため、 ホストが他の用途に割り当てていない ID を指定してください。 環境変数 BENCHER_JAIL_UID でも設定できます。

    --jail-gid <JAIL_GID>

    サンドボックスプロセスが移行する非特権グループ ID。 デフォルトでは 61016 が使用されます。 0 は指定できません。 環境変数 BENCHER_JAIL_GID でも設定できます。

    --danger-allow-no-sandbox

    Sandbox なしでの Job の実行を許可します。 このフラグがない場合、Sandbox を持たない Spec の Job は実行時に拒否されます。 サンドボックスなしの Job はホスト上で直接実行されるため、信頼できるワークロードに対してのみ有効にしてください。 BENCHER_DANGER_ALLOW_NO_SANDBOX 環境変数でも設定できます。

    --sandbox-log-level <SANDBOX_LOG_LEVEL>

    サンドボックスプロセスのログレベル。 デフォルトでは warning が使用されます。

    --no-raid-pause

    ホスト上の md RAID アレイが再同期、復旧、チェック、修復、または再形成を行っている間も Job を受け付け続けます。 デフォルトでは、Runner は各 Job を要求する前に md アレイを確認し、 いずれかがこれらの処理を実行している間は一時停止します。同期が完了するまで新しい Job を受け付けず、 すでに実行中の Job を停止することはありません。 一時停止中の Runner は接続を維持し、自己更新も引き続き行います。

    --no-auto-update

    サーバーからの自動更新を無効にします。 デフォルトでは、サーバーが新しいバージョンを提供すると、Runner は Job の合間に自身を更新します。 BENCHER_NO_AUTO_UPDATE 環境変数でも設定できます。

    --update-channel <UPDATE_CHANNEL>

    自動更新に使用する更新チャネル。stable または canary のいずれかです。 デフォルトでは stable が使用されます。 stable チャネルはバージョン付きリリースへ更新します。 canary チャネルはローリング canary ビルドを追跡し、 このビルドは Bencher Cloud のデプロイで Runner が変更されるたびに再ビルドされます。 BENCHER_UPDATE_CHANNEL 環境変数でも設定できます。 --no-auto-update と競合します。

    --max-download-size <MAX_DOWNLOAD_SIZE>

    自己更新バイナリの最大ダウンロードサイズ (バイト)。 デフォルトでは 500 MiB が使用されます。 --no-auto-update と競合します。

    --image-cache-size <IMAGE_CACHE_SIZE>

    Runner が Job をまたいで保持する Image blob の最大サイズ (バイト)。 Runner はプルした各 Image の config と layer の blob を --state-dir 配下の blobs に保持するため、 Job は Runner がまだ保持していない blob だけをダウンロードしますが、 Image のマニフェストは毎回レジストリから取得します。 Job の合間に、Runner は残りがこのサイズに収まるまで、最も長く使われていない blob から削除します。 Runner は起動時にこのストアを作成して自身のものにし、それができない場合はディレクトリを示すエラーとともにすぐに終了します。 デフォルト、または 0 では、Runner は Job をまたいで blob を保持せず、以前に保持していた blob を削除します。 環境変数 BENCHER_IMAGE_CACHE_SIZE でも設定できます。

    --max-output-size <MAX_OUTPUT_SIZE>

    収集される stdout と stderr の最大サイズ (バイト)。 デフォルトでは 25 MiB が使用されます。

    --max-file-count <MAX_FILE_COUNT>

    デコードする出力ファイルの最大数。 デフォルトでは 255 が使用されます。

    パス解決時にたどるシンボリックリンクの最大数。 Linux カーネルの MAXSYMLINKS 制限に一致します。 デフォルトでは 40 が使用されます。 サンドボックスなしモードでのみ使用されます。

    ホストチューニング

    各ベンチマークの前に、runner は測定ノイズを低減するためにホストチューニングを適用します。 デフォルトでは、ASLR、NMI ウォッチドッグ、SMT / ハイパースレッディング、ターボブーストを無効にし、 CPU スケーリングガバナーを performance、swappiness を 10、perf_event_paranoid を -1 に設定します。 前回の起動以降に runner がチューニングしていないホストでは、以下のフラグは、個々の最適化を無効にせず、ホストのデフォルト値のまま維持します。

    ホストチューニングはホストが再起動するまで持続します。各設定は実行時のみの書き込みであり、runner は終了時にそれを元に戻しません。ただし、C ステートの保持は runner の終了時に解除されます。 チューニングを行った実行の後では、それ以外の設定をスキップするフラグは次回の再起動から有効になります。それまでは、その設定はチューニングされた値のままであり、runner は起動時にその値をログに出力します。 共有ホストでは、runner を削除した後にホストを再起動してください。

    --no-tuning

    すべてのホストチューニング最適化を無効にします。

    --aslr

    ASLR を無効にしません (デフォルト: ベンチマークでは無効)。

    --nmi-watchdog

    NMI ウォッチドッグを無効にしません (デフォルト: ベンチマークでは無効)。

    --smt

    SMT / ハイパースレッディングを無効にしません (デフォルト: ベンチマークでは無効)。

    --turbo

    ターボブーストを無効にしません (デフォルト: ベンチマークでは無効)。

    --numa-balancing

    自動 NUMA バランシングを無効にしません (デフォルト: ベンチマークでは無効)。

    --timer-migration

    タイマーマイグレーションを無効にしません (デフォルト: ベンチマークでは無効)。

    --soft-watchdog

    ソフトロックアップウォッチドッグを無効にしません (デフォルト: ベンチマークでは無効)。

    --ksm

    KSM (Kernel Samepage Merging) を無効にしません (デフォルト: ベンチマークでは無効)。

    --cstates

    深い C ステートを無効にしません (デフォルト: ベンチマークでは無効)。

    --no-irq-steering

    デバイスの IRQ とカーネルのワークキューをハウスキーピングコアに振り向けません。

    --no-cpuset-partition

    分離された cpuset パーティションによってベンチマークコアをスケジューラーから切り離しません。

    --swappiness <SWAPPINESS>

    swappiness の値を設定します。 デフォルトでは 10 が使用されます。

    --governor <GOVERNOR>

    CPU スケーリングガバナーを設定します。 デフォルトでは performance が使用されます。

    --perf-event-paranoid <PERF_EVENT_PARANOID>

    perf_event_paranoid の値を設定します。 デフォルトでは -1 が使用されます。

    --thp <THP>

    ホストの Transparent Hugepage モードを never、madvise、always、leave のいずれかに設定します。 leave を指定すると、ホストの現在のモードを維持します。 デフォルトでは never が使用されます。

    --help

    ヘルプを表示します。

すべてのオプションについては runner CLI リファレンスを、 サーバーとやり取りされるメッセージについては Runner プロトコル リファレンスを参照してください。

ホストのメンテナンス

Runner とそのホストのメンテナンス(パッケージのアップグレードや RAID スクラブなど)は交代で実行されるため、メンテナンスが Job の実行中に走ることはありません。 交代は /run/bencher を通じて行われます。これは root として起動した Runner が root 専用に作成するディレクトリです。

  • Job ロック、/run/bencher/job.lock。 Runner は Job を要求する前にこれを取得し、そのポーリングが Job なしで終わるか、届いた Job が終わるまで保持します。 メンテナンスはこのロックを待つため、Job と Job の間にしか始まりません。 また、ロックが保持されているのを見つけた Runner は、ロックが空くまで Job を受け付けません。
  • メンテナンスマーカー、/run/bencher/maintenance または /run/bencher/maintenance.<name>。 メンテナンスはロックを待つ前に自分のマーカーを作成し、完了したら削除します。 マーカーが存在する間、Runner は Job を要求せずロックを空けておくため、 待機中のメンテナンスは Runner の現在のポーリング、またはそのポーリングで届いた Job が終わり次第始まります。

メンテナンスを待つ間、Runner は一時停止しています。接続は維持され、自己更新も引き続き行います。 runner run も Job ロックを待ち、マーカーが存在する間や md アレイが同期している間は警告を出しつつ実行します。 root ではない Runner は Job ロックを開くこともマーカーを見ることもできないため、それらなしで Job を受け付けます。

systemd では、ドロップインによってメンテナンスユニットに順番を待たせます。 たとえば /etc/systemd/system/fstrim.service.d/zz-bencher-quiet.conf は、ユニット自身のコマンドを flock -F で包みます。 空の ExecStart= はそのコマンドを消去するため、次の行でそれを正確に繰り返す必要があります。

[Service]
ExecStartPre=+/usr/bin/install -d -m 0700 /run/bencher
ExecStartPre=+/usr/bin/touch /run/bencher/maintenance.%n
OpenFile=/dev/null
ExecStart=
ExecStart=/usr/bin/flock -F /run/bencher/job.lock /sbin/fstrim --listed-in /etc/fstab:/proc/self/mountinfo --verbose --quiet-unsupported
ExecStopPost=+/bin/sh -c '/usr/bin/busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager PreparingForShutdown | /usr/bin/grep -q true || /usr/bin/rm -f /run/bencher/maintenance.%n'
TimeoutStartSec=infinity

OpenFile=/dev/null がファイルディスクリプタ 3 を占めるため、apt.systemd.daily のようにコマンドがディスクリプタ 3 を開き直しても、ロックは保持されたままです。 ホストがシャットダウンの準備をしている間、ExecStopPost= はマーカーを残すため、再起動で /run が空になるまで Runner は Job を受け付けません。

Runner をドレインする

Runner をドレインするには、root として単純なマーカーを作成します。

Terminal window
touch /run/bencher/maintenance

Runner は現在のポーリング(最大 --poll-timeout 秒)と、実行中の Job またはそのポーリングで届いた Job を終えた後、マーカーがなくなるまで次の Job を受け付けません。

Terminal window
rm /run/bencher/maintenance

/run は起動時に空になるため、再起動でもマーカーは削除されます。

セルフホスト型 Runner のワークフロー

Runner が接続されると、他の Bare Metal Runner と同じ方法でベンチマークを送信します。 Image をビルドしてプッシュし、一致する Spec で bencher run --image を実行します。 以下の図は、Runner の登録から Job の実行までの全体の流れを示しています。

OCI Registryrunner binaryAPI ServerOCI Registryrunner binaryAPI ServerAdminbencher runner createRunner + keybencher spec createbencher runner spec addrunner up --host --runner --keyConnect (WebSocket) and poll for JobsAssign matching JobPull ImageImage layersRun benchmarkSubmit resultsAdmin

続けて読む: runner CLI リファレンス ➡

🤖 このドキュメントは AI によって自動的に翻訳されました。 正確ではない可能性があり、間違いが含まれている可能性があります。 エラーを見つけた場合は、GitHub で問題を開いてください。.


Published: Fri, June 19, 2026 at 8:00:00 AM UTC | Last Updated: Fri, October 9, 2026 at 3:39:11 PM UTC