容器沙盒知识点补充
容器沙盒知识点补充
本文档为 2026-04-29 容器沙盒方案深度对比 的配套知识库,从底层原理出发帮助小白理解容器沙盒涉及的核心技术。
知识来源:知乎专栏、AWS 官方文档、Google gVisor 博客、Linux 内核文档、Red Hat 技术博客等。
一、容器隔离的底层"积木"
容器不是虚拟机。它本质上是一个被施加了多重限制的普通 Linux 进程。理解容器沙盒,首先要理解 Linux 内核提供的这几块"积木":
┌─────────────────────────────────────────────┐
│ 应用进程 (PID 1001) │
├─────────────────────────────────────────────┤
│ Namespaces │ cgroups │ seccomp │ Cap │ ← 四大限制机制
├─────────────────────────────────────────────┤
│ Linux 内核 │
├─────────────────────────────────────────────┤
│ 硬件 / KVM │
└─────────────────────────────────────────────┘
1.1 Linux Namespaces(命名空间)— "看不见别人"
核心概念
- Namespace 是内核级的资源隔离机制,每个命名空间内都有独立的资源实例
- 一个进程可以拥有多个命名空间(PID、Net、Mount 等),也可以与其他进程共享某些命名空间
- 同一 namespace 中的进程可以互相影响,不同 namespace 中的进程互不干扰
- 即使用 chroot 限制了根目录,也不能阻止进程创建设备文件(需要 device namespace)
八种命名空间(Linux 3.8+ 完整支持)
| 命名空间 | 隔离内容 | 实际效果 | 引入版本 |
|---|---|---|---|
| Mount | 文件系统挂载点 | 容器有自己的根文件系统,看不到宿主的其他挂载 | 2.4.19 |
| UTS | 主机名和域名 | 容器可以有自己的 hostname | 2.6.19 |
| IPC | 进程间通信资源 | 信号量、消息队列、共享内存相互隔离 | 2.6.19 |
| PID | 进程 ID | 容器内 PID 从 1 开始,看不到宿主进程 | 2.6.24 |
| Network | 网络栈 | 独立的网卡、IP、路由表、端口范围 | 2.6.29 |
| User | 用户和组 ID | 容器内 root (UID 0) 映射到宿主的普通用户 | 3.8 |
| Cgroup | cgroup 根目录 | 容器看不到宿主的 cgroup 层级 | 4.6 |
| Time | 系统时钟 | 容器可以有独立的系统时间(Linux 5.6+) | 5.6 |
clone() 系统调用
创建命名空间的核心方式是通过 clone() 系统调用的标志位:
// 创建一个拥有独立 PID 和 Network 命名空间的子进程
clone(child_func, stack,
CLONE_NEWPID | CLONE_NEWNET | SIGCHLD, NULL);
在已有进程上也可以通过 setns() 加入已有命名空间,或 unshare() 在当前进程上创建新命名空间。
深入理解
为什么需要 Network Namespace?
1.2 cgroups v2(控制组)— "限制资源用量"
核心概念
- cgroups 限制进程组的资源使用:CPU、内存、磁盘 IO、网络带宽等
- Linux 有两种 cgroups 版本:v1(旧)和 v2(新),v2 是现代标准
- cgroups v2 是 Linux 内核 4.5 开始引入的,RHEL 9 等新发行版已默认使用
- cgroups 的配置体现为文件系统的目录和文件(通常挂载在
/sys/fs/cgroup)
cgroups v2 vs v1
| 特性 | v1 | v2 |
|---|---|---|
| 层级结构 | 每种资源控制器独立层级 | 统一层级,所有控制器共享 |
| 进程归属 | 进程可以属于不同层级 | 每个进程只属于一个 cgroup |
| 线程支持 | 有限 | 更完善的线程级控制(threaded mode) |
| PSI(Pressure Stall Information) | ❌ | ✅ 监控 CPU/内存/IO 压力 |
| 内存管理 | 每个控制器独立管理 | 统一的内存管理 |
cgroup 文件系统示例
# cgroups 的配置本质就是写文件
# 限制某个进程组最多使用 512MB 内存
echo 536870912 > /sys/fs/cgroup/my-container/memory.max
# 限制 CPU 配额
echo "50000 100000" > /sys/fs/cgroup/my-container/cpu.max # 50% CPU
# 把一个进程加入 cgroup
echo $PID > /sys/fs/cgroup/my-container/cgroup.procs
主要资源控制器
| 控制器 | 功能 |
|---|---|
cpu |
CPU 时间分配(CFS 配额) |
cpuset |
绑定到特定 CPU 核心 |
memory |
内存使用限制 |
io |
块设备 IO 带宽限制 |
pids |
限制进程/线程数量 |
rdma |
RDMA 资源限制 |
hugetlb |
大页内存限制 |
与安全的关系
1.3 seccomp(安全计算模式)— "禁用危险系统调用"
发展历史
2005 Linux 2.6.12 引入 seccomp(严格模式)
只允许 read/write/exit/sigreturn 四个系统调用
目的:把服务器闲置 CPU 出借给不可信程序
2012 Linux 3.5 引入 seccomp-BPF(过滤模式)
允许自定义 BPF 规则过滤任意系统调用
真正实用化
2015 Docker 默认启用 seccomp profile
禁用约 44 个危险系统调用,允许约 300+ 个
至今 成为容器安全标配
两种模式
严格模式(SECCOMP_MODE_STRICT):
- 只允许 4 个系统调用:
read()、write()、exit()、sigreturn() - 调用其他任何系统调用 → 进程直接被
SIGKILL终止 - 适用场景极窄(如纯计算任务)
过滤模式(SECCOMP_MODE_FILTER):
- 使用 BPF(Berkeley Packet Filter)程序定义过滤规则
- 可以精确匹配系统调用号和参数
- 不匹配的调用可以:返回错误码、发送信号、通知追踪器、直接杀进程
seccomp-BPF 的返回值
| 返回值 | 行为 |
|---|---|
SECCOMP_RET_KILL_PROCESS |
立即终止整个进程 |
SECCOMP_RET_TRAP |
发送 SIGSYS 信号给进程 |
SECCOMP_RET_ERRNO |
返回指定的错误码(如 EPERM) |
SECCOMP_RET_USER_NOTIF |
通知用户空间程序处理(用于容器管理器拦截特定调用) |
SECCOMP_RET_TRACE |
通知 ptrace 追踪器 |
SECCOMP_RET_LOG |
允许调用但记录日志 |
SECCOMP_RET_ALLOW |
允许调用 |
Docker 默认 seccomp profile 实战
Docker 的默认配置文件是一个白名单:
defaultAction: SCMP_ACT_ERRNO(默认拒绝)- 逐一列出允许的系统调用(约 300+ 个)
- 禁用了约 44 个危险系统调用
被禁用的典型系统调用:
| 系统调用 | 禁用原因 |
|---|---|
mount / umount |
防止挂载/卸载文件系统 |
reboot |
防止重启宿主机 |
swapon / swapoff |
防止操作交换空间 |
ptrace |
防止追踪其他进程(可能泄露宿主信息) |
kexec_load |
防止加载新内核 |
keyctl |
防止使用未命名空间的内核密钥环 |
bpf |
防止加载 BPF 程序 |
unshare |
防止创建新命名空间 |
userns |
防止创建用户命名空间 |
在 Kubernetes 中使用 seccomp
# 使用容器运行时的默认 seccomp profile
apiVersion: v1
kind: Pod
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
# 使用自定义 seccomp profile
apiVersion: v1
kind: Pod
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/audit.json
seccomp 的局限性
1.4 Linux Capabilities(能力)— "细分 root 权限"
核心概念
传统 Linux 只有两种权限:普通用户和 root(全能)。Capabilities 将 root 权限拆分为独立的能力单元:
| Capability | 控制的能力 |
|---|---|
CAP_NET_BIND_SERVICE |
绑定 1024 以下端口 |
CAP_SYS_ADMIN |
超级大杂烩:mount、namespaces、设备操作等 |
CAP_NET_RAW |
使用原始套接字(ping、网络嗅探) |
CAP_SYS_PTRACE |
追踪其他进程 |
CAP_DAC_OVERRIDE |
绕过文件权限检查 |
CAP_CHOWN |
修改文件所有者 |
Docker 默认赋予容器的 Capabilities(约 14 个),远少于完整的 root 权限。可以通过 --cap-drop 和 --cap-add 精确控制。
二、容器逃逸:为什么需要更强的隔离?
2.1 容器逃逸的三种典型路径
① 内核漏洞(最严重)
- CVE-2016-5195(Dirty COW):Linux 内核竞态条件漏洞,容器内普通用户可以修改只读内存映射获得 root 权限
- CVE-2022-0185:文件系统层堆溢出漏洞,非特权用户利用
mount()系统调用创建嵌套挂载,触发溢出逃逸到宿主
② 特权容器
- 使用
--privileged启动的容器拥有宿主的全部 Capabilities - 可以访问宿主设备文件(如
/dev/sda) - 攻击者可以直接挂载宿主磁盘
③ 危险配置
- 挂载了 Docker socket(
/var/run/docker.sock) - 挂载了宿主敏感目录(
/etc、/root) seccomp=unconfined禁用了系统调用过滤
2.2 容器安全的防御层次
┌─────────────────────────────────────────┐
│ 第 1 层:Namespace(可见性隔离) │ ← 看不到别人
├─────────────────────────────────────────┤
│ 第 2 层:Capabilities(权限裁剪) │ ← 权限受限
├─────────────────────────────────────────┤
│ 第 3 层:seccomp(系统调用过滤) │ ← 危险操作被拦
├─────────────────────────────────────────┤
│ 第 4 层:cgroups(资源限制) │ ← 资源耗尽攻击
├─────────────────────────────────────────┤
│ ❌ 共享内核(根本性风险) │ ← 内核漏洞 = 逃逸
└─────────────────────────────────────────┘
对比:MicroVM 方案
┌─────────────────────────────────────────┐
│ 第 1 层:硬件虚拟化(KVM) │ ← 独立内核,逃逸需突破虚拟化层
├─────────────────────────────────────────┤
│ 第 2 层:Jailer(seccomp + namespace) │ ← VMM 进程自身也被限制
├─────────────────────────────────────────┤
│ 第 3 层:极简设备模型 │ ← 攻击面极小
└─────────────────────────────────────────┘
三、gVisor — 用户态内核
3.1 核心架构
传统容器: gVisor:
┌──────────┐ ┌──────────┐
│ 应用 │ │ 应用 │
│ libc │ │ libc │
├──────────┤ ├──────────┤
│ Linux 内核│ │ Sentry │ ← 用户态内核(Go 实现)
│ (共享!) │ │ (Go) │ 拦截 ~237 个系统调用
├──────────┤ ├──────────┤
│ 硬件 │ │ Linux 内核│
└──────────┘ ├──────────┤
│ 硬件 │
└──────────┘
三个核心组件:
| 组件 | 功能 |
|---|---|
| Sentry | 应用内核,拦截并实现所有系统调用(Go 实现,~237 个 syscall) |
| Gofer | 文件系统代理,负责宿主机文件 IO(独立进程,通过 9P 协议通信) |
| Runsc | OCI 兼容运行时,管理沙箱生命周期 |
3.2 工作原理
拦截方式:
| 系统调用类型 | 拦截方式 |
|---|---|
| 快速路径(read/write/close 等) | 通过 PTRACE_SYSEMU ptrace 方式拦截 |
| 慢速路径(open、connect、mmap 等) | 需要额外 IPC 到 Gofer |
| 信号处理 | Sentry 利用 Linux 信号机制,通过 SIGSYS 注入处理逻辑 |
关键数据:
- Sentry 实现了约 237 个 Linux 系统调用,覆盖绝大多数应用需求
- 每个容器(Sandbox)运行在独立的 Sentry 内核中
- 每个 Sentry 拥有独立的内核地址空间和虚拟文件系统
3.3 KVM 平台模式(更深度的隔离)
gVisor 最初使用 ptrace 拦截,后来增加了 KVM 平台模式:
ptrace 模式:gVisor 和应用共享同一进程地址空间,通过 ptrace 拦截
KVM 模式:应用运行在 KVM 虚拟化的 guest ring3,
guest ring0 运行 Sentry(gVisor 自己的 ring0 代码)
系统调用触发 VM Exit → Sentry 在 host ring0 处理
3.4 gVisor 的局限性
| 局限 | 说明 |
|---|---|
| 性能损耗 | 快速路径损耗 2x-3x,慢速路径(open/close/mmap)损耗高达 4x-20x |
| 兼容性 | 只实现 237 个 syscall,复杂应用可能不兼容(如使用 io_uring 的应用) |
| 功能缺失 | 不支持 SCM_RIGHTS、部分 socket 选项、io_uring 等 |
| ptrace 模式的安全问题 | 不能有效阻止 TOCTOU 攻击 |
| 适合场景有限 | 最适合非持久化、无状态、可扩展的计算型工作负载(如 AWS Lambda) |
3.5 gVisor vs Kata Containers
| 维度 | gVisor | Kata Containers |
|---|---|---|
| 本质 | 用户态内核(拦截 syscall) | 完整虚拟机(独立 Linux 内核) |
| 启动速度 | 快(无需启动完整内核) | 较慢(需要启动 guest 内核) |
| 内存开销 | 低 | 较高(每个容器一个内核) |
| 兼容性 | 受限(237 个 syscall) | 好(完整 Linux 内核,兼容所有 syscall) |
| 适用负载 | 无状态、短生命周期 | 有状态、长运行、传统应用 |
| 性能 | IO 密集型场景损耗大 | 接近原生 VM 性能 |
| 安全性 | 用户态隔离 + 可选 KVM | 硬件虚拟化隔离 |
四、Firecracker — 极简 MicroVM
4.1 为什么需要 Firecracker?
AWS Lambda 的演进之路:
2014 Lambda 发布 → 每个租户独立 EC2 实例(太重、太慢)
2015 尝试 Docker 容器 → 安全隔离不足(共享内核)
2017 开发 Firecracker → 兼具 VM 安全性 + 容器速度
2018 开源 Firecracker
至今 Lambda + Fargate 全面使用 Firecracker MicroVM
4.2 架构设计
┌──────────────────────────────────────┐
│ Firecracker 进程 │
│ ┌─────────────────────────────────┐ │
│ │ API Server (RESTful) │ │ ← 配置网卡、磁盘、启动参数
│ ├─────────────────────────────────┤ │
│ │ VMM (Virtual Machine Manager) │ │ ← 管理 MicroVM 生命周期
│ ├─────────────────────────────────┤ │
│ │ 设备模型(极简) │ │ ← 只保留必要设备
│ │ - virtio-net │ │
│ │ - virtio-blk │ │
│ │ - virtio-vsock │ │
│ │ - serial console │ │
│ │ - 仅关机键的键盘 │ │
│ ├─────────────────────────────────┤ │
│ │ KVM │ │ ← 硬件虚拟化
│ └─────────────────────────────────┘ │
└──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ MicroVM (Guest) │
│ ┌─────────────────────────────────┐ │
│ │ 精简 Linux 内核 │ │ ← AWS 定制裁剪
│ │ 最小化 rootfs │ │
│ │ 单个应用容器 / 函数 │ │
│ └─────────────────────────────────┘ │
└──────────────────────────────────────┘
4.3 Firecracker 的"减法哲学"
与 QEMU 对比,Firecracker 做了大量裁剪:
| 组件 | QEMU | Firecracker | 裁剪原因 |
|---|---|---|---|
| BIOS | SeaBIOS | ❌ 移除 | MicroVM 不需要传统 BIOS 启动流程 |
| PCI 总线 | ✅ | ❌ 移除 | 只用 virtio 直通,不需要 PCI 枚举 |
| VGA 显示 | ✅ | ❌ 移除 | 无头计算不需要图形输出 |
| USB / Sound | ✅ | ❌ 移除 | 服务器工作负载不需要 |
| 设备模型 | 140+ 设备 | ~5 个设备 | 最小化攻击面 |
保留的设备:
virtio-net:网络virtio-blk:块存储virtio-vsock:宿主 ↔ 客户机通信(替代 Docker socket)- 串口控制台(
/dev/ttyS0) - 可编程间隔计时器、KVM 时钟
- 仅包含关机键的键盘
4.4 性能数据
| 指标 | 数值 |
|---|---|
| 冷启动时间 | < 125ms |
| 启动吞吐 | 每秒 150 台 MicroVM |
| 内存开销 | < 5MB |
| 单机并发 | 4000 台(AWS i3.metal EC2) |
| API 延迟 | < 5ms |
4.5 Jailer:Firecracker 的安全加固
Firecracker 通过 Jailer 进程实现生产环境的安全加固:
Firecracker 进程
│
├── seccomp BPF 过滤器(每个线程独立配置)
├── cgroups 资源限制
├── namespace 隔离
├── chroot 监狱
└── 权限降级(drop privileges)
4.6 Firecracker 的局限
| 局限 | 说明 |
|---|---|
| 不支持热迁移 | MicroVM 状态无法迁移,只能销毁重建 |
| 不支持设备热插拔 | 运行时不能动态添加设备 |
| 设备模型极简 | 不支持 GPU 直通、VFIO 等高级特性 |
| 仅 Linux | 不支持 Windows guest |
| 存储限制 | 只支持 virtio-blk,不支持 virtio-scsi |
五、Kata Containers — 安全容器的"正规军"
5.1 架构
┌─────────────────────────────────────┐
│ Kubernetes (CRI) │
├─────────────────────────────────────┤
│ containerd + kata-runtime │
├─────────────────────────────────────┤
│ Kata Shim │
│ ┌───────────────────────────────┐ │
│ │ hypervisor (QEMU/CHV/FC) │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ Guest Kernel │ │ │
│ │ │ ┌───────────────────┐ │ │ │
│ │ │ │ Kata Agent │ │ │ │
│ │ │ │ ┌─────────────┐ │ │ │ │
│ │ │ │ │ 容器 (OCI) │ │ │ │ │
│ │ │ │ └─────────────┘ │ │ │ │
│ │ │ └───────────────────┘ │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
5.2 关键技术点
Hypervisor 选择(Kata 3.0+):
| Hypervisor | 特点 |
|---|---|
| QEMU | 最成熟,功能最全,但最重 |
| Cloud Hypervisor (CHV) | Rust 实现,轻量,Kata 3.0+ 默认 |
| Firecracker | 最轻,但功能受限(不支持 VFIO/热迁移等) |
| Dragonball | 蚂蚁集团贡献,针对 Kata 优化 |
kata-agent:运行在 guest 内部的守护进程,接收 shim 的 gRPC 请求来创建/管理容器。
3.0 重大改进:
- 底层从 QEMU 切换到 Cloud Hypervisor(Rust 重写)
- 使用 rust-runtime,进一步提升性能和安全性
- 原生支持 Confidential Containers(机密容器)
5.3 局限
- 每个 Pod 一个完整 VM → 内存开销大
- 启动时间比普通容器慢(需要启动 guest 内核)
- 需要嵌套虚拟化支持或裸金属服务器
- 比 Firecracker 更重(保留了更多兼容性)
六、OCI 运行时规范 — 容器标准
6.1 核心概念
OCI 运行时规范定义了:
- 容器的文件系统 bundle 如何组织
- 容器生命周期的各个阶段(创建、运行、销毁)
- 配置文件格式(
config.json)
6.2 三种运行时类型
OCI Runtime
│
├── 传统隔离型(共享内核)
│ └── runc(参考实现)
│
├── 轻量虚拟化型(独立内核)
│ ├── kata-runtime(内置 hypervisor)
│ ├── firecracker-containerd
│ └── cloud-hypervisor
│
└── 内核定制型(限制系统调用)
├── gVisor (runsc)
└── Nabla Containers(已不活跃)
6.3 三种方案对比
| 维度 | runc(传统) | gVisor(内核定制) | Kata(轻量虚拟化) |
|---|---|---|---|
| 隔离机制 | 内核特性(namespace + cgroups + seccomp) | 用户态内核拦截 syscall | 硬件虚拟化(KVM) |
| 资源占用 | 低 | 中 | 高 |
| 安全性 | 低(共享内核) | 中(用户态内核) | 高(独立内核) |
| 启动速度 | 快 | 快 | 慢 |
| 兼容性 | 完美 | 受限(237 个 syscall) | 好 |
| 适用场景 | 传统容器化应用 | 无状态计算(Serverless) | 有状态、安全敏感 |
6.4 安全总结
安全性:runc < gVisor < Kata
兼容性:gVisor < Kata < runc
启动速度:Kata < gVisor ≈ runc
资源开销:Kata > gVisor > runc
七、容器安全的"最小权限原则"
7.1 普通用户 vs root
普通用户:
- 只能访问自己的文件
- 不能修改其他用户的文件或进程
- 不能监听 1024 以下的端口
- 不能修改系统关键文件
root:可以绕过所有权限检查(这就是为什么容器逃逸到 root 如此危险)
7.2 容器安全的分层防御
# 一个安全加固的容器配置示例
apiVersion: v1
kind: Pod
spec:
securityContext:
# 非 root 运行
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
# 禁止权限提升
allowPrivilegeEscalation: false
# 只读根文件系统
readOnlyRootFilesystem: true
# seccomp profile
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: my-app:latest
# 最小 Capabilities
securityContext:
capabilities:
drop:
- ALL # 丢弃所有 Capabilities
7.3 各安全机制的定位
| 机制 | 防什么 | 不防什么 |
|---|---|---|
| Namespace | 进程看到不该看的资源 | 内核漏洞 |
| cgroups | 资源耗尽攻击 | 代码执行漏洞 |
| seccomp | 危险系统调用 | 应用层逻辑漏洞 |
| Capabilities | 越权操作 | 内核漏洞 |
| User Namespace | 容器内 root 映射到宿主普通用户 | 内核漏洞 |
| gVisor | 大部分内核漏洞(用户态拦截) | 性能敏感场景 |
| MicroVM | 内核漏洞(硬件隔离) | 侧信道攻击(需要额外措施) |
八、关键术语速查表
| 术语 | 全称 | 解释 |
|---|---|---|
| OCI | Open Container Initiative | 定义容器镜像和运行时的标准(由 Docker、CoreOS 等发起) |
| KVM | Kernel-based Virtual Machine | Linux 内核的硬件虚拟化模块,需要 CPU 支持 VT-x/AMD-V |
| VMM | Virtual Machine Monitor | 虚拟机监视器,管理虚拟机的生命周期 |
| virtio | Virtual I/O | 半虚拟化 IO 标准,比全模拟设备性能更好 |
| vsock | Virtual Socket | 虚拟机与宿主机之间的套接字通信机制 |
| BPF | Berkeley Packet Filter | 内核级的字节码执行引擎,seccomp 和 eBPF 的基础 |
| eBPF | Extended BPF | 扩展版 BPF,可以在内核中运行自定义程序(网络、安全、监控) |
| Guest OS | — | 运行在虚拟机内部的操作系统 |
| Host OS | — | 宿主机操作系统 |
| TOCTOU | Time-of-Check to Time-of-Use | 检查-使用竞态攻击,安全检查和实际操作之间的竞态条件 |
| Jailer | — | Firecracker 的安全加固进程,应用 cgroup/namespace/chroot |
| Shim | — | 容器运行时的中间层,处理容器生命周期 |
九、沙盒与外部工具集成 — "工具丢了怎么办?"
9.1 问题拆解
Agent 需要调用工具
│
├── 工具在哪运行?
│ ├── 方案 A:工具装在沙盒内(临时,重启丢失)
│ ├── 方案 B:工具装在沙盒外(持久,通过网络调用)
│ └── 方案 C:预烘焙到镜像中(持久,但需重建镜像才能更新)
│
├── 密钥怎么管理?
│ ├── 放沙盒内 → 不安全(恶意代码可窃取)
│ ├── 放沙盒外 + 代理注入 → 安全
│ └── 放沙盒外 + MCP Server → 安全 + 标准化
│
└── 工具版本怎么保证一致性?
├── 镜像预装 → 版本固定,更新需重建
├── 快照恢复 → 版本随快照
└── 外部代理 → 版本由外部管理
9.2 五种集成模式
模式一:镜像预烘焙(Template Baking)
把工具直接打包进沙盒的基础镜像(OCI Image)。
┌─────────────────────────────────────┐
│ OCI 镜像 │
│ ├── Ubuntu base │
│ ├── Python 3.11 + pip packages │
│ ├── Node.js + npm packages │
│ ├── Git / curl / jq / ... │
│ └── 自定义工具(已安装) │
└─────────────────────────────────────┘
│
▼ 创建沙盒
┌─────────────────────────────────────┐
│ 沙盒实例(工具已就绪) │
└─────────────────────────────────────┘
代表项目:CubeSandbox Template、E2B Custom Template
CubeSandbox 的三阶段模板构建:
- Init:OCI 镜像 → rootfs(Buildkit 构建)
- Boot & Snapshot:冷启动 rootfs 到 MicroVM → 快照内存状态
- Deploy:注册快照,后续创建沙盒直接克隆快照(热启动,毫秒级)
优点:工具开箱即用;版本可控;配合快照克隆启动极快 缺点:更新工具需要重建镜像;镜像体积增大;灵活性差
模式二:快照与持久化(Snapshot & Persistence)
沙盒停止时自动保存状态,重启时恢复,工具不会丢失。
沙盒运行中(工具已安装)
│
▼ 停止
┌──────────────────┐
│ 快照(内存+磁盘) │ ← 自动保存
└──────────────────┘
│
▼ 重启(~10s)
┌──────────────────┐
│ 沙盒恢复 │ ← 工具还在!
│ (工具+状态保留) │
└──────────────────┘
代表项目:
- BoxLite:有状态持久化,Box 停止/重启后保留包、文件和环境
- Vercel Sandbox (OpenClaw):
persistent: true创建的沙盒,停止时自动快照,恢复时保留全部状态 - CubeSandbox:快照克隆(Coming Soon 正式版本)
Vercel Sandbox 的生命周期:
uninitialized → creating → setup → booting → running
│
┌────┴────┐
▼ ▼
stopped error
(快照保存) (可恢复)
优点:工具和中间状态全部保留;恢复比从头创建快(~10s vs 完整引导) 缺点:快照占用存储;快照可能过期(配置变更后需重建);长时间停止后快照可能不一致
模式三:MCP 作为工具代理(MCP Tool Proxy)
MCP(Model Context Protocol)是连接 Agent 和外部工具的标准协议。工具运行在沙盒外部的 MCP Server 中,沙盒通过 MCP 协议调用工具。
┌────────────┐ MCP 协议 ┌────────────────┐
│ Agent │ ◄──────────────► │ MCP Server │
│ (沙盒内) │ │ (沙盒外) │
│ │ stdio/HTTP │ ┌──────────┐ │
│ │ │ │ GitHub │ │
│ │ │ │ Slack │ │
│ │ │ │ DB │ │
│ │ │ │ 自定义 │ │
│ │ │ └──────────┘ │
└────────────┘ └────────────────┘
代表项目:
- OpenSandbox MCP Server:将沙盒生命周期和文件操作暴露为 MCP 工具(
sandbox_create、command_run、file_read等),任何 MCP 客户端(Claude Code、Cursor)都可以调用 - E2B MCP Gateway:提供 200+ 预构建的 MCP Server 集成,创建沙盒时声明需要的 MCP 工具
E2B 的 MCP 集成示例:
# 创建沙盒时声明需要 GitHub MCP 工具
sandbox = Sandbox.create(
mcp={"github": {"token": "..."}}
)
# 沙盒内自动获得本地 MCP endpoint,可直接调用 GitHub API
OpenSandbox 的架构:
┌─────────────────────────────────────┐
│ MCP 客户端(Claude Code / Cursor) │
├─────────────────────────────────────┤
│ OpenSandbox MCP Server(沙盒外) │ ← 密钥在这里,不在沙盒内
│ ├── sandbox_create │
│ ├── sandbox_command_run │
│ ├── sandbox_file_read │
│ └── server proxy(网络代理) │
├─────────────────────────────────────┤
│ 沙盒实例(沙盒内) │ ← 只执行代码,不持有密钥
└─────────────────────────────────────┘
优点:工具与沙盒生命周期完全解耦;密钥不进入沙盒;标准化协议,生态丰富 缺点:需要额外部署 MCP Server;网络调用增加延迟;MCP 生态仍在早期
模式四:工具网关 / 代理(Tool Gateway Pattern)
工具运行在沙盒外部的网关/代理后面,沙盒通过代理 URL 调用工具,凭证永远不进入沙盒。
┌──────────┐ ┌───────────────┐ ┌──────────────┐
│ 沙盒 │────►│ 工具网关 │────►│ 外部工具 │
│ │ │ (代理层) │ │ │
│ 无密钥 │ │ ├── 凭证注入 │ │ GitHub API │
│ 只有 │ │ ├── 域名过滤 │ │ Slack API │
│ 代理URL │ │ ├── 审计日志 │ │ 数据库 │
│ │ │ └── 速率限制 │ │ │
└──────────┘ └───────────────┘ └──────────────┘
代表项目:agentgateway.dev(Linux Foundation)、Vercel Sandbox
Vercel 的凭证注入方式:
沙盒内代码: fetch("https://ai-gateway.vercel.sh/...")
│
▼ 网络策略层自动注入
请求实际变成: GET https://ai-gateway.vercel.sh/...
Authorization: Bearer <token> ← 网关注入,沙盒内不可见
优点:凭证安全级别最高;细粒度访问控制;审计和监控 缺点:增加架构复杂度;网关成为单点故障;需要运维网关服务
模式五:Session-Harness-Sandbox 三元分离(Anthropic 架构)
Anthropic 提出的最新架构模式,将 Agent 系统拆分为三个独立的原语:
┌─────────────────────────────────────────────────┐
│ Session(会话日志) │
│ ├── append-only 事件流 │
│ ├── 记录每个工具调用和结果 │
│ └── 任何 Harness 都可以接管恢复 │
├─────────────────────────────────────────────────┤
│ Harness(编排层,无状态) │
│ ├── 驱动 Agent 循环(调用 LLM + 工具) │
│ ├── 崩溃后可被任何新 Harness 接管 │
│ └── 凭证通过 Vault 代理获取,不经过沙盒 │
├─────────────────────────────────────────────────┤
│ Sandbox(执行层,临时) │
│ ├── 执行不可信代码 │
│ ├── 不持有任何凭证 │
│ └── 崩溃不影响 Session 和 Harness │
└─────────────────────────────────────────────────┘
关键设计:
- Session 是真理之源:所有事件(工具调用、结果、模型输出)都记录在 Session 日志中
- Harness 无状态:任何 Harness 实例都可以接管任何 Session,实现水平扩展和崩溃恢复
- 凭证不进沙盒:两种方式 —— Resource-bundled auth(provision 阶段注入后丢弃)或 Vault-proxied auth(通过 MCP 代理)
崩溃恢复流程:
沙盒崩溃
│
▼
新 Harness 调用 wake(sessionId)
│
▼
从 Session 日志获取所有历史事件
│
▼
从最后一个成功的工具调用处继续
│
▼
用户看到短暂暂停,而不是从头开始
性能收益:TTFT(首 token 时间)降低约 60%(p50)和 90%(p95),因为推理可以与沙盒准备并行进行。
优点:最强的解耦;天然支持崩溃恢复和水平扩展;凭证安全级别最高 缺点:架构最复杂;需要维护 Session 存储;目前主要在 Anthropic 内部使用
9.3 五种模式对比总结
| 维度 | 镜像预烘焙 | 快照持久化 | MCP 工具代理 | 工具网关 | 三元分离 |
|---|---|---|---|---|---|
| 工具持久性 | ✅ 在镜像中 | ✅ 在快照中 | ✅ 在外部 Server | ✅ 在外部 | ✅ 在外部 |
| 重启后工具是否保留 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 密钥安全性 | ❌ 在沙盒内 | ❌ 在沙盒内 | ✅ 在 MCP Server | ✅ 在网关 | ✅ 结构性分离 |
| 工具更新灵活性 | ❌ 需重建镜像 | ❌ 需重建快照 | ✅ 更新 Server | ✅ 更新网关 | ✅ 更新 Server |
| 架构复杂度 | 低 | 低 | 中 | 高 | 最高 |
| 代表项目 | CubeSandbox | BoxLite / Vercel | OpenSandbox / E2B | agentgateway | Anthropic |
| 适合阶段 | MVP / 原型 | 本地开发 | 生产 Agent | 企业级 Agent | 大规模 Agent 平台 |
9.4 选型建议
十、agentgateway 深度剖析 — "AI 原生网关如何工作"
10.1 为什么传统 API 网关不够用?
| 维度 | 传统 API 网关 | agentgateway |
|---|---|---|
| 请求模型 | 无状态请求/响应 | 有状态 JSON-RPC 会话,长连接 |
| 路由方式 | 一个请求 → 一个后端 | 一个请求 → 扇出到多个 MCP Server |
| 通信方向 | 客户端发起 | 双向:服务端可通过 SSE 推送事件 |
| 路由决策 | 基于路径/头部 | 协议感知:理解 JSON-RPC 消息体 |
| 后端映射 | 静态 | 动态工具虚拟化(per-client) |
| 会话管理 | 不需要 | 必须维护 Mcp-Session-Id 绑定 |
10.2 整体架构
┌─────────────────────────────────────────────────────────────┐
│ Control Plane (Go) │
│ ┌──────────┐ ┌──────────────┐ ┌────────────────────┐ │
│ │ Config │ │ Translation │ │ xDS Server │ │
│ │ Watcher │→ │ Engine │→ │ (gRPC 配置分发) │ │
│ │ (K8s CRD)│ │ (资源翻译) │ │ │ │
│ └──────────┘ └──────────────┘ └─────────┬──────────┘ │
│ │ xDS snapshot │
├─────────────────────────────────────────────┼───────────────┤
│ Data Plane (Rust) │ │
│ ┌──────────────────────────────────────────▼─────────────┐ │
│ │ Gateway Proxy (agentgateway) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ LLM GW │ │ MCP GW │ │ A2A GW │ │ │
│ │ │ (LLM 路由)│ │ (工具联邦)│ │ (Agent间)│ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ │ │ │ │ │ │
│ │ ┌────▼─────────────▼──────────────▼────────────────┐ │ │
│ │ │ Policy Engine (CEL) │ │ │
│ │ │ Auth │ RBAC │ Rate Limit │ Guardrails │ CORS │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Observability (OpenTelemetry) │ │ │
│ │ │ Metrics │ Logs │ Distributed Tracing │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ LLM │ │ MCP │ │ A2A │
│ Providers│ │ Servers │ │ Agents │
│ (OpenAI, │ │ (GitHub, │ │ (其他 │
│ Anthropic│ │ Slack, │ │ Agent) │
│ Gemini) │ │ 自定义) │ │ │
└──────────┘ └──────────┘ └──────────┘
技术栈:
- Data Plane(Rust 59%):高性能代理,管理有状态长连接和扇出
- Control Plane(Go 28%):Kubernetes 控制器,监听 CRD 变更,翻译为 xDS 配置
- UI(TypeScript 10%):内置自服务门户,Playground 测试
10.3 MCP Gateway 核心机制
10.3.1 工具联邦(Tool Federation)
多个 MCP Server 的工具聚合到一个端点。
Agent 客户端(只看到一个 MCP endpoint)
│
│ GET /mcp → tools/list
│
▼
┌─────────────────────────────────────────┐
│ agentgateway MCP Gateway │
│ │
│ ┌────────────┐ ┌────────────┐ │
│ │ MCP Server │ │ MCP Server │ │
│ │ "filesystem"│ │ "memory" │ │
│ │ (stdio) │ │ (stdio) │ │
│ └────────────┘ └────────────┘ │
│ │
│ 工具列表自动聚合 + 名称前缀: │
│ ├── filesystem_read_file │
│ ├── filesystem_write_file │
│ ├── memory_create_entities │
│ └── memory_search │
└─────────────────────────────────────────┘
配置示例:
binds:
- port: 3000
listeners:
- routes:
- backends:
- mcp:
targets:
- name: filesystem # 第一个 MCP Server
stdio:
cmd: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
- name: memory # 第二个 MCP Server
stdio:
cmd: npx
args: ["-y", "@modelcontextprotocol/server-memory"]
工作机制:
- 启动时,agentgateway 分别连接每个 MCP Server,获取其工具列表
- 将所有工具聚合,自动添加
{server_name}_前缀避免命名冲突 - 客户端调用
tools/list时,返回聚合后的完整工具列表 - 客户端调用某个工具时,agentgateway 根据前缀路由到对应的后端 MCP Server
10.3.2 多路复用与扇出(Multiplexing & Fan-out)
一个客户端连接 → 扇出到多个后端 MCP Server → 聚合响应返回。
传统 API 网关:一个请求打一个后端
agentgateway:一个 tools/list 请求扇出到 N 个 MCP Server,合并结果
客户端: tools/list
│
▼ agentgateway
├──► filesystem Server → 返回 10 个工具
├──► memory Server → 返回 5 个工具
└──► github Server → 返回 8 个工具
│
▼ 合并(23 个工具,自动去重+前缀)
│
客户端: 收到 23 个工具的统一列表
Kubernetes 模式下支持标签选择器动态发现 MCP Server:
apiVersion: agentgateway.dev/v1alpha1
kind: AgentgatewayBackend
spec:
mcp:
targets:
- name: mcp-server-everything
selector: # 动态发现
services:
matchLabels:
app: mcp-server-everything
- name: mcp-website-fetcher
static: # 静态配置
host: mcp-website-fetcher.default.svc.cluster.local
port: 80
protocol: SSE
10.3.3 OpenAPI → MCP 自动翻译
零代码改造:把现有的 REST API 自动变成 MCP 工具。
启动时 运行时
OpenAPI Spec ──► 解析每个 ──► MCP Tool MCP Client ──► call_tool("addPet")
(YAML/JSON) path+method 定义 │ │
▼ ▼
agentgateway 翻译为 HTTP 请求
│ POST /pet
│ {"name": "Fido", ...}
▼
REST Backend
翻译规则:
| OpenAPI 字段 | → MCP 字段 |
|---|---|
operationId |
→ 工具名(如 addPet);若无则用 {method}_{path} |
summary + description |
→ 工具描述 |
parameters(query/path/header)+ requestBody |
→ 工具输入 schema |
| HTTP method + path + query string | → 请求构造 |
请求翻译 10 步流水线(源码级):
| 步骤 | 动作 | 代码位置 |
|---|---|---|
| 1 | 根据工具名查找 (Tool, UpstreamOpenAPICall) |
self.tools IndexMap |
| 2 | 解析参数到 path_params、query_params、header_params、body_value |
call_tool() |
| 3 | 路径模板替换 {param} → 实际值(百分号编码防注入) |
PathParamReplacer |
| 4 | 拼接 URL:prefix + path + query string | normalize_url_path() |
| 5 | 构造 HTTP 请求(method、Accept header、body) | http::Request::builder() |
| 6 | 注入网关级头部(auth policy 等) | ctx.apply(&mut request) |
| 7 | 添加用户头部(仅白名单内的 header) | allowed_headers 过滤 |
| 8 | 执行 HTTP 调用 | self.http_client.call(request) |
| 9 | 解压响应(gzip/deflate/brotli/zstd)+ JSON 反序列化 | to_bytes_with_decompression() |
| 10 | 包装为 MCP CallToolResult 返回 |
JSON object / wrapped in {"data": ...} |
安全措施(内建):
- 路径遍历防护:路径参数百分号编码,
"../admin"→"..%2Fadmin" - 查询注入防护:查询参数值全部编码,
"true&admin=true"→"true%26admin%3Dtrue" - Header 白名单:只转发 OpenAPI spec 中声明的 header,
content-length/content-type/transfer-encoding/host永远被阻止 - URL 规范化:防止双斜杠
/api/v1//pets问题
10.3.4 MCP 会话管理(Session Management)
MCP 是有状态协议,agentgateway 必须管理会话生命周期。
客户端连接
│
▼
agentgateway 创建 Session(绑定 Mcp-Session-Id)
│
├──► 会话路由:后续请求自动路由到同一个后端
├──► 会话扇出:一个会话可以跨多个后端 MCP Server
├──► 会话持久化:支持跨请求的会话状态
└──► 会话认证:per-session 的 RBAC 策略
Session Layer 请求路由:
MCP Client → tools/call "filesystem_read_file"
│
▼ Session Layer (session.rs)
│ parse_resource_name("filesystem_read_file") → target="filesystem"
│
▼ Relay Layer (handler.rs)
│ send_single(request, target="filesystem")
│
▼ UpstreamGroup
│ get("filesystem") → Upstream::Stdio(handler)
│
▼ Handler
generic_stream() → 发送到 filesystem MCP Server
10.4 A2A Gateway 机制
Agent-to-Agent 协议让多个 Agent 互相发现、协商、协作。
Agent A agentgateway Agent B
│ │ │
│ 1. 发现能力 │ │
│ ─────────────────────────► │ │
│ "你能做什么?" │ ────────────────────────► │
│ │ │
│ 2. 协商交互模态 │ │
│ ◄───────────────────────── │ ◄──────────────────────── │
│ "支持文本、表单、媒体" │ │
│ │ │
│ 3. 分配任务 │ │
│ ─────────────────────────► │ ────────────────────────► │
│ "帮我分析这个数据集" │ │
│ │ │
│ 4. 长任务协作 │ │
│ ◄───────────────────────── │ ◄──────────────────────── │
│ 持续返回中间结果... │ │
A2A 网关的核心功能:
- 能力发现:Agent 通过
AgentCard描述自己的能力 - 模态协商:协商支持的交互格式(文本/表单/媒体)
- 任务协作:支持长时间运行的任务,状态由网关管理
- 隐私保护:Agent 之间不暴露内部状态或工具
10.5 LLM Gateway 机制
Agent 代码
│ fetch("https://gateway/v1/chat/completions")
▼
┌─────────────────────────────────────────┐
│ agentgateway LLM Gateway │
│ │
│ 1. 统一 OpenAI 兼容 API │
│ 2. Provider 路由: │
│ ├── /models/gpt-4* → OpenAI │
│ ├── /models/claude-* → Anthropic │
│ └── /models/gemini-* → Google │
│ 3. 预算控制 + Token 计费 │
│ 4. 负载均衡 + 故障转移 │
│ 5. Prompt 增强(注入系统提示等) │
│ 6. Guardrails(内容过滤) │
└─────────────────────────────────────────┘
10.6 策略引擎与安全
CEL 策略引擎
agentgateway 使用 CEL(Common Expression Language) 作为策略语言,支持细粒度 RBAC:
# 只允许特定客户端访问 GitHub MCP 工具
policies:
- name: github-access
type: authorization
rules:
- match: "request.headers['x-client-id'] == 'agent-001'"
allow:
- tool: "github_*" # 允许所有 github_ 开头的工具
多层认证
请求进入
│
├── JWT 验证 → 提取 claims
├── API Key 验证 → 匹配客户端身份
├── Basic Auth → 用户名密码验证
└── MCP Auth Spec → OAuth 2.0(Auth0 / Keycloak)
│
▼
CEL 策略引擎评估 RBAC
│
├── 允许 → 路由到后端
└── 拒绝 → 返回 403 + JSON-RPC error
工具投毒防护
agentgateway 提供的防护:
- 工具注册的来源验证
- 工具描述的完整性校验
- per-client 的工具可见性控制
10.7 部署模式
独立部署(Standalone)
# 安装
curl https://raw.githubusercontent.com/agentgateway/agentgateway/main/common/scripts/get-agentgateway | bash
# 启动
agentgateway -f config.yaml
Kubernetes 部署
┌─────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ Control Plane (agentgateway-system ns) │
│ ├── Config Watcher(监听 CRD 变更) │
│ ├── Translation Engine(CRD → xDS) │
│ └── xDS Server(gRPC 配置分发) │
│ │
│ Data Plane │
│ ├── agentgateway-proxy Pod │
│ │ ├── LLM Gateway │
│ │ ├── MCP Gateway │
│ │ └── A2A Gateway │
│ │ │
│ ├── MCP Server Pods(各工具服务) │
│ └── Application Pods(Agent 应用) │
│ │
│ CRDs │
│ ├── Gateway │
│ ├── HTTPRoute │
│ ├── AgentgatewayBackend │
│ ├── AgentgatewayPolicy │
│ └── AgentgatewayParameters │
└─────────────────────────────────────────────┘
配置流转:
用户创建 CRD(Gateway/HTTPRoute/AgentgatewayBackend)
│
▼ Config Watcher 检测到变更
│
▼ Translation Engine 翻译为 xDS snapshot
│
▼ xDS Server 通过 gRPC 推送到 Data Plane
│
▼ agentgateway-proxy 热更新配置(无重启)
10.8 与沙盒场景的结合
十一、Agent 文件系统(VFS)— "一切皆文件" 的新范式
11.1 为什么 Agent 需要专属文件系统?
传统文件系统为人类设计,Agent 面临的问题不同:
| 问题 | 人类的解法 | Agent 需要的解法 |
|---|---|---|
| "我做了什么操作?" | 自己记得 | 完整审计日志(tool call history) |
| "回到上一步" | Ctrl+Z / git | 文件系统级快照 + 时间旅行 |
| "访问 S3、Slack、GitHub" | 分别用不同 SDK | 统一的文件树挂载 |
| "记住这次对话的上下文" | 大脑 | 持久化记忆层(history / memory / scratchpad) |
| "多个 Agent 互不干扰" | 独立电脑 | Copy-on-Write 隔离 |
| "在浏览器/Serverless 中工作" | 不可能 | SQLite / 内存文件系统 |
11.2 三个项目:三种哲学
Agent VFS 光谱
执行层隔离 服务层统一 记忆层治理
(sandbox-oriented) (service-oriented) (memory-oriented)
│ │ │
AgentFS Mirage AIGNE/AFS
(Turso) (strukto-ai) (论文)
│ │ │
"用 SQLite 记录 "把 S3/Slack/GitHub "用文件系统抽象
Agent 的一切" 挂载成一棵文件树" 管理 Agent 记忆"
11.3 AgentFS — SQLite 即文件系统
Turso 出品,3.1k stars,核心理念:把 Agent 的全部状态存进一个
.db文件。
架构
┌─────────────────────────────────────────┐
│ Agent 应用层 │
├─────────────────────────────────────────┤
│ AgentFS SDK(Python / TS / Rust) │
│ ├── fs — POSIX 文件操作 │
│ ├── kv — 键值存储 │
│ └── tools — 工具调用审计 │
├─────────────────────────────────────────┤
│ SQLite + WAL(Write-Ahead Log) │
│ └── 单个 .db 文件包含一切 │
├─────────────────────────────────────────┤
│ 挂载层 │
│ ├── Linux: FUSE(挂载为 /agent) │
│ ├── macOS: NFS │
│ └── Firecracker VM: NFSv3 │
└─────────────────────────────────────────┘
核心机制:Copy-on-Write 隔离
Base 文件系统(只读)
│
▼ Overlay
┌─────────────────────────────────────┐
│ Agent A 的 CoW 层(SQLite WAL) │ ← 只看到自己的修改
├─────────────────────────────────────┤
│ Agent B 的 CoW 层(SQLite WAL) │ ← 看不到 A 的修改
├─────────────────────────────────────┤
│ 共享只读基础层 │
└─────────────────────────────────────┘
关键特性:
| 特性 | 实现方式 | 意义 |
|---|---|---|
| 快照 | cp agent.db snapshot.db |
一行代码冻结 Agent 全部状态 |
| 时间旅行 | WAL 记录每次变更 | 回溯任意时刻的文件系统状态 |
| 可查询 | SQL 查询文件系统 | SELECT * FROM files WHERE path LIKE '/output/%' |
| 审计 | 工具调用记录在表中 | 完整的 tool call history + 耗时 + 输入输出 |
| 可移植 | 单文件即全部状态 | 机器间迁移 = 拷贝一个文件 |
| 跨环境 | FUSE/NFS/浏览器 WASM | Serverless、浏览器、VM 都能用 |
SDK 用法
import { AgentFS } from 'agentfs-sdk';
const agent = await AgentFS.open({ id: 'my-agent' });
// 文件操作
await agent.fs.writeFile('/output/report.pdf', pdfBuffer);
const files = await agent.fs.readdir('/output');
// 键值存储
await agent.kv.set('user:preferences', { theme: 'dark' });
// 工具调用审计
await agent.tools.record('web_search', startTime, endTime, input, output);
与其他方案的对比
| 维度 | AgentFS | Docker 沙盒 | Git Worktree |
|---|---|---|---|
| 隔离方式 | 文件系统级 CoW | 内核级 namespace | 目录级复制 |
| 能否绕过隔离 | ❌ 系统级强制 | ❌ 内核强制 | ✅ Agent 可以访问外部 |
| 快照/恢复 | 一行代码 | 需要容器快照工具 | git commit/checkout |
| 可查询性 | SQL 查询 | ❌ | ❌ |
| 审计能力 | 内建 | 需要外部工具 | git log |
| 持久化 | 天然持久(SQLite) | 容器销毁即丢失 | 天然持久 |
| 适用环境 | 任何(含浏览器) | 需要 Docker/KVM | 需要 git |
11.4 Mirage — 万物皆可挂载的统一 VFS
strukto-ai 出品,1.1k stars,核心理念:把 S3、Slack、GitHub、Gmail 等一切服务挂载成一棵文件树,Agent 用 bash 操作一切。
架构
┌──────────────────────────────────────────────────────┐
│ AI Agent(用 bash 命令操作一切) │
│ ls /s3/my-bucket/ │
│ cat /slack/general/messages.json │
│ cp /gdrive/report.pdf /local/ │
│ grep "error" /s3/logs/*.log | wc -l │
├──────────────────────────────────────────────────────┤
│ Mirage VFS 层 │
│ ├── Bash 解析器(命令解析 + 路由) │
│ ├── Dispatcher(路由到对应资源适配器) │
│ └── Cache(Index Cache + File Cache) │
├──────────────────────────────────────────────────────┤
│ 资源适配器(Resource Adapters) │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ S3 │ │ Slack │ │ GitHub │ │ GDrive │ ... │
│ │ │ │ │ │ │ │ │ │
│ └────────┘ └────────┘ └────────┘ └────────┘ │
├──────────────────────────────────────────────────────┤
│ 远程服务(S3 / Slack API / GitHub API / ...) │
└──────────────────────────────────────────────────────┘
核心理念:复用 LLM 最擅长的技能
支持挂载的资源
| 类别 | 资源 |
|---|---|
| 存储 | RAM、Disk、Redis、S3、R2、GCS、OCI、Supabase |
| Gmail、GDrive、GDocs、GSheets、GSlides | |
| 项目管理 | GitHub、Linear、Notion、Trello |
| 通信 | Slack、Discord、Telegram、Email |
| 数据库 | MongoDB |
| 远程 | SSH |
双层缓存
请求 /s3/my-bucket/data.csv
│
▼ Index Cache(目录元数据)
│ ├── 命中 → 直接返回
│ └── 未命中 → 调用 S3 API → 缓存(TTL 10min)
│
▼ File Cache(文件内容)
│ ├── 命中 → 直接返回
│ └── 未命中 → 流式读取 S3 → 缓存(512MB 上限)
│
返回文件内容
缓存后端可选:RAM(默认,进程内)或 Redis(跨进程/跨机器共享)。
跨服务管道
# 用例:从 Slack 搜索消息,过滤,保存到 S3
grep "deploy" /slack/engineering/messages.json | \
jq '.[] | select(.ts > "2026-05-01")' | \
tee /s3/my-bucket/deploy-log.json
# 用例:读取 Google Doc,总结,写回
cat /gdocs/project-spec.md | summarize > /local/summary.md
Agent 只需要知道 bash,不需要学 Slack SDK、S3 SDK、Google Docs SDK。
SDK 用法
from mirage import Workspace
from mirage.resource.s3 import S3Config, S3Resource
from mirage.resource.slack import SlackConfig, SlackResource
ws = Workspace(
mounts={
"/s3": S3Resource(S3Config(bucket="my-bucket")),
"/slack": SlackResource(SlackConfig()),
}
)
# 执行 bash 命令
result = await ws.execute("ls /s3/logs/")
result = await ws.execute("cat /slack/general/last-message.json")
# 快照
ws.snapshot("workspace.tar")
11.5 AIGNE/AFS — 文件系统作为上下文工程基础设施
论文 "Everything is Context" 提出,核心理念:用 Unix "一切皆文件" 哲学管理 Agent 的全部上下文——记忆、历史、工具、人类输入。
三层持久化模型
┌─────────────────────────────────────────────────┐
│ Context Repository │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ /context/history/ ← 不可变 │ │
│ │ 原始交互记录,永久保存 │ │
│ │ 带 timestamp、origin、model version │ │
│ ├──────────────────────────────────────────┤ │
│ │ /context/memory/{agentID}/ ← 可变 │ │
│ │ 结构化记忆,按类型分类 │ │
│ │ ├── scratchpad/ 临时推理空间 │ │
│ │ ├── episodic/ 会话摘要 │ │
│ │ ├── fact/ 原子事实(KV/三元组)│ │
│ │ ├── procedural/ 工具/函数定义 │ │
│ │ └── user/ 用户偏好/画像 │ │
│ ├──────────────────────────────────────────┤ │
│ │ /context/pad/{taskID}/ ← 临时 │ │
│ │ 任务级草稿纸,会话结束后 │ │
│ │ 有价值的晋升为 memory,其余丢弃 │ │
│ └──────────────────────────────────────────┘ │
│ │
│ /modules/github-mcp/ ← MCP 工具挂载 │
│ /tools/analyser.py ← 可执行工具 │
│ /config/settings.yaml ← 配置数据 │
└─────────────────────────────────────────────────┘
七大记忆类型
| 记忆类型 | 时间范围 | 结构单元 | 表示形式 | 文件路径 |
|---|---|---|---|---|
| Scratchpad | 临时,任务内 | 对话轮次 | 纯文本/嵌入 | /context/pad/{taskID} |
| Episodic | 中期,会话级 | 会话摘要 | 摘要+嵌入 | /context/memory/episodic/ |
| Fact | 长期,细粒度 | 原子事实 | KV/三元组 | /context/memory/fact/ |
| Experiential | 长期,跨任务 | 观察-行动轨迹 | 结构化日志 | /context/memory/experiential/ |
| Procedural | 长期,系统级 | 函数/工具定义 | API/代码引用 | /context/memory/procedural/ |
| User | 长期,个性化 | 用户属性/偏好 | 用户画像/嵌入 | /context/memory/user/ |
| History | 永久,不可变 | 原始日志 | 纯文本+元数据 | /context/history/ |
上下文工程流水线
┌─────────────────────┐
│ Token Window │ ← 128K/200K 硬限制
│ (推理空间) │
└─────────┬───────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Constructor │ │ Updater │ │ Evaluator │
│ (选择+压缩) │ │ (注入+刷新) │ │ (验证+治理) │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
▼ ▼ ▼
┌──────────────────────────────────────────┐
│ 持久化上下文仓库 │
│ /context/history/ + /context/memory/ │
└──────────────────────────────────────────┘
- Constructor:从仓库中选择、优先排序、压缩上下文 → 生成 manifest
- Updater:将构造好的上下文注入 token window(静态快照 / 增量流 / 自适应刷新)
- Evaluator:验证输出(检测幻觉/矛盾/漂移)→ 写回 memory → 触发人类审查
11.6 三种方案对比
| 维度 | AgentFS | Mirage | AIGNE/AFS |
|---|---|---|---|
| 核心抽象 | SQLite DB = 文件系统 | 服务 = 挂载点 | 上下文 = 文件 |
| 解决的问题 | Agent 执行隔离 + 审计 | 多服务统一访问 | 记忆管理 + 上下文治理 |
| 隔离机制 | Copy-on-Write (SQLite WAL) | 命名空间隔离 | 沙盒访问控制 |
| 快照 | cp agent.db |
ws.snapshot("tar") |
文件级版本控制 |
| 审计 | SQL 查询 tool call history | 命令日志 | 事务日志 + 元数据 |
| 记忆管理 | KV store(简单) | ❌ 无内建 | 7 层记忆体系(完整) |
| 多服务集成 | ❌ 专注文件 | ✅ S3/Slack/GitHub 等 20+ | ✅ 通过 MCP 挂载 |
| 挂载机制 | FUSE / NFS | 适配器模式 | 可编程 Resolver |
| Agent 交互方式 | SDK API | bash 命令 | 文件操作 API |
| 适用环境 | 任何(含浏览器 WASM) | macOS / Linux | Node.js 运行时 |
| 成熟度 | Beta(3.1k ⭐,58 releases) | 早期 v0.0.1(1.1k ⭐) | 论文阶段(AIGNE 框架) |
| 语言 | Rust 核心 + 多语言 SDK | TypeScript / Python | TypeScript(AIGNE) |
11.7 Agent VFS 与容器沙盒的关系
┌─────────────────────────────────────────────────┐
│ Agent 应用 │
├─────────────────────────────────────────────────┤
│ Agent VFS 层 │
│ ├── AgentFS(执行审计 + 快照恢复) │
│ ├── Mirage(多服务统一访问) │
│ └── AIGNE/AFS(记忆管理 + 上下文治理) │
├─────────────────────────────────────────────────┤
│ 容器沙盒层 │
│ ├── MicroVM(CubeSandbox / BoxLite) │
│ ├── Docker / gVisor │
│ └── Bubblewrap(用户态隔离) │
├─────────────────────────────────────────────────┤
│ 工具集成层 │
│ ├── agentgateway(MCP/A2A 网关) │
│ └── MCP Server(外部工具) │
├─────────────────────────────────────────────────┤
│ Linux 内核 + 硬件 │
└─────────────────────────────────────────────────┘
| 层次 | 解决的问题 | 代表技术 |
|---|---|---|
| Agent VFS | Agent 怎么访问和管理数据 | AgentFS / Mirage / AIGNE |
| 容器沙盒 | 在哪里安全地执行代码 | CubeSandbox / BoxLite / gVisor |
| 工具网关 | 怎么连接外部工具 | agentgateway / MCP |
| 内核隔离 | 底层安全边界 | namespace / cgroups / KVM |
11.8 选型建议
参考资料
- 知乎 - Linux Namespace 技术
- 知乎 - 三、Linux Cgroup
- 知乎 - 深度解析 AWS Firecracker
- 知乎 - 容器逃逸
- Google Cloud - What is gVisor?
- AWS - Firecracker 开源项目
- Red Hat - Container security seccomp
- Kubernetes - Seccomp 教程
- Linux 内核文档 - Seccomp BPF
- 腾讯云 - 浅谈 Linux Seccomp 安全机制
- OpenSandbox MCP Server
- E2B MCP Gateway
- CubeSandbox Template Docs
- Anthropic Managed Agents Architecture
- agentgateway - Linux Foundation
- agentgateway - GitHub
- agentgateway Architecture (DeepWiki)
- agentgateway OpenAPI-to-MCP Bridge (DeepWiki)
- agentgateway MCP Federation Tutorial
- Vercel OpenClaw Lifecycle
- AgentFS - Turso
- Mirage - strukto-ai
- Everything is Context: Agentic File System Abstraction (arXiv:2512.05470)
- AIGNE Framework