
Bazel 内置远程执行 Worker 完全指南构建、运行与沙箱配置【免费下载链接】bazela fast, scalable, multi-language and extensible build system项目地址: https://gitcode.com/GitHub_Trending/ba/bazel导读Bazel 仓库的src/tools/remote下内置了一个基于 gRPC 的远程执行 Worker 程序它既可以充当远程执行remote execution后端也可以只作为分布式缓存cache worker后端或者两者兼而有之。本文以仓库内 src/tools/remote/README.md 为骨架结合RemoteWorker、ExecutionServer、RemoteWorkerOptions等源码实现完整讲解如何编译并启动 Worker、如何让本地 Bazel 客户端通过--remote_executor接入它以及在 Linux 上开启沙箱提升构建隔离性与可复现性的全部配置项。读完本文你将能够独立搭建一套单机版远程执行 分布式缓存环境并理解 Worker 内部的服务结构与关键命令行参数。Worker 是什么一个 gRPC 远程执行服务端根据 src/tools/remote/README.md 的说明该程序实现了一个远程执行 Worker通过 gRPC 接受工作请求。它有三种工作形态远程执行 Worker接收 Bazel 客户端发来的 action 并在本地执行回传ActionResult缓存 Worker仅作为内容寻址存储CAS与 action 缓存AC的服务端不执行任务两者兼有既缓存又执行这也是最简单、最常见的单机部署方式。入口类为com.google.devtools.build.remote.worker.RemoteWorker构建产物定义在 src/tools/remote/BUILD 中java_binary( name worker, jvm_flags [--enable-native-accessALL-UNNAMED], main_class com.google.devtools.build.remote.worker.RemoteWorker, runtime_deps [//src/tools/remote/src/main/java/com/google/devtools/build/remote/worker], )内部服务结构从 RemoteWorker.java 的字段与startServer()方法可以看到Worker 启动后会在同一个 gRPC 端口上挂载多个服务实现自build.bazel.remote.execution.v2等协议服务实现类职责ExecutionExecutionServer接收并执行 action管理长运行操作OperationContentAddressableStorageCASCasServer存储与读取内容寻址的数据块ActionCacheActionCacheServer读写 action 缓存ActionResultByteStreamByteStreamServer流式上传/下载 blob 与输出文件CapabilitiesCapabilitiesServer向客户端通告支持的 API 版本与能力FetchFetchServer远程资源拉取remote asset fetch值得注意的是只有当设置了--work_path时ExecutionServer才会被创建RemoteWorker构造函数中workPath为空则execServer null此时 Worker 会打印Execution disabled, only serving cache requests退化为纯缓存服务。这与 README 中可以作为执行 Worker、缓存 Worker 或两者兼有的描述完全对应。最简部署构建并启动 Worker第一步构建 Worker 与示例目标README 给出的最简流程首先构建 Workerbazel build src/tools/remote:all随后创建工作目录与 CAS 目录mkdir -p /tmp/worker/work /tmp/worker/cas第二步启动 Workerbazel-bin/src/tools/remote/worker \ --work_path/tmp/worker/work \ --cas_path/tmp/worker/cas \ --listen_port8080三个核心参数的含义定义见 RemoteWorkerOptions.java--work_pathWorker 执行 action 的工作目录类型为路径默认值为null。一旦未设置执行能力即被禁用Worker 只做缓存设置后源码会在该路径下创建build-uuid形式的临时执行目录见ExecutionServer.execute()。--cas_path内容寻址存储CAS的落地目录类型为路径。在 RemoteWorker.java 的main()中强制要求该路径为绝对路径否则直接System.exit(1)并输出--cas_path must be set to an absolute path。底层由OnDiskBlobStoreCache封装DiskCacheClient实现见 OnDiskBlobStoreCache.java。--listen_portgRPC 服务监听端口默认值8080。启动成功后日志会输出Starting gRPC server on port 8080。第三步让 Bazel 客户端接入 Worker再开一个终端直接对仓库内的目标发起远程构建bazel build \ --remote_executorgrpc://localhost:8080 \ src/tools/generate_workspace:all--remote_executor指定远程执行/缓存后端的地址协议前缀为grpc://。README 特别说明这条命令会以remote spawn 策略构建generate_workspace并把本地 Worker 当作分布式缓存与执行后端——也就是 Bazel 客户端把 action 与输入上传到 Worker 的 CASWorker 执行后回传结果客户端同时把结果写入本地并复用于后续增量构建。Linux 沙箱提升构建的封闭性与可复现性在 Linux 上运行 Worker 时可以开启沙箱以获得更强的封闭性hermeticity。README 给出的完整配置如下mkdir --parents /tmp/worker/work /tmp/worker/cas /tmp/worker/tmpfs bazel-bin/src/tools/remote/worker \ --work_path/tmp/worker/work \ --cas_path/tmp/worker/cas \ --listen_port8080 \ --sandboxing \ --sandboxing_writable_path/run/shm \ --sandboxing_tmpfs_dir/tmp/worker/tmpfs \ --sandboxing_block_network沙箱初始化逻辑开启沙箱后RemoteWorker.prepareSandboxRunner()会执行一系列前置检查与准备源码见 RemoteWorker.java仅在 Linux 上可用其他操作系统直接报错退出Sandboxing requested, but it is currently only available on Linux要求--work_path必须是绝对路径从 Worker 的 jar 资源中解压内嵌的linux-sandbox二进制到--work_path/linux-sandbox并设置为可执行该二进制在 src/tools/remote/src/main/java/com/google/devtools/build/remote/worker/BUILD 中通过resources [//src/main/tools:linux-sandbox]打入用LinuxSandboxCommandLineBuilder构造并执行一条自检命令运行true失败则退出确保沙箱可用。三个沙箱调优参数README 对三个参数给出了明确语义结合ExecutionServer.getCommand()见 ExecutionServer.java可以看到它们如何被翻译成linux-sandbox的命令行选项--sandboxing_writable_pathpath允许正在执行的 action 向该路径写入对应linux-sandbox的-w参数可多次指定。适合把/run/shm这类需要共享写权限的系统路径放行给 action。--sandboxing_tmpfs_dirpath为每个 action 在指定路径上挂载一个全新的、空的 tmpfs对应linux-sandbox的-e参数可多次指定。适合给临时文件、中间产物提供独立且自动清理的文件系统。--sandboxing_block_network把每个 action 放入独立的网络命名空间除了自身的localhost外没有任何网络连通性对应linux-sandbox的-N参数。README 特别提醒受 Linux 内核某已知问题影响若并行执行大量 action可能导致性能损失对长时间运行的测试则影响通常不大。开启沙箱后ExecutionServer会用sandboxPath前缀拼接执行命令例如实际执行的命令行形态为linux-sandbox [-N] [-w path] [-e path] -- arguments...。此外若 action 的 platform 属性中带有container-image形如docker://...Worker 会优先把命令包装进docker run容器中执行见ExecutionServer.dockerContainer()与getCommand()的容器分支沙箱与容器两种隔离手段按需取舍。更多命令行参数从源码看全量配置除了 README 提到的参数RemoteWorkerOptions.java 中定义了完整的选项集按用途整理如下并发与调试参数默认值说明--jobsauto最大并发执行的任务数取值语法与 Bazel 的--jobs一致auto表示按机器硬件如 CPU 数推导有效范围 1 ~ 16384低于 1 报错超过上限自动钳制为上限。对应ExecutionServer中线程池的corePoolSize/maximumPoolSize见 ExecutionServer.java。--debugfalse开启后日志输出更详细且失败时保留工作目录ExecutionServer.execute()的 finally 分支中不再删除build-id目录便于排查远程任务失败。--pid_filenullWorker 完全启动后把进程号写入该文件进程退出时自动删除见RemoteWorker.createPidFile()。缓存行为参数默认值说明--http_listen_port0不启动额外启动一个内嵌 HTTP REST 缓存服务PUT 存入、GET 取回内存实现仅供测试底层由 Netty 启动并复用同一 CAS。--action_cache_integrity_checktrue为false时返回 action 结果前不再校验其引用的 blob 是否存在于 CAS用于模拟不做完整性校验的远程缓存测试用途见 OnDiskBlobStoreCache.java。--error_on_duplicate_downloadsfalse为true时同一个工具调用tool invocation内每个 digest 最多只允许下载一次测试用途。安全与传输TLS、鉴权参数默认值说明--tls_certificatenullTLS 服务器证书路径设置后整个 gRPC 服务启用 TLSNettyServerBuilder.sslContext(...)。--tls_private_keynull与证书配对的私钥路径。--tls_ca_certificatenullCA 证书路径设置该参数即隐式启用客户端认证mTLSClientAuth.REQUIRE见RemoteWorker.getSslContextBuilder()。--expected_authorization_tokennull校验每个请求的Authorization: Bearer token头不匹配则返回PERMISSION_DENIED测试用途见AuthorizationTokenInterceptor。API 兼容与故障注入测试用途参数默认值说明--legacy_apifalse为true时把通告的 Remote Execution API 版本限制为 2.0见CapabilitiesServer.getCapabilities()。--unavailablefalse为true时除Capabilities外所有 gRPC 服务都返回UNAVAILABLE测试用途。--failure_count/--failure_method/--failure_marker_file0/google.bytestream.ByteStream/Read/null对指定 gRPC 方法注入前 N 次UNAVAILABLE失败可用 marker 文件反复武装用于驱动客户端的远程失败熔断逻辑测试用途见FailFirstNInterceptor。未设置--cas_path时的行为若既不设置--cas_path也不设置其他存储RemoteWorkerOptions的说明指出 Worker 会退化为内存存储不过当前版本main()中要求--cas_path必须为绝对路径因此实际部署请始终显式提供。验证与进阶如何确认 Worker 正常工作查看启动日志应看到Starting gRPC server on port 8080若只做缓存会出现Execution disabled, only serving cache requests。观察构建是否真正远程化用bazel build --remote_executorgrpc://localhost:8080 --remote_verbose_failures ...构建后可在--work_path下看到build-uuid执行目录--debug时失败会保留在--cas_path下看到按 digest 组织的 blob 文件。回归测试仓库提供了 Worker 的测试资源可参考 src/tools/remote/src/test/java/com/google/devtools/build/remote/worker 下的测试结构以及src/tools/remote/BUILD中的srcs文件组了解协议兼容与缓存行为的验证思路。小结src/tools/remote内置的 Worker 是理解 Bazel 远程执行体系的最小可运行实现一条bazel build即可构建三条参数即可启动配合--remote_executor即可让本机 Bazel 使用远程 spawn 策略完成分布式缓存与执行。在 Linux 上--sandboxing及配套的--sandboxing_writable_path、--sandboxing_tmpfs_dir、--sandboxing_block_network三个参数提供了可调校的封闭执行环境。若需进一步深挖协议与调度可继续阅读 ExecutionServer.javaaction 执行流程、OnDiskBlobStoreCache.java磁盘缓存实现与 RemoteWorkerOptions.java全量参数定义。【免费下载链接】bazela fast, scalable, multi-language and extensible build system项目地址: https://gitcode.com/GitHub_Trending/ba/bazel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考