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.SandboxActioncube.HttpHandler
CubeMaster/pkg/service/httpservice/cube/sandbox_create.gocreateSandbox()constructCreateReq() → 模板合并 → 亲和性
CubeMaster/pkg/service/sandbox/sandbox_run.goCreateSandbox()createSandboxContextnewContext()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()

延伸阅读