跳转到主要内容
桥接模式下,你的沙箱平台留在内网,外部不可达。你在沙箱平台旁的主机上运行 ei-worker 守护进程(产品界面中称「工作节点」):它只发起出站 HTTPS 调用,长轮询 Empiric Intelligence 获取沙箱作业,在你的本地沙箱平台上执行每个操作,并把结果回传。
无需开放任何入站端口,且 Empiric Intelligence 永不持有你沙箱平台的凭证:worker 仅从本地环境变量读取。

前置条件

  • Python 3.11+。
  • 到 Empiric Intelligence 云 API 的出站 HTTPS。
  • 到本地沙箱平台的网络访问。
  • 沙箱实例到制品存储的出站 HTTPS(见下文「文件传输与出站访问」)。
  • 用于 worker 结果日志的持久化磁盘(见下文「结果日志与恢复」)。

文件传输与出站访问

体积较小的操作载荷经由工作队列传递,文件内容不走这条路:沙箱使用云端按操作签发的短期预签名 URL,直接与制品存储读写。大文件不会往返经过 Empiric Intelligence API——正是这一点让数百兆字节的工作区在实践中可行。 因此只需一条出站规则,而且它落在沙箱上,而不是 worker 主机上: 在你开放任何规则之前,你的 Empiric Intelligence 对接人会先确认你这套部署对应的确切制品主机名。 不需要的东西:
  • 始终不需要任何入站规则。 两条规则都是出站;你的平台对外仍然不可达。
  • 你的网络中不存放任何云端凭据。 预签名 URL 自带授权,只针对单个对象,并在 60 分钟内过期。worker 和沙箱都不会持有制品存储的访问密钥。
  • worker 主机不需要访问制品存储。 worker 只与 API 通信,沙箱才与存储通信。
如果你用 network_policy 限制沙箱自身的互联网访问,制品主机必须保持可达;否则文件装载会在运行开始时失败,该次运行无法继续。
如果你的策略无法放行到 Amazon S3 的出站访问,请在开始之前联系我们。 我们可以改为从 Empiric Intelligence 自有主机分发制品流量,这样你的白名单里只需写一个由我们运营的域名,而不是第三方域名。该能力尚未构建:只要你告诉我们它成为阻碍,我们就会优先安排。如果你的约束是客户数据完全不得离开你的网络——这与白名单是两个不同的要求——请明确说明,因为那需要的是存储方案的调整,而不是分发方式的调整。

安装

empiric-intelligence-worker 已发布到 PyPI;你的 runtime id 和 runtime worker 密钥 由 Empiric Intelligence 对接人另行提供。作为系统服务运行时,请将锁定版本安装到由 root 管理的虚拟环境:
请锁定版本,让升级成为运维人员的明确动作;worker 不会自动更新。pipx 或 uv tool 适合交互式用户使用,但二进制通常位于该用户的主目录中,而下文加固后的 systemd 单元会刻意禁止访问用户主目录。 发行版本由 Empiric Intelligence CI 通过 PyPI Trusted Publishing 发布,并附带 Sigstore PEP 740 证明(attestations)以便校验来源。本软件以源码可见(source-available)方式发布,采用受限使用许可(见 LICENSE):你可以运行它以连接 Empiric Intelligence,但不得再分发或修改。

配置

worker 读取的 Empiric Intelligence 设置: 沙箱平台设置由 e2b SDK 自行读取(worker 有意不触碰这些变量,这正是它能同时兼容 E2B 官方云与 CubeSandbox 的原因):

关于 runtime worker 密钥

runtime worker 密钥(lkw01_...)由 Empiric Intelligence 针对单个 runtime 签发,仅展示一次,由你的 Empiric Intelligence 对接人交付。它只能访问本 runtime 的作业队列(一个 runtime 的密钥永远无法轮询另一个 runtime 的队列)。请保存在 root 拥有、权限 600 的文件中。轮换即重新签发:收到新密钥后,换入环境变量文件即可。

用 systemd 运行

将以下单元保存为 /etc/systemd/system/ei-worker.service:
然后创建环境变量文件并启动守护进程:
该单元为结果日志使用持久化状态目录,并自动重启守护进程,唯独在版本被拒后不重启(见下文)。收到 SIGTERM 时,worker 会优雅退出:停止认领新作业,完成进行中的操作,上报当前仍被认领的作业后退出。

启用前检查:doctor

请在启用守护进程前运行,并在沙箱平台升级后再次运行:
每项检查输出 OK、WARN 或 FAIL,只要出现 FAIL 命令就以非零状态码退出:
  1. 云端可达性、密钥有效性、密钥与 runtime 的绑定关系。
  2. 与服务器的时钟偏差(超 30 秒警告,超 300 秒失败)。
  3. 本地沙箱平台可达性。
  4. 暂停能力(未加 --probe 时仅提示)。
  5. 快照能力(CubeSandbox >= v0.5.1;未加 --probe 时仅提示)。
  6. 磁盘剩余空间。
