OpenSandbox Isolation Session 实战:用 bubblewrap 隔离会话在单个沙箱内并行跑多个互不干扰的任务

发布时间:2026/9/15 18:28:25

OpenSandbox Isolation Session 实战:用 bubblewrap 隔离会话在单个沙箱内并行跑多个互不干扰的任务 OpenSandbox Isolation Session 实战用 bubblewrap 隔离会话在单个沙箱内并行跑多个互不干扰的任务【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox在跑批量任务时常见需求是不想为每个任务都新起一个容器但又不能让任务之间互相污染进程、环境变量和文件系统。OpenSandbox 的 Isolation Session 解决这个问题——它让沙箱内的execd为每个会话 fork 一个 bubblewrapbwrap子进程bwrap建好 Linux namespace 后在其中exec一个长驻bash每个会话拥有独立的 PID、mount、tmpfs 和 env namespace。一个沙箱 pod 因此可以承载多个互不隔离的短任务会话创建约 100 ms之后同一会话内的每次run开销接近于零。适用环境来自文档的组件版本要求execd 1.0.20推荐 1.0.21binds、List sessions、uid_mode: userns与默认可写白名单需要 1.0.21opensandbox-server 0.2.1镜像声明bootstrap.execd.isolation时server 会注入CAP_SYS_ADMIN、apparmorunconfined和bwrap所需的 tmpfs mountPython SDK 0.1.14isolation.run_once/isolation.sessionJavaScript/TypeScript SDK 0.1.10Kotlin 1.0.16C# 0.1.4Go 1.0.4主机要求execd 镜像内自带bwrap二进制与受信任的 native workload gate、CAP_SYS_ADMIN、内核支持overlayfsoverlay工作区模式需要。Linux 源码构建 execd 时需先make build-session-gate再sudo make install-session-gate把辅助程序装到/opt/opensandbox/opensandbox-session-gate且该路径必须 root-owned、不允许组/全局可写缺少它时隔离能力探测 fail-closed适合RL rollouts、批量代码判分、多工具 agent 运行——一个 worker 一个沙箱沙箱内跑大量互相隔离的任务。不适合跨语言内核用/code、交互式 REPL用/session、对抗内核漏洞的硬信任边界用 gVisor/Kata见 Secure Container Runtime。先探测确认当前沙箱支持隔离会话所有接口挂在 execd 的/v1/isolated/下execd 默认监听 44772 端口。如果 execd 配置了 access token请求要带X-EXECD-ACCESS-TOKEN头。curl -s http://localhost:44772/v1/isolated/capabilities文档示例输出{ available: true, isolator: bwrap, version: 0.9.0, setpriv_available: true, userns_available: false, commit_supported: false, diff_supported: false }判断方法available: true说明可以创建隔离会话。available: false对应三种原因native workload gate 缺失或不受信任、bwrap缺失、主机无法创建所需 namespace缺CAP_SYS_ADMIN、user-ns sysctl 受限等。setpriv_available/userns_available分别表示uid_mode: setpriv默认真实 setuid/setgid 降权和uid_mode: usernsuser namespace 重映射能否建会话。这两个字段是 execd v1.0.21 之后才有的旧版 execd 不返回客户端要容忍缺失。commit_supported/diff_supported目前是 Phase 2 占位当前返回503。注意缺少overlayfs不会翻转available但workspace.mode: overlay的会话创建仍可能在运行时失败依赖 overlay 模式的主机需自行验证overlayfs支持。创建会话并执行第一个任务最短主路径curlSSE 流返回stdout/error/complete事件# 创建会话strict profile overlay 工作区 SESSION$(curl -s -X POST http://localhost:44772/v1/isolated/session \ -H Content-Type: application/json \ -d { profile: strict, workspace: {path: /workspace, mode: overlay}, idle_timeout_seconds: 300 } | jq -r .session_id) # 第一次 run curl -N -X POST http://localhost:44772/v1/isolated/session/$SESSION/run \ -H Content-Type: application/json \ -d {code: export X1; echo $X, timeout_seconds: 30} # 第二次 run 复用 shell 状态会打印 1 curl -N -X POST http://localhost:44772/v1/isolated/session/$SESSION/run \ -H Content-Type: application/json \ -d {code: echo $X} # 用完后销毁 curl -X DELETE http://localhost:44772/v1/isolated/session/$SESSIONbash是长驻的所以同一会话内一次run里export X1对下一次run可见——但只在同一会话内可见另一个会话看不到。这就是互不干扰的核心环境变量、进程和/tmpstrictprofile 下是私有 tmpfs都按会话隔离。用 Python SDK 的话同一任务可以写成from opensandbox import Sandbox from opensandbox.models.isolated import ( CreateIsolatedSessionRequest, IsolatedWorkspaceSpec, IsolatedRunOpts, ) async with (await Sandbox.create(python:3.11)) as sandbox: # 一次性执行 await sandbox.isolation.run_once( python -c print(42), workspace/workspace, profilestrict, ) # 长驻会话 async with sandbox.isolation.session( CreateIsolatedSessionRequest( workspaceIsolatedWorkspaceSpec(path/workspace, modeoverlay), profilestrict, idle_timeout_seconds300, ) ) as session: await session.run(export STAGEtrain) await session.run(python train.py, optsIsolatedRunOpts(timeout_seconds600))客户端重启后可以用sandbox.isolation.attach(known_session_id)重新挂回已知会话。并行跑多个互不干扰的任务文档明确给出并行模型的边界同一会话内的run是串行的要做并行就创建多个会话。每个会话各自持有独立的 namespace 和 bash 进程A 会话里 export 的变量、写/tmp的文件B 会话都不可见。# 两个相互隔离的会话 S1$(curl -s -X POST http://localhost:44772/v1/isolated/session \ -H Content-Type: application/json \ -d {profile:strict,workspace:{path:/workspace,mode:overlay},idle_timeout_seconds:300} \ | jq -r .session_id) S2$(curl -s -X POST http://localhost:44772/v1/isolated/session \ -H Content-Type: application/json \ -d {profile:strict,workspace:{path:/workspace,mode:overlay},idle_timeout_seconds:300} \ | jq -r .session_id) # 两个 run 同时在两个会话里执行 curl -N -X POST http://localhost:44772/v1/isolated/session/$S1/run \ -H Content-Type: application/json \ -d {code:export TASKa; sleep 3; echo task-a in $TASK} curl -N -X POST http://localhost:44772/v1/isolated/session/$S2/run \ -H Content-Type: application/json \ -d {code:export TASKb; sleep 3; echo task-b in $TASK} wait # 验证互不干扰S1 看不到 S2 的 TASK 值 curl -N -X POST http://localhost:44772/v1/isolated/session/$S1/run \ -H Content-Type: application/json \ -d {code:echo TASK$TASK} # 输出 a若输出 b 说明隔离失败创建多个会话时的成本结构要心里有数创建会话约 100 msexecd 在bwrap启动后短暂等待以检测立即退出的子进程之后同一会话内每次POST /run复用同一个 bash开销可忽略。所以批量任务的设计原则是把创建成本摊薄到一个会话内的多次run上而不是每跑一条命令就建删会话。选择工作区模式任务之间文件系统怎么隔离workspace.mode决定会话看到的/workspace语义与 profile 相互独立省略时 execd 会把mode归一化为overlay模式语义rw读写 bind-mount写入持久化到宿主机overlay默认overlayfs copy-on-write写入落在每会话独立的 upper 目录DELETE会话后消失ro只读 bind-mount写入报EROFS并行任务的默认选择就是overlay各会话写同一path互不影响会话销毁后写入自动消失也避免了一个池化沙箱的占用者把数据泄漏给下一个占用者。只有任务间需要交换文件时才用rw写入落宿主机或额外 bind。额外暴露路径用两个字段source 都会先做 symlink 解析再对照allowed_writable白名单默认/workspace、/mnt、/media、/data含子路径空白名单拒绝一切额外 bind{ workspace: { path: /workspace, mode: rw }, extra_writable: [/data/scratch], binds: [ { source: /data/in, dest: /mnt/in, readonly: true }, { source: /data/out, dest: /mnt/out } ] }binds的dest必须已存在于沙箱镜像内bwrap无法在只读根下新建挂载点需要时打进镜像。长任务同一会话内的后台 run如果希望某个任务跑着的同时还能在同一会话上继续其他工作用 background run文档中作为同一会话内的补充手段# 启动后台 run202 返回 {session_id, run_id, started_at} RUN$(curl -s -X POST http://localhost:44772/v1/isolated/session/$SESSION/run \ -H Content-Type: application/json \ -d {code: sleep 5 echo done, background: true} | jq -r .run_id) # 轮询状态直到 runningfalse curl -s http://localhost:44772/v1/isolated/session/$SESSION/runs/$RUN # 读输出纯文本EXECD-ISOLATED-TAIL-CURSOR 响应头给出增量读取的下一字节偏移 curl -s http://localhost:44772/v1/isolated/session/$SESSION/runs/$RUN/logs?cursor123后台 run 的边界timeout_seconds只对前台 run 生效后台 run 不限时后台 run 活跃期间该会话的 idle GC 挂起ro工作区会因无可写日志位置而拒绝后台 run400rw/overlay可以每次logs最多返回 16 MiB单 run 日志保留上限也是 16 MiB超出部分在 run 结束时丢弃需要更多时要增量拉取。验证隔离是否按预期工作结合上面的步骤核对点是能力探测/v1/isolated/capabilities返回available: true、isolator: bwrap。会话状态隔离在会话 A 里export的变量会话 B 里查不到SSE 输出里应为空或旧值同一会话内的第二次run能看到第一次的export结果。工作区隔离两个overlay会话对/workspace各写一个文件互相ls不应看到对方的写入DELETE任一会话后其 overlay 写入消失。会话清单GET /v1/isolated/sessions列出当前活跃会话GET /v1/isolated/session/{id}返回完整状态并回显创建参数无状态客户端可据此重建句柄。销毁DELETE /v1/isolated/session/{id}后对已销毁会话的run会返回IsolatedErrorsession process has exited或ErrContextNotFound。失败处理与限制非正常路径的行为文档有明确定义处理时可以照表判断现象行为处理前台run的timeout_seconds到期execd 取消 run context向 bwrap 进程组发SIGINT发IsolatedErrorSSE 事件会话本身存活换更短的命令分段或调大超时后重跑客户端在 SSE 中途断开请求 context 取消execd 对运行中命令发SIGINTrun不会转入后台继续需要跑完就改用background: truebwrap进程退出下一次run返回IsolatedErrorsession process has exitedDELETE后重建会话idle 超时到达GC 执行与DELETE相同的拆除把idle_timeout_seconds设为0可禁用 idle GC改为显式DELETE限制项直接决定这套方案能用到哪里diff/commit是 Phase 2 占位当前返回503见 OSEP-0013。没有硬件级保证只有 namespace seccomp需要对抗内核漏洞时配合 gVisor/Kata 安全运行时。仅支持 Linux非 Linux 构建返回available: false。同一会话内 run 串行并行必须多会话。share_net省略时默认共享沙箱网络 namespace沙箱级的 egress 与 Credential Vault 策略仍然生效。私有网络会话share_net: false无法跨越 execd 重启恢复启用了它的部署要把 execd 视为沙箱关键进程execd 退出时整个沙箱需要重建。会话状态只存在于 execd 内存中execd 重启后所有会话状态不保留upper_root下残留的 overlay upper 目录会在启动时被回收。服务端配置可选隔离行为由 execd 读取的可选 TOML 控制通过--isolation-config或环境变量EXECD_ISOLATION_CONFIG指定完整示例见 isolation.example.toml# 每会话 overlay upper 目录的父目录 upper_root /var/lib/execd/isolation # 所有会话 upper 目录的总大小硬上限字节默认 8 GiB0 表示禁用配额 upper_max_bytes 8589934592 # extra_writable / binds 允许的 source 前缀symlink 解析后检查 # 默认 [/workspace, /mnt, /media, /data]置空则拒绝所有额外 bind allowed_writable [/workspace, /mnt, /media, /data]多会话并行写放大时upper_max_bytes是每个沙箱内全部会话共享的配额会话可能因超配额而创建失败需要按并发任务数和工作集大小调整。进一步阅读execd 组件文档、OSEP-0013 Isolated Execution API、Secure Container Runtime。【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/15 18:38:25

