Cloudflare Computer容器沙箱架构拆解:FUSE + computerd + capnweb全景图
【免费下载链接】computerGive your agent a computer 👾项目地址: https://gitcode.com/GitHub_Trending/computer1/computer
Cloudflare Computer 是一个"给 AI Agent 一台真实计算机"的开源项目:它在 Durable Object 里用 SQLite 持久化一份虚拟文件系统,再通过容器沙箱把这份文件投射成真实的 FUSE 挂载,让 Agent 能像操作本地电脑一样跑 shell 与任意二进制。本文拆解这套容器沙箱架构的三大核心——FUSE 挂载机制、容器内守护进程 computerd 与双向同步的 capnweb 协议,帮你看懂整张架构全景图。
💡 图中两条黄色批注点出了关键事实:容器侧是"内存虚拟文件系统 + FUSE 挂载",而 DO 侧的SQLite 才是文件系统的唯一事实来源(source of truth)——容器重启也不影响数据安全。
三大核心角色:一分钟看懂分工
| 角色 | 所在位置 | 核心职责 |
|---|---|---|
| Durable Object (DO) | 云端隔离运行时 | 以 SQLite 持久化虚拟文件系统,是文件状态的唯一事实来源,对外提供fs读写 API |
| computerd | 容器内守护进程 | 把内存 VFS 挂载为 FUSE 文件系统(默认/workspace),执行 shell 命令并回传输出流 |
| capnweb 通道 | DO ↔ 容器之间 | 一条长连接 WebSocket,承载双向增量文件同步 + exec 事件流 |
设计上一个 DO 与一个容器实例1:1 绑定:WebSocket 对端唯一无歧义,同步水位(watermark)只面向单一对方,也为未来的 DO 休眠(hibernation)留好了门。
FUSE 挂载:容器如何看见"同一份文件"
FUSE(Filesystem in Userspace)让 computerd 以用户态程序向 Linux 内核"伪装"出一个文件系统,容器里的任何进程——node、shell、编译器——访问/workspace时,实际读写的是 computerd 管理的内存 VFS:
- 自带 Node 的单体二进制:computerd 是 Node SEA 单文件可执行程序,内嵌 Node 运行时、
fuse-native预编译件与libfuse,镜像里无需安装 Node,apt装个fuse3即可。 - 路径绝对一致:VFS 中的
/workspace/repo/a.txt在容器进程眼中就是同一个绝对路径,fsAPI、exec命令与同步协议三方对齐。 - 没有 FUSE 也能跑:
FUSE_MOUNT=auto会自动探测——有/dev/fuse就挂真实内核 FUSE;没有(常见于 CI 和普通容器)则透明降级为用户态 shim:把 VFS 文件实体化写到磁盘并双向轮询同步,本地开发体验完全不受影响。 - 三步启动序列:启动二进制 → 轮询
GET /health直至 200 → 建立 capnweb 会话。会话方向可以是 DO 直连/ws,也可以是容器经POST /connect反向拨号(让流量穿过 DO 可控的路由),详见 docs/07_injected_service.md。
computerd:容器里的隐形文件管理员
computerd 是一个"管文件、跑命令、开接口"的三合一守护进程:
- HTTP/WS 服务面:
/health健康探针、/api(HTTP-batch RPC)、/ws(WebSocket RPC,主同步载体)、/__computerd/stats(观测表行数、孤儿 blob 字节数、进程内存,排障第一入口)。 - 写模型:字节归属权在 DOFS 虚拟文件系统层,computerd 内部没有逐文件暂存缓冲——
create/open直接挂接写缓冲,write/truncate原地修改,release时单文件一个事务落盘到vfs_chunks,打开窗口内的读取总能看见最新字节。 - 源码位置:packages/computerd/,官方 Dockerfile 配方见 examples/container/Dockerfile。
capnweb 同步协议:双向增量同步如何工作
两侧各维护一个单调递增的 revision 计数器,DO→容器的 push 与容器→DO 的 pull 各走各的时钟,谁也不需要重发整棵树:
- Coalesce 合并:两次 exec 之间同一路径被改写 5 次?线上只传 1 条(最终状态赢)。
- 字节不内联:变更条目只带 chunk 哈希,发送方先探测
hasObjects,只补传接收方缺失的对象——天然去重、天然省带宽。 - 最终状态制:线上只有"活条目 + 墓碑",没有 rename 之类的操作指令,apply 幂等、无需按操作顺序重放;崩溃中途 pull 最多重放 256 条一批。
- 冲突处理:last-writer-wins,收敛树形而不纠结过程。
协议细节见 docs/02_sync_protocol.md,线类型定义在 packages/rpc/。
一次 exec 调用的完整数据链路
以workspace.runtime.exec("npm test")为例,整条链路分六步:
- Push— DO 把容器尚未见过的所有 revision 合并后推给容器;
- Hydrate— 命令可能触碰的懒加载挂载桩(lazy mount)从数据源取来,随批下发;
- Exec— 命令执行,FUSE 写入被容器内 VFS 实时捕获并打上新 revision;
- Fetch— 命令返回后,DO 按
(rev, path)游标拉取变更流; - Diff— DO 对照本地
vfs_blobs,只 fetch 缺失的 blob chunk; - Apply— 按 256 条一批写入 SQLite,每批一个已提交事务,游标按批推进。
结果:fs写入对exec立即可见,反之亦然,且全程崩溃可恢复。生命周期与休眠策略见 docs/11_lifecycle.md。
性能实测:FUSE 挂载快在哪、慢在哪 📊
官方基准(standard-2 容器,对比 ext4 磁盘与 tmpfs)结论很清晰:
| 场景 | computerd vs ext4 磁盘 | 结论 |
|---|---|---|
| stat 1000 个文件 | 0.91x | ✅ 快于磁盘 |
| rm 1000 个文件 | 0.66x | ✅ 快于磁盘 |
| mkdir / find 万级目录树 | 0.72x ~ 0.74x | ✅ 快于磁盘 |
| git init + commit 100 文件 | 0.72x | ✅ 快于磁盘 |
| 读取 64 MiB 大文件 | 约 20x ~ 40x | ❌ 明显更慢 |
| 完整 npm install(854 包、3.6 万文件) | 124.7s vs 63.9s | ❌ 约为磁盘 2 倍 |
一句话总结:元数据密集型操作(git status、模块解析、增量构建)内存 inode 存储全面胜出;大文件顺序 I/O 是已知代价——根源是每个 512 KiB chunk 都要做内容寻址哈希写入 blob 库。完整数字见 docs/19_performance.md。
上手与源码导航 📍
想动手跑一遍,先克隆仓库:
git clone https://gitcode.com/GitHub_Trending/computer1/computer
| 想了解的模块 | 路径 |
|---|---|
| 设计规格总览(19 篇专题文档) | docs/ |
| SQLite 虚拟文件系统 + 同步构件 | packages/dofs/ |
| capnweb 线类型与客户端/服务端 | packages/rpc/ |
| computerd 守护进程(FUSE + RPC) | packages/computerd/ |
| 顶层 Workspace 包(fs / runtime) | packages/computer/ |
| 最小可运行容器示例 | examples/container/ |
总结:Cloudflare Computer 用"DO 侧 SQLite 事实来源 + 容器侧 FUSE 内存镜像 + capnweb 双向增量同步"三板斧,把一台安全、持久、随时可重启的"Agent 计算机"装进了一个容器镜像。看懂这张全景图后,你在读任何 sandbox 类项目时都会发现:难点从来不是隔离本身,而是让两侧对同一份文件保持低延迟、可恢复的一致。
【免费下载链接】computerGive your agent a computer 👾项目地址: https://gitcode.com/GitHub_Trending/computer1/computer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考