Skip to content

从一次创建请求看完整控制链路 ​

当你调用 sdk.sandbox.create(template_id="my-template") 时,请求穿过了 CubeAPI、CubeMaster、Cubelet 三个组件,最终在某台节点上启动了一个 MicroVM。

这篇文章把这条链路拆开,告诉你每一步该去读哪个源码文件。


1. 总览:创建请求经过了哪些组件 ​


2. 第一站:CubeAPI — 对外兼容层 ​

你要读的文件 ​

文件看什么
CubeAPI/src/main.rsCLI 参数、AppState 构建、axum server 启动
CubeAPI/src/routes.rsbuild_router() → build_e2b_router() + build_cubeapi_router()
CubeAPI/src/handlers/sandboxes.rscreate_sandbox() handler 入口
CubeAPI/src/services/sandboxes.rsSandboxService::create_sandbox() 字段映射逻辑
CubeAPI/src/cubemaster/mod.rsCubeMasterClient::create_sandbox() HTTP 调用

关键函数调用链 ​

main() → Cli::parse() → AppState::new() → build_router() → axum::serve()
    ↓
POST /sandboxes → sandboxes::create_sandbox()
    ↓
SandboxService::create_sandbox(body)
    ↓
  body.template_id → annotations["cube.master.appsnapshot.template.id"]
  body.timeout     → req.Timeout
  body.metadata    → req.Labels
  instance_type    → "cubebox" (default)
  network_type     → "tap" (default)
    ↓
CubeMasterClient::create_sandbox(&CreateSandboxRequest)
    ↓
POST {cubemaster_url}/cube/sandbox

下一步 ​

→ 继续读 CubeMaster 的 /cube/sandbox handler


3. 第二站:CubeMaster — 控制面大脑 ​

你要读的文件 ​

文件看什么
CubeMaster/pkg/server/server.goregisterHandlers() 路由注册,cube.SandboxAction → cube.HttpHandler
CubeMaster/pkg/service/httpservice/cube/sandbox_create.gocreateSandbox() → constructCreateReq() → 模板合并 → 亲和性
CubeMaster/pkg/service/sandbox/sandbox_run.goCreateSandbox() → createSandboxContext → newContext() → Handle() → handleCubelet()
CubeMaster/pkg/scheduler/schedule.goSelect() 五阶段调度
CubeMaster/pkg/scheduler/init.goInitScheduler() 注册 prefilter / filter / score / backoff

关键函数调用链 ​

cube.HttpHandler → createSandbox(r)
    ↓
constructCreateReq(r)
    ↓ 补默认值
  labels / annotations 非空
  instance_type = "cubebox"
  network_type = "tap"
  namespace = "default"
    ↓
dealCubeboxCreateReqWithTemplate(ctx, req)
    ↓ 合并模板定义中的镜像、rootfs、端口等
runInsReq2Affinity(ctx, req)
    ↓ 从 annotation / 配置 / 大规格策略构造 NodeSelector
sandbox.CreateSandbox(ctx, req)
    ↓
createSandboxContext.newContext()
    ↓ selctx.New() + ConstructCubeletReq() + checkAndGetReqResource()
scheduler.AddBufferTask(createCtx, instanceType)
    ↓
createCtx.Handle() → handleCubelet()
    ↓ 循环
  schedule() → scheduler.Select(selctx)
    ↓ prefilter → filter → score → postscore → LeastRandomSelect
  callCubelet() → gRPC RunCubeSandbox
    ↓ 成功: dealSuccResult() / 失败: 重试 or 换节点

下一步 ​

→ 继续读 Cubelet 的 RunCubeSandbox 节点侧流程


4. 第三站:Cubelet — 节点执行面 ​

你要读的文件 ​

文件看什么
Cubelet/services/cubebox/沙箱生命周期管理(create / destroy / update)
Cubelet/plugins/workflow/工作流引擎,编排节点侧步骤
Cubelet/plugins/cube/容器 / MicroVM 创建插件
Cubelet/plugins/network/网络准备(TAP / IP / 端口)
Cubelet/plugins/snapshots/快照恢复

关键动作 ​

  1. 网络准备:借出 TAP 设备、分配 IP、配置端口映射
  2. 存储准备:挂载 rootfs、准备可写层
  3. 运行时创建:通过 CubeShim 启动 containerd 任务 → CubeHypervisor 创建 MicroVM
  4. Agent 启动:guest 内 agent 作为 PID 1 启动,注册 vsock 服务
  5. 路由注册:将 sandboxID → hostIP:port 映射写入 Redis,供 CubeProxy 使用

5. 完整链路速查表 ​

阶段组件关键文件关键函数
API 入口CubeAPIservices/sandboxes.rsSandboxService::create_sandbox()
HTTP 转发CubeAPIcubemaster/mod.rsCubeMasterClient::create_sandbox()
请求兜底CubeMasterhttpservice/cube/sandbox_create.goconstructCreateReq()
模板合并CubeMasterhttpservice/cube/sandbox_create.godealCubeboxCreateReqWithTemplate()
亲和性CubeMasterservice/sandbox/affinityutil.gorunInsReq2Affinity()
调度上下文CubeMasterservice/sandbox/sandbox_run.gonewContext()
节点选择CubeMasterscheduler/schedule.goSelect()
下发 CubeletCubeMasterservice/sandbox/sandbox_run.gocallCubelet()
节点创建工作流Cubeletplugins/workflow/workflow engine
路由注册CubeMasterservice/sandbox/sandbox_run.gosetProxyToRedis()

延伸阅读 ​