中文字体子集化:精准裁剪而非压缩的工程实践

1. 为什么中文字体子集化不是“压缩”而是“外科手术式裁剪”很多人第一次听说“中文字体子集化”,下意识就联想到 ZIP 压缩、图片 WebP 转换——这是最典型的认知偏差。我去年给一个面向海外用户的中文内容平台做性能优化时,也犯过这个错:直…

2026/9/15 18:38:25

ZZULIOJ刷题全攻略:从入门基础到算法进阶的题解整合与避坑指南

我记得第一次在新生群里看到“ZZULIOJ”这五个字母时,整个人是懵的。页面白底黑字,左侧一排深色菜单,点进去是一道道看着都认识的题,但提交后不是“编译错误”就是“答案错误”。后来我在这套OJ上从大一刷到大四,从被s…

2026/9/15 18:38:25

北京学会网站建设避坑指南:小白不踩雷实操手册

北京学会网站建设避坑指南:小白不踩雷实操手册 想在北京做个像样的网站,心里没底?自己不会代码,又怕被坑?别慌。 这三年我在北京海淀、朝阳跑遍了各大软件园,见过太多初创团队花大价钱做了个“四不像”网站,最后因为服务器卡顿、SEO做废、备案拖延…

2026/9/15 4:54:30

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/14 13:53:59

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码