--probe 额外执行真实沙箱检查。暂停检查在本机执行:在你的沙箱平台上创建真实沙箱,验证暂停后磁盘数据得以保留并能正常恢复。快照检查则请求 Empiric Intelligence 云端针对该 runtime 执行自己的往返测试(创建快照、从快照启动派生沙箱、验证磁盘数据完整传递),并打印其结论——因为“Empiric Intelligence 是否会接入该 runtime”只有云端能回答;该往返测试创建的快照也会在同一步骤中被云端登记,因此不会在你的提供方上留下我们没有跟踪的产物。执行该检查时 daemon 必须处于运行状态,因为往返测试是经由该 runtime 自身的工作队列下发的;若未运行,检查会明确指出并提示你先启动 daemon。两项检查创建的任何东西都不会被销毁:探测用的沙箱会被暂停,快照也原样保留——已有派生沙箱从该快照启动,你的提供方本来也会拒绝删除它。两者都只占用存储、不消耗算力;当你的沙箱平台让固定该快照的暂停沙箱到期后,Empiric Intelligence 会回收该快照。请在接入时执行一次,并在每次沙箱平台升级后再次执行。关于 CubeSandbox 为何必须执行此检查,参见兼容性。

版本锁定与 HTTP 426

云端强制部署级通用 worker 版本下限(快照/认证兼容性,当前为 0.5.0,或 runtime 配置的更高版本)。低于下限的 worker 会被 HTTP 426 拒绝,并以特定非零状态码退出,systemd 刻意不重启它(避免对永久性错误进入崩溃重启循环)。请升级锁定的软件包(sudo /opt/ei-worker/bin/pip install --upgrade empiric-intelligence-worker==0.13.1)并重启守护进程(sudo systemctl restart ei-worker)。worker 0.7.0 新增沙箱 network_policy 能力(包括允许列表与断网快照分叉)。在分阶段升级期间,允许公网的工作可继续使用兼容的旧 worker;但受限出站运行会探测实际领取任务的 worker,缺少该能力时将拒绝启动。 worker 0.8.0 是一次线路协议变更:大文件字节不再随操作结果一起传输,因此 0.7.0 及更早版本的 worker 在认证阶段即被拒绝,必须升级。你的其他配置无需改动——这些字节此前就是沙箱直连制品存储传输的,现在依然如此。 worker 0.10.0 同样是一次线路协议变更,只不过是做减法:exec-server 标准输入输出隧道操作及其两个中继端点已被移除,因为已不再有任何调用方派发它们。0.9.0 及更早版本的 worker 在认证阶段即被拒绝,必须升级;你的沙箱平面、密钥与 systemd 单元文件均无需改动。 worker 0.11.0 同样是一次做减法的线路协议变更:sandbox.kill 操作已从操作词汇表中移除。Empiric Intelligence 在任何环节都不再销毁沙箱——用完的沙箱一律暂停,既不消耗算力,磁盘内容也会无限期保留——因此云端不存在该操作的调用方;而仍然应答该操作的 worker,等于在你的平面上常驻一份销毁沙箱的能力。0.10.0 及更早版本的 worker 在认证阶段即被拒绝,必须升级。 worker 0.12.0 是一次增量式的线路协议变更:长时间运行的操作会在执行期间向云端上报进度,命令的时限也不再是总时长。exec.run 携带的是静默时限而非超时时间——只要命令持续输出,无论运行多久都不会被中止;只有在整个时限窗口内毫无输出时,才会在沙箱内部结束该进程(沙箱本身不受影响,继续运行)。模板构建同样会上报构建日志进度,因此缓慢的镜像构建不会再在三十分钟处被放弃。0.11.0 及更早版本的 worker 在认证阶段即被拒绝,必须升级;你的沙箱平面、密钥与 systemd 单元文件均无需改动。 worker 0.13.1 是一次做减法的线路协议变更:sandbox.delete_template 操作已从操作词汇表中移除。Empiric Intelligence 不会删除任何已存储的沙箱制品——模板与快照一律保留,平台既不回收也不为此计费——因此云端不存在该操作的调用方;而仍然应答该操作的 worker,等于在你的平面上常驻一份销毁已存储制品的能力。0.12.0 及更早版本的 worker 在认证阶段即被拒绝,必须升级;你的沙箱平面、密钥与 systemd 单元文件均无需改动。 升级顺序:先云端,后软件包。 协议在两个方向上都要求完全一致,因此把新版软件包提前部署到旧版云端,会与旧版软件包对接新版云端被拒绝的原因完全相同地遭到拒绝。请等待承载新协议的 Empiric Intelligence 部署上线,然后再升级 worker。

结果日志与恢复

每个操作的结果都会在上报之前先提交到本地 SQLite 结果日志,使结果具备崩溃安全性:
  • 守护进程或主机重启后,重新投递的操作会回放结果日志中的记录,不会重复执行。
  • 若操作被重新投递到另一台主机(例如故障转移到第二台 worker 机器),且该主机没有对应的结果日志记录,worker 会将本次执行上报为不确定(indeterminate),不会重复执行命令,也不会重复创建沙箱。
请把结果日志放在持久化存储上(EI_WORKER_STATE_DB 路径)。若在容器中运行 worker,请把结果日志目录挂载为卷;一旦结果日志随容器丢失,原本可干净完成的同机恢复也会变成不确定结果。

调优

  • EI_WORKER_CONCURRENCY:沙箱平台有余量且任务出现排队时可调高;每个槽位同一时间只处理一个沙箱的操作。
  • EI_WORKER_IDLE_TIMEOUT_S:一个空闲的认领保留多久后释放。默认值(330 秒)设计为高于云端的单次操作超时预算;仅在槽位不足时才调低。