OpenSandbox — 架构与原理
30 秒导读: OpenSandbox 是阿里开源的通用沙箱平台,给 AI 应用(编码 agent、GUI agent、代码执行、RL 训练)提供「安全、可编程、可大规模调度的一次性电脑」。它的核心是两个平面的分离:一套 OpenAPI 协议把「谁来管容器的生老病死」(控制面)和「怎么在容器里跑命令/读写文件/执行代码」(数据面)彻底切开——你换掉底 层是 Docker 还是 Kubernetes,上层的执行 API 一字不变。
1. 这是什么(零基础也能懂)
一句话定义: OpenSandbox 是一个「沙箱即服务」平台——你发一个 HTTP 请求,它给你一台隔离的、临时的、装好环境的容器;你再发请求,就能在里面跑 shell 命令、执行 Python、读写文件、开终端(PTY)。
解决什么问题 / 给谁用: 假设你在写一个 AI agent,它会生成代码并想「真的跑一下」。你绝不敢让模型生成的代码直接在你的服务器上执行——它可能 rm -rf、可能偷你的密钥、可能挖矿。于是你需要一个用完即弃的隔离环境。OpenSandbox 就是把「造这样一台环境、在里面执行、然后销毁」这件事标准化成协议 + 运行时,让你不用自己去拼 Docker API、iptables、seccomp 这些底层。
它能做什么(功能):
- 用统一 API 创建 / 暂停 / 恢复 / 快照 / 销毁沙箱,底层可选 Docker(本地)或 Kubernetes(大规模分布式调度)。
- 在沙箱里执行命令、跑代码解释器(Jupyter 内核)、读写/搜索/替换文件、开交互式 PTY 终端。
- 给沙箱套更强的隔离:既能用 gVisor / Kata / Firecracker 这类安全容器运行时,也能在容器内部再用 bubblewrap 套一层「可回滚」的嵌套沙箱。
- 管网络进出:统一入站网关(ingress)按沙箱 ID 路由,逐沙箱出站策略(egress)按域名放行/拦截,还能用「 凭证保险箱」把真密钥注入到出站请求里而不让工作负载看到明文。
- 配套多语言 SDK(Python / Java / JS / .NET / Go)、
osbCLI、MCP server。
用起来什么样: 一段最小的 osb CLI 交互(取自 README.md):
osb sandbox create --image python:3.12 --timeout 30m -o json
# → 返回一个 sandbox-id,容器已在后台异步provision
osb command run <sandbox-id> -o raw -- python -c "print(1 + 1)"
# → 2
第一条走控制面(造出容器),第二条走数据面(在容器里执行)——这正是理解 OpenSandbox 的钥匙。
一句话直觉/类比: 把它想成「云函数的孪生兄弟」,但反过来:云函数给你无状态的一次调用,OpenSandbox 给你一台有状态、可交互、能装任何东西、随时能拍快照冻结再解冻的一次性电脑。控制面像酒店前台(发钥匙、开房、退房),数据面像房间里的服务电话(点餐、打扫、叫醒)。
本节不谈实现。记住一句话:「管容器的」和「在容器里干活的」是两拨代码、两套 API,故意分开。
2. 顶层全景(它大概怎么转)
OpenSandbox 是个多组件系统。先看谁是谁,再看一次请求怎么流。
2.1 部件一句话职责
| 部件 | 干什么 | 语言 / 位置 |
|---|---|---|
| 协议 specs | 用 OpenAPI 定义「生命周期 API」「执行 API」「出站 API」「诊断 API」的契约 | specs/*.yml *.yaml |
| server(控制面) | FastAPI 服务,收生命周期请求,决定用 Docker 还是 K8s 去创建/暂停/快照/销毁容器 | Python · server/opensandbox_server/ |
| execd(数据面) | 每个沙箱容器里都跑的 Go 守护进程,监听 44772 端口,提供命令/文件/PTY/代码解释器/嵌套隔离 | Go · components/execd/ |
| ingress(入站网关) | 反向代理,按 sandbox-id 从 header 或 URI 路由到对应容器,校验安全访问签名 | Go · components/ingress/ |
| egress(出站网关) | 每沙箱一个 sidecar,透明拦截出站流量,按域名策略放行/拦截,内含凭证保险箱 | Go · components/egress/ |
| SDK / CLI / MCP | 多语言客户端、osb 终端工具、MCP server,封装上面两套 API | sdks/ cli/ |
控制面 = Python,数据面/网络面 = Go。 这不是随意的:控制面要跟 Docker SDK、Kubernetes client、编排逻辑打交道(Python 生态顺手);数据面要塞进每个容器、常驻、低开销、直接摸 Linux namespace/seccomp(Go 单二进制顺手)。