CubeSandbox 源码阅读地图
这篇文章是整个「源码学习」栏目的入口。它帮你回答一个最朴素的问题:
我想读懂 CubeSandbox 的源码,应该从哪里开始?
1. 全局组件拓扑
先把 8 个核心组件的位置和职责记下来。
一句话记忆:
- CubeAPI 是对外兼容层,Rust 写的 axum 服务
- CubeMaster 是控制面大脑,Go 写的编排调度器
- Cubelet 是节点守护进程,管理单机所有沙箱
- CubeShim 是 containerd Shim v2 实现,桥接容器运行时与 guest
- agent 是来宾虚机里的 PID 1,负责 exec / stdio / 监控
- CubeProxy 是 OpenResty 反向代理,按 Host 路由到目标沙箱
- CubeVS 是 eBPF 数据面,做 ARP 代理 / NAT / 策略
- network-agent 是节点网络编排服务,管理 TAP / IP / 端口
2. 一次请求的生命周期
从 SDK 发起 create_sandbox() 到 tool call 执行完毕,请求穿过了两条完全不同的路径。
关键区分:
| 维度 | 控制面 | 数据面 |
|---|---|---|
| 职责 | 创建、调度、销毁沙箱 | 在已有沙箱里执行代码/命令 |
| 入口 | CubeAPI → CubeMaster → Cubelet | SDK → CubeProxy → envd |
| 协议 | REST / gRPC | HTTP 流式 / WebSocket |
| 文章 | 从一次创建请求看完整控制链路 | 从一次 run_code 看完整数据链路 |
3. 源码学习导航
本栏目按 6 个分组组织文章,每组对应一个源码子系统。
3.1 总览与阅读路径
| 文章 | 适合谁 |
|---|---|
| 从一次创建请求看完整控制链路 | 想理解"沙箱怎么创建出来"的读者 |
| 从一次 run_code 看完整数据链路 | 想理解"tool call 怎么执行"的读者 |
| 源码对象索引 | 想快速定位某个对象在哪个文件的读者 |
3.2 CubeAPI:入口层
| 文章 | 核心问题 |
|---|---|
| CubeAPI 是怎么接住第一个请求的 | axum 框架、路由注册、中间件栈 |
| E2B 兼容接口如何映射到内部模型 | 外部字段 → 内部 CreateSandboxRequest |
| 中间件、鉴权与错误处理 | 鉴权回调、限流、AppError |
3.3 CubeMaster:控制面
| 文章 | 核心问题 |
|---|---|
| 进程启动与服务注册 | main → coreInit → server.New 启动链 |
| 创建沙箱时 CubeMaster 做了哪些事 | constructCreateReq → CreateSandbox 全链路 |
| 调度器到底看什么做决策 | 5 阶段 selector 管线 |
3.4 Cubelet:节点面(即将上线)
Cubelet 进程启动、RunCubeSandbox 节点侧流程、Destroy 回收顺序、Exec vs Commands.Run、Snapshot/Commit、cubebox 插件、workflow 引擎。
3.5 CubeShim & Agent:Runtime(即将上线)
CubeShim 角色、containerd 任务传播、agent 作为 init 进程、ttrpc/vsock 通信、stdio/exec 进程管理。
3.6 网络与数据面(即将上线)
network-agent EnsureNetwork、TAP 池、CubeVS ARP/NAT/策略、CubeProxy Host 路由与 Path 路由。
3.7 SDK 与案例(即将上线)
SDK 表面模型、CUBE_PROXY_NODE_IP 直连模式、从 examples 反推能力边界。
4. 建议阅读顺序
如果你是第一次读 CubeSandbox 源码:
- 先看架构概览建立系统全貌
- 再看本文(源码阅读地图)理解组件关系
- 然后按兴趣选一条路径深入:
- 关心沙箱怎么创建 → 创建链路阅读路径
- 关心 tool call 怎么执行 → run_code 阅读路径
如果你已经读过架构文:
直接从 CubeAPI 入口 开始,按控制面 → 节点面 → Runtime → 网络的顺序推进。
延伸阅读
- 架构概览 — 系统级组件关系
- 一个沙箱的生命周期 — 端到端生命周期概述
- 调度是怎么做的 — 调度算法高层解读
- 模板如何变成可运行沙箱 — 模板供应链概述