☰
如何看懂 AgentENV 系统架构全景图:从 API 到 Firecracker 微虚拟机的完整数据流
2026/9/28 20:16:42 网站建设 项目流程

如何看懂 AgentENV 系统架构全景图:从 API 到 Firecracker 微虚拟机的完整数据流

【免费下载链接】AgentENVAgentENV (AENV) is a distributed platform for running agent environments at scale.项目地址: https://gitcode.com/gh_mirrors/age/AgentENV

AgentENV(AENV)是一个用于大规模运行 Agent 环境的分布式平台。本文带你从一张全景图出发,完整走通一个 HTTP 请求如何穿透 API 层、编排器,最终变成一台运行中的 Firecracker 微虚拟机(microVM),并解释快照、ublk 块设备与分布式控制平面在其中扮演的角色——这是理解 AgentENV 系统架构最快的路径。

一、30 秒看懂 AgentENV 系统架构全景

AgentENV 的核心目标只有一个:让 AI Agent 能跑在隔离、可快照、可秒级恢复的 Firecracker microVM 里,并且能在集群中水平扩展。

整个系统分两大平面:

平面组成职责
单节点平面(Rust 编写)API Server + Orchestrator + Firecracker + 存储子系统管理沙箱生命周期、块设备、网络、快照
分布式控制平面(Go 编写)Gateway + Scheduler多节点间的路由与节点选择

官方架构文档对这一全景有权威定义:

AgentENV 在隔离的、支持快照的 Firecracker microVM 中运行 AI Agent。其核心是一个存储子系统,提供可挂载进虚拟机的分层块设备,以及基于 ublk 的内存快照恢复。每个节点还有一个编排器管理沙箱生命周期,以及一个分布式控制平面(Gateway + Scheduler)负责多节点路由。

完整原文见 architecture.md。

二、核心组件地图:7 个关键模块与源码位置

下面这张表把全景图上的每个方块映射到了源码目录,方便你边读边对照代码:

组件源码位置一句话职责
API Serversrc/api/暴露 E2B 兼容的 HTTP API 与反向代理入口
Orchestrator 编排器src/orchestrator/沙箱生命周期状态机、持久化与自动清理
Firecracker 运行时src/sandbox/firecracker/创建并控制每个沙箱的 microVM
overlaybd 存储storage/overlaybd/基于 LSMT 的分层镜像,根文件系统层栈
ublk 块设备storage/ublk/用户态块设备服务,把镜像暴露为/dev/ublkbN
快照管理器src/snapshot/提交、解析、删除持久化快照
模板构建器src/template/构建用户模板并发布其提交后的快照

📌 一个值得注意的设计:存储 I/O 的"重活"被隔离在独立守护进程uvm-ublk-daemon(storage/ublk-daemon/)里,通过 Unix 域套接字 RPC 与节点主进程通信。这样 io_uring 控制与设备生命周期集中在一个进程,而节点服务器只负责编排状态,互不拖累。

三、完整数据流:一个创建沙箱请求的旅程

我们以POST /sandboxes(E2B 兼容接口)为例,追踪请求在节点内的完整路径。

第 1 站:API 层(Axum HTTP 服务器)

请求首先到达由 Axum 构建的 HTTP 服务器。在 server.rs 中可以看到路由装配顺序:先挂载生成的控制面 API 路由,再合并手写的/proxy/*反向代理入口、镜像构建路由与/metrics,最后叠加沙箱代理分类中间件和API Key 鉴权中间件。

鉴权在这里完成:所有控制面请求必须携带部署级X-API-Key。数据面流量(进入沙箱内部的请求)则由沙箱自身的凭证校验,两条路径严格分离。

第 2 站:编排器(生命周期状态机)

API 层验证请求后,交给编排器驱动状态转换。沙箱状态机定义了 8 个状态,定义在 types.rs:

Creating → Running → Pausing → Paused → Resuming → Running ↓ Killing

编排器同时负责三件事:

  • 持久化:沙箱元数据写入存储,节点重启后 Paused 沙箱依然可恢复
  • 自动驱逐:超时的沙箱被自动清理,释放 CPU 与内存
  • 增量指标:运行中沙箱数、已分配 CPU/内存等计数器随生命周期事件实时更新

第 3 站:Firecracker microVM 启动

编排器调用 Firecracker 后端(sandbox.rs)完成三件关键装配:

  1. 分配网络插槽:从网络插槽池取一个预热好的 network namespace(含 veth + TAP),避免冷启动时的命名空间创建开销
  2. 挂载块设备:通过 ublk 守护进程创建 overlaybd 块设备作为根文件系统/dev/vda,额外数据盘挂为/dev/vdb
  3. 启动 microVM:通过 Firecracker API socket 配置 CPU、内存、boot source 并触发启动

第 4 站:存储子系统——真正的性能核心 🔥

这是 AgentENV 架构中最精妙的部分。虚拟机看到的"磁盘"其实是一个分层镜像栈:

/dev/vda ← /dev/ublkbN(用户态 ublk 块设备) ↓ overlaybd 层栈 ├── upper(可读写层,最新写入) ├── layer N … layer 2(只读压缩层) └── layer 0(基础镜像层)

读路径:ImageFile 从顶层向下查找段索引,第一个包含该块映射的层提供服务数据;写路径:所有写入只追加到顶部可写层,底层只读层永远不被修改。

块设备怎么来的?Linux 内核 ublk 驱动 + 用户态服务(storage/ublk/src/ctrl.rs):

  1. 用户态通过 io_uring 向/dev/ublk-control发送ADD命令
  2. 内核分配设备 ID,创建/dev/ublkcN(控制)与/dev/ublkbN(块设备)
  3. 每个队列一个 worker 线程,异步处理内核分发的 I/O
  4. 虚拟机把它当作普通磁盘读写,零额外系统调用开销

分层镜像的三大好处:

  • 🚀按需加载:OCI 镜像层可从 registry/OSS 远程拉取,本地磁盘只作有界缓存,集群镜像总量可超出本地磁盘容量数个数量级
  • ⚡写时复制:同一模板启动的多个沙箱共享全部只读层,只有 upper 层独立
  • 📦快照即分层:暂停时上层被"封存"为新的只读层(create_snapshot_and_restack),再开一个全新 upper,整个过程不拷贝数据

四、快照数据流:为什么暂停 <100ms、恢复 <50ms

暂停(Pause)的完整数据流

aenv pause <id> → API: POST /sandboxes/{id}/pause → Orchestrator: Running → Pausing → Firecracker 创建 state-only diff 快照 → 查询脏内存区间,用 process_vm_readv 读取选中内存 → 直接生成 overlaybd 内存层(叠加在历史快照层之上) → 封存文件系统 upper 层 → SnapshotManager 提交到仓库(S3 兼容对象存储 / 分布式文件系统) → Orchestrator: Paused(元数据持久化)

内存与文件系统都走增量 diff:只记录自上次快照以来变化的部分,因此即使磁盘被大量修改,暂停也能在 100ms 内完成。核心提交逻辑见 manager.rs。

恢复(Resume)的完整数据流

恢复路径是快照架构的精华所在:

  1. 从快照仓库解析出层栈(固定产物会先尝试 P2P向同集群其他节点要,命中不了才回源对象存储)
  2. 从分层内存镜像创建一个只读 ublk 块设备,作为 Firecracker 的BackendType::File内存后端
  3. Firecracker 对块设备做 mmap,首次写入时 COW(写时复制)到匿名内存——底层设备永不被修改
  4. 同一快照恢复的多个沙箱引用计数共享同一个内存 ublk 设备,Linux 页缓存在它们之间复用,并发冷启动 I/O 大幅下降

💡 传统 userfaultfd 缺页填充方案被 ublk 方案取代:块设备 + 页缓存天然享受内核缓存,无需用户态缺页处理线程。旧实现仍保留在 storage/uffd-core/ 供参考。

五、网络数据流:每个沙箱一个隔离命名空间

每个运行中的沙箱拥有专用 Linux 网络命名空间,Firecracker 通过 TAP 设备接入,命名空间通过 veth 对连到宿主机。拓扑与报文路径详见 networking.md。

关键机制一览:

  • 地址规划:由插槽索引派生宿主机交互 IP、veth/31链路地址、VM 固定链路地址,内部地址池在用户放行规则之前被整体拒绝,沙箱之间完全隔离
  • 透明出口代理:需要域名策略时,命名空间内 TCP 80/443 被 REDIRECT 到本地代理(egress_proxy.rs),代理解析 SNI/Host 后查可信 DNS,策略失败即关闭(fail-closed)
  • 策略热替换:iptables-restore批处理原子替换命名空间规则链,存量连接不受影响
  • 网络预热池:(network slot, Firecracker 进程)对可以预先创建,恢复路径直接"移交",跳过 spawn 与 socket 等待

六、分布式控制平面:Gateway 与 Scheduler 如何协作

多节点部署时,客户端只面对一个 Gateway。数据流如下:

Client ──HTTP──> Gateway(:8080) ├─ 新沙箱 → gRPC Schedule() 选节点 ├─ 已有沙箱 → gRPC LookupNode() 查绑定 └─ 创建成功后 → RecordAssignment() 播种沙箱→节点绑定 ↓ 反向代理 HTTP Node A / Node B (:8000)
  • Gateway(services/gateway/):HTTP 反向代理。从路由头(x-agentenv-sandbox-id/e2b-sandbox-id)或基于 Host 的代理域名({port}-{sandboxID}.{domain})提取数据面路由;控制面路由(如 pause)按 URL 路径中的沙箱 ID 路由。它还聚合GET /sandboxes、GET /nodes等跨节点列表请求
  • Scheduler(services/scheduler/):gRPC 服务,维护内存中的沙箱→节点绑定表。RPC 包括Schedule、LookupNode、RecordAssignment、Heartbeat等,契约见 scheduler.proto。调度策略支持round_robin(默认)与random
  • 绑定生命周期:运行时节点心跳携带完整沙箱 ID 清单,调度器将其视为事实来源,心跳中缺失的绑定会被清除;节点下线时UnregisterNode主动清理其名下绑定
  • 节点发现:支持static(配置显式列表)与kubernetes(watch EndpointSlice,取就绪 DaemonSet Pod IP)两种模式

⚠️ 一个诚实的设计取舍:所有绑定都在内存中,Scheduler 重启后绑定丢失,但会通过"新沙箱创建 + 各节点下一次心跳清单"自动重建。

可选加速层——P2P 制品传输(src/p2p/):快照提交成功后,固定 Firecracker 产物与 overlaybd 层会经 P2P 层尽力广播;解析时先问 P2P 再问对象存储,让制品在集群内自然扩散。调度器只存/返透明的 peer 端点,真正的目录查询与字节传输全部走节点直连。

七、架构全景速查:源码目录对照表

目录内容
src/api/HTTP API 层(E2B 兼容端点 + 反向代理)
src/orchestrator/沙箱生命周期状态机与持久化
src/sandbox/Firecracker 管理、网络命名空间、ublk 集成
src/snapshot/快照仓库后端、运行时解析、P2P 发布
src/template/用户模板构建器
storage/overlaybd/LSMT 分层镜像核心(本地/registry/tar 后端)
storage/ublk/ + storage/ublk-daemon/用户态块设备与守护进程
services/gateway/ + services/scheduler/分布式控制平面(Go)

📖 延伸阅读(仓库内官方文档):

  • 架构总览:docs/src/internals/architecture.md
  • 沙箱网络:docs/src/internals/networking.md
  • 反向代理设计:docs/src/internals/proxy-design.md
  • P2P 设计:docs/src/internals/p2p-design.md
  • 控制平面服务:docs/src/internals/services.md

八、总结:AgentENV 架构设计的三个关键洞察

  1. 存储即架构:AgentENV 的性能故事完全由存储子系统书写——overlaybd 分层镜像让"镜像仓库"变成集群级无限缓存,ublk 让块 I/O 停留在用户态却享受内核级效率
  2. 快照 = 分层 + 写时复制:文件系统快照是"封存上层",内存快照是"只读块设备 + COW",两者都不做全量拷贝,这才有了暂停 <100ms、恢复 <50ms 的硬指标
  3. 平面分离、进程隔离:API 编排、块 I/O、分布式路由分属不同进程(乃至不同语言栈),每个平面只对自己的延迟敏感路径负责,互不拖累

理解了这个"API → Orchestrator → Firecracker → ublk → overlaybd"的数据流主链,你就掌握了 AgentENV 系统架构的骨架——无论是排查一次慢启动,还是评估如何扩展集群,都能从这张全景图快速定位到正确的模块。

【免费下载链接】AgentENVAgentENV (AENV) is a distributed platform for running agent environments at scale.项目地址: https://gitcode.com/gh_mirrors/age/AgentENV

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询