本章提要
在大语言模型(LLM)从静态单轮对话向自主智能体(Agent)演进的范式转移中,模型的训练与评估不再局限于固定的文本数据集,而是依赖于模型与外部真实环境的交互轨迹。强化学习(RL)的大规模 Rollout 与自动化评估,对底层执行环境提出了极端并发、多变依赖、深度有状态与高密度低成本运行的严苛要求。
本章以 DeepSeek 生产级沙箱基础设施 DSec(DeepSeek Elastic Compute) 为核心剖析对象,系统讲解面向智能体的大规模沙箱系统架构设计。内容涵盖异构沙箱运行时选型、基于 Overlayfs 与 EROFS 的可组合分层文件系统、基于 3FS 的按需轻量镜像分发、高密度超卖下的内存去重与 CPU QoS 调度机制,以及沙箱系统与强化学习训练框架的协同设计与安全防作弊治理。本章还提供了详尽的内核系统调用实现代码,并横向严密对比了 DSec 与 Kubernetes、Ray、AWS Firecracker 及 Modal/E2B 等主流运行时的架构机理。
1.1 本章导读与学习目标
在传统深度学习任务中,计算基础设施的核心矛盾集中在 GPU/TPU 的张量计算算力与显存带宽上,数据读取通常为高吞吐的流式数据载入。然而,随着智能体(Agentic AI)在软件工程(SWE)、代码运行测试(OJ/Benchmarking)、终端交互(Terminal Use)、网页操作(Web Use)乃至全系统操作(Computer Use)等复杂任务中的应用,模型需要自主发出 Shell 命令、调用系统工具、读写代码仓库乃至操作浏览器与移动应用。
这就要求平台必须为每次 Rollout(交互探索生成)或评估任务即时物化(Materialize)出一个安全、隔离、有状态、且与真实环境高度一致的沙箱(Sandbox)。如图 1-1 所示,智能体交互循环将物理计算系统深度嵌入到了模型学习回路中。
flowchart LR
subgraph AgentLoop["智能体交互与学习闭环"]
M["Frontier LLM / Policy Model"]
S["DSec 沙箱环境<br/>(Container / MicroVM)"]
R["反馈验证与奖励计算<br/>(Reward Engine)"]
T["策略优化更新<br/>(RL Trainer)"]
end
M -->|"执行动作 (Tool Call / Shell)"| S
S -->|"状态反馈 (Stdout / ExitCode / FS)"| M
S -->|"最终执行轨迹与测试结果"| R
R -->|"奖励分数 (Reward Signal)"| T
T -->|"权重梯度更新"| M学习目标
完成本章学习后,读者应当能够:
- 掌握智能体沙箱负载的核心特征:深入理解突发性(Bursty)、高密度稀疏占空(Sparse CPU)、长期有状态(Stateful & Long-lived)、环境极端多样(High Diversity)与低扇出(Low Fanout)等特征对底层系统架构提出的本质挑战。
- 掌握多层级沙箱运行时选型与权衡:理解 Function Call(函数级)、Container(容器级)、MicroVM(微虚拟机)以及 Full VM(全功能虚拟机)在性能、隔离性、系统完整性及资源开销上的定量权衡。
- 深入理解可组合分层存储架构:掌握如何通过 EROFS 只读文件系统与 Overlayfs 动态分层,将“基础镜像”、“任务代码仓库(Workspace)”与“工具链(Toolkit)”解耦,彻底避免单体镜像组合爆炸(将维护开销从 $O(m \cdot N)$ 降低至 $O(m) + O(k)$)。
- 精通基于超大规模分布式存储的按需镜像流式载入:掌握利用非对称分布式文件系统(如 DeepSeek 3FS)结合 EROFS 多设备模式与 Rust ublk 驱动,实现“本地写、远端大块顺序读、元数据本地预热”的高效分发范式。
- 掌握微虚拟机超卖与系统 QoS 关键技术:掌握结合
virtio-pmem+ DAX 的 Host/Guest 共享页缓存技术与内核内存开销数学推导,基于 DAMON 的冷内存识别与virtio-balloon自由页主动归还机制,以及 Linux Core Scheduling 结合SCHED_IDLE消除 SMT 线程级 CPU 争用的核心原理。 - 掌握基础设施与强化学习框架的协同设计:理解 Rollout 控制层与 GPU 训练的解耦架构、基于快照的透明挂起/恢复机制,以及基于 AppArmor 和 eBPF 的防作弊(Reward Hacking)安全治理实践。
- 具备前沿沙箱技术横向选型与机理辨析能力:深入对比 DSec 与 Kubernetes/Knative、Ray、AWS Firecracker 及 Modal/E2B 等平台的架构差异。
1.2 智能体执行环境的背景与核心挑战
1.2.1 强化学习训练流水线中的沙箱角色
在 DeepSeek-R1、DeepSeek-V3/V4 等前沿大模型的研发过程中,强化学习(RL)起到了决定模型逻辑推理、工具运用与长程决策能力的核心作用。智能体强化学习的训练流水线通常包含五个连续环节:
- 环境与数据构建(Environment Construction):准备包含特定代码工程、依赖环境、测试用例的模板。
- 强化学习交互探索(RL Rollout):模型在沙箱中按步推理并调用工具,观察环境反馈,形成多轮轨迹(Trajectory)。
- 奖励计算(Reward Computation):根据环境最终输出的测试通过率、编译器报错、测试返回值或特定检验器计算标量奖励。
- 策略模型更新(Policy Update):基于收集的大量轨迹与奖励,利用 PPO、GRPO 等算法对模型参数进行分布式优化。
- 周期性基准评估(Periodic Evaluation):在独立的测试集上实例化沙箱,评测当前模型能力的泛化性。
在上述阶段中,RL Rollout 和周期性评估对底层沙箱计算平台构成了绝大部分压力。现代强化学习系统为了对抗推理长尾延迟、最大化 GPU 计算吞吐,普遍引入了异步 Rollout 管道——即不断生成并并发维持大量处于不同执行进度的沙箱会话。
1.2.2 生产级智能体执行环境的七大本质特征
根据 DeepSeek 生产集群的长期观测与度量,智能体沙箱环境呈现出与传统云原生微服务截然不同的负载特征:
1. 创建请求呈现剧烈脉冲与突发性(Bursty Demand)
强化学习是以 Batch(批次)为单位推进的。一个大型训练或评测 Job 往往会在几秒钟之内瞬时请求创建数千到数万个沙箱实例(生产峰值单任务请求高达 32,000 个沙箱)。由于模型必须等待沙箱就绪后才能进行首轮推理,任何镜像拉取或初始化的长尾延迟(Stragglers)都会直接转化为昂贵 GPU 集群的空转等待。
2. CPU 计算利用率高度稀疏,天然依赖高密度超卖(Sparse Utilization & High Density)
在智能体的多轮交互过程中,沙箱的典型生命周期呈现“脉冲式计算—长时间等待”的交替形态。如图 1-2 所示,整个生命周期分为 Setup 阶段(初始化依赖)、Tool-call 阶段(工具调用与交互)和 Test 阶段(测试验证)。在 Tool-call 阶段,沙箱绝大多数时间处于阻塞等待状态,等待远端 GPU 上的大模型生成下一个 Action;沙箱内部的真实 CPU 占用极低。
gantt
title 典型智能体沙箱生命周期中的资源利用特征
dateFormat X
axisFormat %s 秒
section 交互状态
环境装配与初始化 (Setup) :active, 0, 15
LLM 思考与生成 Token (Sandbox Idle) :crit, 15, 45
执行工具调用命令 (CPU Burst) :active, 45, 50
LLM 思考与生成 Token (Sandbox Idle) :crit, 50, 85
执行文件修改与编译 (CPU Burst) :active, 85, 95
执行最终单元测试 (Test Burst) :active, 95, 115生产数据显示,约 90% 的容器与 MicroVM 沙箱平均 CPU 占空比不超过所申请配额的 5%。这意味着系统必须进行数十倍甚至上百倍的资源超卖(Overcommit)。在生产中,单个计算节点稳定承载多达 3,200 个容器或 800 个 MicroVM。
3. 运行状态具有强驻留性与长期寿命(Stateful & Long-lived)
与无状态的 Serverless 函数不同,智能体在解决软件工程或复杂系统任务时,会在沙箱内创建文件、切换 Git 分支、安装临时依赖包、启动后台守护进程。沙箱必须在整个交互周期内精确保持这些状态。 生产数据显示,容器沙箱的运行寿命中位数为 17.4 分钟,MicroVM 为 15.5 分钟,而 P99 寿命超过 3 小时。在此期间,沙箱内部产生的文件系统改动、Guest OS 与 Host OS 的内存页缓存(Page Cache)一直被钉住(Pinned),长期占据宝贵的 DRAM 物理空间。
4. 任务场景极端异构(Workload Heterogeneity)
智能体任务覆盖多种迥异的执行需求:
- 算法刷题与简短执行(OJ 任务):需要极快的冷启动和最小开销,但无需复杂系统服务。
- 软件工程仓库开发(SWE):需要完整的 Linux 用户态工具链(Python, Node.js, Rust, C++ 等)和 Git 工作流。
- 安全红蓝对抗与漏洞利用:需要强内核级隔离,防止未信任代码利用共享内核发起提权或越权反扑。
- 计算机操作与多媒体渲染(Computer Use):需要图形界面渲染(GUI)、桌面系统乃至 Android 模拟器运行支持。
单一的沙箱技术路线(如纯容器或纯全虚拟化)无法同时满足上述所有场景在性能与安全上的诉求。
5. 镜像集合规模巨大且扇出复用率极低(Large Working Sets & Low Fanout)
在传统的 Web 微服务场景中,几个核心业务镜像会在成千上万个节点上大规模运行,节点本地镜像缓存命中率极高。而在智能体训练中,训练集涵盖成千上万个不同的开源或内部项目,每个任务都有独立的代码版本与依赖。
- 在 DeepSeek 生产环境单周内,活跃着 11,266 个容器基础镜像 与 102,171 个独立工作区(Workspace),总镜像资产超过 130 TB。
- 低扇出(Low Fanout):容器镜像的中位数复用扇出仅为 3(P90 扇出为 28),而 MicroVM 镜像的中位数扇出仅为 1。这意味着本地磁盘缓存近乎完全失效,每次突发启动都必然引发镜像分发。
- 低运行时读取率:如表 1-1 所示,各种语言环境的镜像在运行时真正被读取的数据只占其总大小的 4.2%~13.3%,全量拉取镜像存在 85% 以上的网络与磁盘 I/O 浪费。
| 环境类别 | 镜像压缩大小 (MB) | 解压后体积 (MB) | 交互期真实读取量 (MB) | 实际数据读取率 (%) |
|---|---|---|---|---|
| Python 数据科学栈 | 2,840 | 8,120 | 345 | 4.2% |
| Node.js 前端全栈 | 1,420 | 4,350 | 382 | 8.8% |
| Rust / C++ 编译环境 | 3,110 | 9,450 | 690 | 7.3% |
| Android 模拟器与 SDK | 8,900 | 24,500 | 3,260 | 13.3% |
6. 确定性重放与严格防作弊需求(Anti-Cheating & Determinism)
在强化学习中,智能体会极尽所能寻找奖励函数的漏洞(Reward Hacking):
- 篡改测试用例:直接修改本地单元测试脚本,使其永远返回
exit 0; - 探测环境并硬编码返回值:读取预设的隐藏验证集;
- 耗尽算力发起拒绝服务:启动 Fork 炸弹或死循环挂死宿主机。 因此,沙箱基础设施必须在内核层实施严格的防作弊策略与只读保护。
1.3 异构沙箱运行时全景与系统权衡
为了应对异构负载,业界与学术界演化出了四种典型的执行环境形态。如图 1-3 所示,各形态在冷启动耗时、隔离强度、系统开销与特权能力上形成了显著的 Pareto 前沿。
flowchart TD
subgraph IsolationLevels["沙箱隔离技术栈全景对比"]
direction TB
subgraph L1["级别 1: 函数级沙箱 (Function / WASM)"]
F1["V8 Isolate / WebAssembly<br/>毫秒级启动, 内存开销 < 5MB<br/>缺陷: 无 Linux 系统调用, 无法运行原生工具链"]
end
subgraph L2["级别 2: 原生容器沙箱 (Linux Containers)"]
C1["Namespace + Cgroups + Seccomp<br/>秒级启动, 内存开销 20~50MB<br/>优势: 共享宿主机内核, I/O 性能极高<br/>缺陷: 存在内核漏洞逃逸风险, 无法修改内核参数"]
end
subgraph L3["级别 3: 微虚拟机沙箱 (MicroVMs)"]
M1["Firecracker / Cloud-Hypervisor<br/>启动耗时 100~300ms, 内存开销 100~200MB<br/>优势: 独立 Guest 内核, 硬件级虚拟化隔离 (Intel VT-x / AMD-V)<br/>缺陷: 双重页缓存, 嵌套虚拟化开销"]
end
subgraph L4["级别 4: 全功能虚拟机 (Full VMs)"]
V1["QEMU / KVM 全虚拟化<br/>启动耗时 10~30s, 内存开销 > 1GB<br/>优势: 支持任意 OS、PCI 设备直通、图形渲染与 Android 运行<br/>缺陷: 资源笨重, 无法超大规模密度部署"]
end
L1 --> L2 --> L3 --> L4
end1.3.1 四类运行时定量选型对比表
| 指标维度 | 函数级 / WASM | Linux 容器 (Container) | 微虚拟机 (MicroVM) | 全虚拟化 (Full VM) |
|---|---|---|---|---|
| 典型代表 | Cloudflare Workers, Wasmtime | Docker, Podman, runc | Firecracker, Kata Containers | QEMU + KVM |
| 冷启动延迟 | $< 5\text{ ms}$ | $500\text{ ms} \sim 2\text{ s}$ | $100 \sim 300\text{ ms}$ | $10 \sim 30\text{ s}$ |
| 单实例基础内存开销 | $< 10\text{ MB}$ | $20 \sim 50\text{ MB}$ | $100 \sim 200\text{ MB}$ | $1 \sim 2\text{ GB}$ |
| 单机最大并发密度 | $> 10,000$ | $2,000 \sim 3,500$ | $500 \sim 1,000$ | $50 \sim 100$ |
| 隔离边界 | 语言/字节码虚拟机 | Linux 内核 Namespaces | 硬件辅助虚拟化 (CPU/MMU) | 完整硬件模拟 |
| 内核特权与环境自洽性 | 极低 (无原生系统调用) | 中等 (共享宿主内核) | 高 (独立 Guest 内核) | 极高 (支持自定义模块) |
| 多租户安全防护能力 | 脆弱 (共享进程空间) | 较弱 (易受内核 0-day 逃逸) | 极强 (硬件边界阻断) | 极强 (物理边界模拟) |
| 最佳适配智能体任务 | 纯 Python/JS 算法代码评估 | 通用 SWE 软件工程任务 | 外部不可信代码、内核安全对抗 | Android 模拟器、桌面 GUI 交互 |
1.4 DSec 总体架构设计
DeepSeek 的 DSec(DeepSeek Elastic Compute) 并非一个简单的虚拟机调度平台,而是一个高度面向强化学习交互流水线定制的、端到端解耦的智能体弹性执行基础设施。
1.4.1 分层架构与核心组件
如图 1-4 所示,DSec 架构在逻辑上划分为四个核心层级:
- 控制调度层(Control & Orchestration):暴露极简的 gRPC API,接收强化学习 Rollout 与评估请求。通过会话亲和性调度器(Session-Affinity Scheduler),将具有相同 Base 镜像的任务分发至同一计算节点。
- 边缘节点运行时管理(Edge Daemon):运行在宿主机上的轻量守护进程,管理容器 runc 与 MicroVM Firecracker 实例的生命周期、挂载点拼装与 cgroups 动态配置。
- 分层按需存储引擎(Tiered Storage Engine):基于 EROFS 只读文件系统与 3FS 分布式存储系统,实现秒级镜像流式按需供给与本地 NVMe 环形缓存。
- 内核级 QoS 与超卖治理(Kernel-level Overcommit & QoS):通过
virtio-pmem+ DAX、DAMON 冷内存回收与 Linux Core Scheduling 保障单机千级实例的高密稳定运行。
flowchart TB
subgraph ControlPlane["控制调度平面 (Control Plane)"]
API["DSec gRPC Gateway"]
Scheduler["批次感知与亲和性调度器 (Affinity Scheduler)"]
API --> Scheduler
end
subgraph StorageSubsystem["分布式存储底座 (3FS Distributed Storage)"]
ThreeFS["3FS 分布式共享存储集群<br/>(数十 TB/s 聚合读取带宽, RDMA 互联)"]
BaseStore["Base 镜像 Blobs"]
ToolStore["Toolkit 工具链 Blobs"]
WorkStore["Workspace 代码仓库 Blobs"]
ThreeFS --- BaseStore
ThreeFS --- ToolStore
ThreeFS --- WorkStore
end
subgraph ComputeNode["计算节点 (High-Density Bare-Metal Node)"]
Edge["DSec Edge Daemon (宿主机运行时管理器)"]
LocalCache["本地 NVMe 环形缓存 (L2 Cache)"]
subgraph MemoryGov["内核内存与 CPU 治理模块"]
DAX["virtio-pmem DAX<br/>共享 Host Page Cache"]
DAMON["DAMON 监控 + Balloon FPR<br/>Order-9 归还"]
CoreSched["Core Scheduling<br/>PR_SCHED_CORE + SCHED_IDLE"]
end
subgraph Sandboxes["高密异构沙箱集群 (单机承载数百至数千实例)"]
C1["Container 1 (SWE Task)"]
C2["Container 2 (OJ Task)"]
VM1["MicroVM 1 (Untrusted Code)"]
VM2["MicroVM 2 (Linux Kernel Exploit)"]
end
Edge --> Sandboxes
MemoryGov -.-> Sandboxes
end
Scheduler -->|"调度实例派发"| Edge
ComputeNode <==|"按需流式大块读取 (On-Demand Bulk Read)"| ThreeFS1.5 核心模块深度工程实现与机理剖析
1.5.1 可组合分层文件系统(Composable Layered Storage)
镜像组合爆炸难题
在早期的智能体评测中,如果将“操作系统环境”、“代码仓库”与“工具链(Harness/Prompts)”打成单体 Docker 镜像,会面临严重的组合爆炸问题。 设系统中存在 $m$ 个基础开发环境(Python 3.10, Node 18, Rust 1.75 等),测试数据集中有 $N$ 个代码仓库(SWE-bench 包含数万个独立的 Commit 快照),工具链演进迭代了 $k$ 个版本。若采用单体镜像方案,需要构建和分发的镜像总数为:
$$\text{Image Count}_{\text{monolith}} = m \times N \times k$$这不仅在存储上造成数百 TB 的冗余,而且每次工具链的小幅更新都会导致全部镜像重新全量构建。
解耦架构:三层分立与 EROFS 组合
DSec 采用可组合分层存储范式,将执行镜像物理拆解为三个正交的层:
- 基础层(Base Layer):由平台预先烘焙的纯净环境(Ubuntu, Python, gcc, git),生命周期最长,版本稳定;
- 工作区层(Workspace Layer):由代码工程、特定 commit 的源文件、预安装的第三方依赖构成,数量庞大($10^5$ 量级);
- 工具链层(Toolkit Layer):智能体执行时所需的辅助脚本、API 拦截器、Prompt 配置文件与测试驱动二进制程序,版本更新极其频繁。
在沙箱启动时,Edge 守护进程直接利用 Linux 内核的原生 Overlayfs,在纳秒级将三层自底向上动态堆叠:
$$\text{RootFS} = \text{Overlayfs}(\text{upperdir}=\text{local\_tmpfs}, \, \text{lowerdir}=\text{Toolkit} : \text{Workspace} : \text{Base})$$flowchart TD
subgraph MergedRoot["沙箱可见的统一文件系统视图 (/ 根目录)"]
UnifiedView["/workspace, /tools/dsh, /usr, /bin, /etc"]
end
subgraph Overlay["Overlayfs 动态挂载机制"]
Upper["Upperdir (宿主机本地 NVMe 可写层)<br/>存放交互产生的新增文件、Git 变更与测试日志"]
subgraph LowerDirs["Lowerdir (只读层列表,按优先级自顶向下合并)"]
T1["Toolkit Layer (EROFS 只读)<br/>挂载于 /tools/dsh, 包含 Harness 二进制与 Prompt 配置"]
W1["Workspace Layer (EROFS 只读)<br/>挂载于 /workspace, 包含被测代码仓库与对应 commit"]
B1["Base Layer (EROFS 只读)<br/>包含 OS rootfs, Python 运行环境与通用动态库"]
end
end
UnifiedView <--> Upper
Upper --> LowerDirs
T1 --> W1
W1 --> B1通过该机制,当工具链升级时,仅需更新 $k$ 个独立的 Toolkit 镜像:
$$\text{Rebuild Cost}_{\text{composable}} = O(k)$$维护开销下降数个数量级。
30 行 Go 代码定制 Dockerd 动态 Lowerdir 注入
为实现上述能力,无需引入沉重的外部插件。DeepSeek 针对开源码头守护进程 Moby/dockerd 进行了极简的工业级改造(仅修改约 30 行 Go 代码)。
在默认情况下,Docker 仅根据镜像自身的 Manifest 构建 lowerdir 参数。DSec 允许在调用创建容器接口时,通过附加参数传入宿主机上预先就绪的 EROFS 挂载路径数组,dockerd 在最终调用系统 mount(..., "overlay", ...) 之前,将这些外部路径前置插入到 lowerdir 列表中:
// dockerd 内部 overlay2 驱动挂载点拼装简化示意 (Moby Patch)
func (d *Driver) getLowerDirs(imageLayers []string, extraLayers []string) string {
// 将 DSec 动态注入的 Toolkit 与 Workspace EROFS 挂载路径置于最前端
var allLowers []string
for _, extra := range extraLayers {
allLowers = append(allLowers, extra) // 优先级最高,覆盖同名基础文件
}
allLowers = append(allLowers, imageLayers...)
return strings.Join(allLowers, ":")
}
1.5.2 基于 3FS 的按需镜像流式载入机制
架构选择:分布式文件系统 3FS vs 传统 Registry P2P
业界流行使用基于 P2P 网络(如 Dragonfly、Kraken)的容器镜像拉取方案。然而,P2P 方案依赖节点之间互相传输数据块。当大规模批次同时请求数万个完全互不相同的镜像时(低扇出,中位数扇出仅为 1~3),节点之间不存在可复用数据块,P2P 协议会彻底退化为中心 Registry 的拥塞源。
DSec 全面复用 DeepSeek 内部支撑 GPU 训练的高性能分布式文件系统 3FS(Fire-Flyer File System):
- 节点配置:存储节点单机配备 20 块 15TB NVMe SSD、双口 400Gbps RDMA 网卡,集群聚合 I/O 带宽达数十 TB/s。
- 3FS 的非对称 I/O 特性:极擅长超大规模的顺序并发大读写,但在处理海量 4KB 随机小 I/O 时开销显著。
基于该特性,DSec 制定了三条工程铁律:
- 写操作永远留在本地(Writes stay local):智能体执行时产生的碎片日志、测试编译产物一律写入宿主机本地 NVMe SSD,绝不上报 3FS。
- 读操作按需大块批处理(Reads are on-demand and bulk):只读镜像数据存放在 3FS 上,只有沙箱实际读取某段数据时才按需触发拉取。
- 元数据本地完全预热(Metadata is kept local):文件系统的路径查找(
stat,lookup,readdir)往往是极其高频的随机小 I/O。如果每次ls都访问 3FS 将导致网络延迟剧增。
EROFS 多设备模式(Multi-Device Mode)实现
EROFS(Enhanced Read-Only File System)支持将文件系统的**元数据(Metadata)与数据块(Data Blobs)**完全物理分离:
- 在沙箱实例化前,Edge 仅将体积微小的 EROFS 元数据块预先下载至宿主机本地内存/SSD(通常每个镜像仅几百 KB 至数 MB);
- 容器启动挂载 EROFS 时,所有的路径索引、权限解析直接在宿主机本地极速完成;
- 当进程真正打开并读取具体文件内容时,内核 EROFS 驱动通过其 File-backed 接口直接发起大块对齐的网络读取,直接流式读取 3FS 上的 Data Blob。
MicroVM 的 OverlayBD 与 ublk 用户态块设备
在 MicroVM 环境中,Firecracker 无法直接消费宿主机的 EROFS 挂载点,必须以虚拟块设备暴露存储。 DSec 采用 Rust 实现的 OverlayBD + Linux 原生 ublk(Userspace Block Device) 架构:
- 通过 ublk 将 3FS 上的分层块数据虚拟化为标准的 Linux
/dev/ublkbX块设备,挂载为 MicroVM 的虚拟磁盘; - 256 KiB 分块本地二级缓存(L2 Local Cache):为了抑制 MicroVM 内 ext4 文件系统元数据引发的随机小读,ublk 驱动内部实现了 256 KiB 粒度的块对齐预取与本地 NVMe 环形缓存。即便 Guest OS 的 Page Cache 发生换出,二次访问也直接命中宿主本地缓存,杜绝重复远端流量。
1.5.3 高密度超卖下的资源治理与 QoS 保障
内存治理:virtio-pmem + DAX 的内核开销推导与共享页缓存
在单个节点承载多达 800 个 MicroVM 时,内存是决定系统容量的绝对瓶颈。微虚拟机存在两大内存顽疾:
- 双重页缓存惩罚(Double Caching):宿主机从 3FS 读取镜像文件缓存了一次 Page Cache,通过虚拟磁盘送入 MicroVM 后,Guest OS 内核又在自己的虚拟 RAM 里缓存了一次,导致物理内存消耗翻倍。
- Guest 空闲内存无法自发回收:虚拟机内部即便释放了进程内存,由于缺乏与宿主机的协商机制,宿主机仍认为该物理页处于占用状态。
针对只读数据,DSec 启用 virtio-pmem 结合 DAX(Direct Access):
- 将宿主机端挂载的 EROFS 镜像空间以持久内存(pmem)的形式映射给 MicroVM。
- 开启 DAX 特性后,Guest OS 内核的文件 I/O 绕过 Guest 自身的 Page Cache,直接通过 CPU 内存寻址指令读取宿主机映射的物理页。800 个 MicroVM 共享同一份 Host Page Cache 镜像数据,如图 1-6 所示。实测该项优化使宿主机内存峰值占用降低 40.2%。
flowchart TB
subgraph Host["宿主机内存空间 (Host Physical RAM)"]
HostPC["全局单一只读镜像页缓存 (Shared Host Page Cache)<br/>由 3FS 流式载入"]
HostBuddy["宿主机内存伙伴系统 (Host Buddy Allocator)"]
end
subgraph VM1["MicroVM 1"]
App1["Agent Python / Shell 进程"]
GPC1["Guest 可写盘 Page Cache<br/>(冷页逐渐堆积)"]
App1 -->|"直接内存寻址读取 (DAX 直读)"| HostPC
DAMON1["DAMON 冷页监控采样"] -.->|"识别 > 阈值未访问页"| GPC1
GBuddy1["Guest 伙伴系统"]
Balloon1["virtio-balloon<br/>Free-Page Reporting"]
GPC1 -->|"主动 evict 释放"| GBuddy1
GBuddy1 -->|"拼装 Order-9 (2MB) 连续大块"| Balloon1
end
subgraph VM2["MicroVM 2"]
App2["Agent 进程"]
App2 -->|"直接内存寻址读取 (DAX 直读)"| HostPC
end
Balloon1 ==>|"madvise(MADV_DONTNEED)<br/>归还物理内存"| HostBuddy内核内存开销的定量数学推导
虽然 virtio-pmem 消除了数据页的双重缓存,但在操作系统内核层,Guest OS 内核必须为每一段被识别的物理内存分配 struct page 结构体进行元数据追踪。
在 Linux x86_64 体系结构下,每个标准 4 KiB 物理页对应一个大小为 64 字节的 struct page。因此,映射设备大小为 $S_{\text{pmem}}$ 的内存所引发的不可逐出 Guest RAM 开销为:
这意味着,如果为 Guest 盲目挂载一个 128 GiB 的超大 pmem 设备,仅内核 struct page 元数据就会永久吃掉 Guest 内部高达 $2\text{ GiB}$ 的真实物理内存!
为此,DSec 设计了按需紧凑映射算法:Edge 根据 Workspace 实际解压后体积动态配置 pmem 窗口大小(通常限定在 $4 \sim 16\text{ GiB}$),将 Guest 内核元数据损耗严格压制在 $64 \sim 256\text{ MiB}$ 以内。
动态冷页回收:DAMON + Balloon FPR
针对必须可写的本地磁盘空间,virtio-pmem 不再适用。DSec 组合了 DAMON(Linux 内核数据访问监控器) 与 virtio-balloon 的自由页上报机制(Free-Page Reporting, FPR):
- DAMON 冷页淘汰:在 Guest 内核中运行轻量 DAMON 采样线程,按可配置的时间窗口监测各内存页的活跃度。凡超过阈值未被访问的冷文件页(Cold File Pages),主动触发
reclaim将其从 Guest Page Cache 中逐出,放回 Guest 自身的伙伴系统(Buddy Allocator)。 - FPR 大页上报:Guest 内部的 virtio-balloon 驱动定期扫描伙伴系统,当回收的冷页聚合成 Order-9 连续物理块(在 4KB 基准页下对应 2 MiB) 时,向宿主机 Hypervisor 发起主动通知。
- 宿主机内存解绑:宿主机收到上报后,执行系统调用:通知 Linux 内核直接卸载对应的宿主机物理内存映射。实测该机制在几乎不耗费 CPU 的前提下,使长期存活沙箱的积分内存占用下降了 21.2%。
madvise(guest_hva_addr, 2 * 1024 * 1024, MADV_DONTNEED);
CPU QoS:SCHED_IDLE 配合 Linux Core Scheduling
在超卖比高达数十倍的宿主机上,如果单纯依赖 Linux CFS 调度器的 CPU 配额权重,当宿主机开启超线程(SMT)时,同一物理核上的两个硬件线程(Sibling Hardware Threads)会共享 L1/L2 缓存、执行单元和乱序执行队列。后台 Best-Effort(BE)任务在兄弟硬件线程上的执行会导致 Latency-Sensitive(LS)关键任务遭受严重的时延抖动(实测步时延膨胀达 45.2%)。
DSec 构建了双层 CPU QoS 防御机制:
- 优先级降级:将所有 BE 沙箱的工作进程加入
SCHED_IDLE调度策略,保证只要节点上有任何普通或 LS 任务处于就绪态,BE 任务立刻让出 CPU。 - 物理核心强隔离(Core Scheduling):针对 LS 沙箱,利用 Linux 原生接口:为 LS 任务分配专有的核心调度 Cookie。内核调度器在进行同周期调度判定时,严格杜绝属于不同 Cookie 的 BE 任务与 LS 任务共存排布在同一个物理核心的两个超线程上。
prctl(PR_SCHED_CORE, PR_SCHED_CORE_CREATE, ...);
// 文件路径: src/qos/cpu_core_sched.c
// 生产级 Linux Core Scheduling 与 SCHED_IDLE 绑定实现
#define _GNU_SOURCE
#include <sys/prctl.h>
#include <sched.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#ifndef PR_SCHED_CORE
#define PR_SCHED_CORE 62
#define PR_SCHED_CORE_CREATE 1
#define PR_SCHED_CORE_SCOPE_THREAD_GROUP 1
#endif
int configure_sandbox_cpu_qos(pid_t pid, int is_latency_sensitive) {
if (is_latency_sensitive) {
// 1. 为延迟敏感型沙箱创建独立的核心调度 Cookie,杜绝超线程 SMT 侧信道与算力争用
if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_CREATE, pid, PR_SCHED_CORE_SCOPE_THREAD_GROUP, 0) != 0) {
perror("[CPU-QoS] prctl PR_SCHED_CORE_CREATE failed");
return -1;
}
printf("[CPU-QoS] 成功为 PID %d 分配独占 Core Scheduling Cookie\n", pid);
} else {
// 2. 为普通后台离线执行任务分配 SCHED_IDLE 策略,算力绝对退让
struct sched_param param = { .sched_priority = 0 };
if (sched_setscheduler(pid, SCHED_IDLE, ¶m) != 0) {
perror("[CPU-QoS] sched_setscheduler SCHED_IDLE failed");
return -1;
}
printf("[CPU-QoS] 成功将 PID %d 降级为 SCHED_IDLE 算力退让模式\n", pid);
}
return 0;
}
该机制将超线程资源争用引起的时延膨胀从 45.2% 压制到了 17.3%,彻底筑牢了高密度运行下的性能底线。
1.6 基础设施与强化学习框架的协同设计
1.6.1 Agent Loop 与 GPU 训练框架彻底解耦
在早期的强化学习架构中,驱动智能体思考的 Agent Loop(管理多轮会话状态、调度 Tool Call 的控制进程)通常直接跑在昂贵的 GPU 训练 Pod 内部。一旦训练任务因各种原因发生抢占(Preemption)或故障中断,运行在 GPU Pod 里的 Agent Loop 随之崩溃。尽管远端计算节点上的沙箱还在,但因为失去了连接上下文,整个数小时的 Rollout 探索前功尽弃。
自 DeepSeek-V4.1 起,架构演进为完全解耦的三体模式,如图 1-7 所示:
flowchart LR
subgraph GPUPool["可随时被抢占的 GPU 训练资源池 (Preemptible GPU Pool)"]
Trainer["RL 优化器 (Trainer)"]
LLMInference["模型权重推理服务 (LLM Serving)"]
end
subgraph StateStorage["外部持久状态存储 (Single Source of Truth)"]
RolloutDB["分布式元数据存储 (Redis / MySQL / Raft)<br/>保存会话上下文、未完成的 Tool Call 与执行指针"]
end
subgraph SandboxNode["沙箱计算节点 (DSec Fleet)"]
direction TB
subgraph SandboxGroup["轻量沙箱编排层"]
AgentLoopProc["独立的 Agent Loop 驱动进程<br/>(Worker Container 内部运行)"]
ActiveSandbox["沙箱宿主实例<br/>(Container / MicroVM)"]
AgentLoopProc <-->|"STDIN / STDOUT / Exec"| ActiveSandbox
end
end
Trainer -.->|"参数同步更新"| LLMInference
AgentLoopProc -->|"发请求推理下一个 Token"| LLMInference
AgentLoopProc <-->|"原子写入每步状态与轨迹"| RolloutDB- 状态唯一事实源(Single Source of Truth):Agent Loop 每一轮对话和工具调用的状态,实时以不可变事件的形式追加至远端存储;
- 透明恢复机制:若 GPU 集群发生弹性缩容或抢占,GPU Pod 可以在几分钟甚至几小时后重新就绪。新拉起的进程根据会话 ID 从外部存储重新挂接回远端沙箱,直接继续未完成的交互步,真正实现了秒级断点续跑。
1.7 横向架构对比:DSec vs 主流运行时
为了确立高阶系统工程的宏观视野,下表将 DSec 与当前云计算与 AI 基础设施领域的四种代表性执行平台进行全景横向对比。
1.7.1 五大沙箱基础设施全景对比矩阵
| 评估维度 | DeepSeek DSec | Kubernetes + Knative | Ray Train / Serve | AWS Firecracker (Lambda) | Modal / E2B Sandbox |
|---|---|---|---|---|---|
| 核心业务定位 | 超大规模 RL 训练与 SWE 智能体沙箱 | 云原生微服务与 Serverless 工作负载 | 分布式 Python 计算与大规模模型训练 | 公有云多租户 Serverless 函数与小容器 | 面向 AI Coding 的开发者沙箱云平台 |
| 底层隔离形态 | 异构混合 (Moby+Patch 容器 / Firecracker) | 容器为主 (runc/containerd),部分 Kata | 单进程 / 多线程 / Ray Actor 进程隔离 | 纯硬件辅助微虚拟机 (KVM MicroVM) | gVisor 用户态内核 / Firecracker MicroVM |
| 低扇出镜像流式分发 | 极高 (EROFS + 3FS 非对称大块读取) | 极低 (依赖 Docker Registry,拉取整层) | 无 (依赖共享 NFS 或本地预分发) | 中等 (自研分块快照流式按需读取) | 高 (自研分层按需懒加载流式文件系统) |
| 单机实例并发密度 | 3,200 容器 / 800 MicroVM | 110 ~ 250 Pods (受限于 CNI 与 Kubelet) | 几百个 Python 进程 (受 GIL 与内存限制) | 约 1,000 MicroVM (无 GPU/大内存共享) | 约 500 ~ 800 实例 |
| 内存去重与超卖 | virtio-pmem DAX + DAMON FPR 归还 | 依赖 Linux KSM (开销巨大,通常禁用) | 无内存去重机制,易发生 OOM-Kill | 静态内存分配,依赖冷实例快速挂起冻结 | 虚拟内存压缩与按需缺页加载 |
| CPU QoS 保障 | Linux Core Scheduling + SCHED_IDLE | Linux CFS 静态限额 (cgroup cpu.cfs_quota) | Ray 内部逻辑资源分配,无内核隔离 | 虚拟 vCPU 独占或积分信用突发 (Burstable) | 依赖 Linux CFS 权重,无 SMT 侧信道防御 |
| RL 训练框架协同 | 原生三体解耦,断点透明重挂 | 需借助外部复杂 Operator 协调 | 紧密耦合于 Ray 集群内部,容易级联崩溃 | 无特定协同,面向单次短任务调用 | 面向 API 调用,依赖应用层自行记录 Checkpoint |
1.7.2 关键架构机理辨析
- 对比 Kubernetes / Knative:
- K8s 是为“长期运行、高扇出复用、低变动频率”的 Web 微服务设计的。其 Kubelet 周期上报心跳、CNI 网络接口分配(IPAM)、Pod 探针检查开销巨大,无法承受单节点瞬时创建数千个沙箱的突发脉冲(Kubelet 会直接出现调度雪崩)。
- DSec 舍弃了复杂的 CNI/CSI 网络与存储卷协议栈,直接在单机内核层通过 Moby 补丁与 EROFS 直挂实现纳秒级启动,冷启动吞吐量比标准 K8s 高出两个数量级。
- 对比 Ray:
- Ray 是 Python 优先的分布式计算执行引擎,擅长处理密集的数据流图和 Actor 通信。然而,Ray Actor 共享相同的操作系统环境,缺乏系统级的物理安全边界与文件系统回滚能力。一旦智能体执行了恶意 Shell 命令(如
rm -rf /或系统提权),整个 Ray Worker 节点随之沦陷。 - DSec 坚持微内核级别的强隔离原则,将不受信任的模型生成代码严格囚禁于 MicroVM 或独立可写层内。
- Ray 是 Python 优先的分布式计算执行引擎,擅长处理密集的数据流图和 Actor 通信。然而,Ray Actor 共享相同的操作系统环境,缺乏系统级的物理安全边界与文件系统回滚能力。一旦智能体执行了恶意 Shell 命令(如
- 对比 Modal / E2B:
- Modal 和 E2B 代表了当前面向 AI 智能体的现代商业沙箱产品,采用虚拟化与懒加载文件系统技术。
- DSec 的本质差异在于其与强化学习训练集群(尤其是 3FS 分布式存储底座)的深度软硬件共设计。DSec 充分利用了内部现成的高速 RDMA 网络与非对称大块吞吐特性,摒弃了昂贵的通用多租户计费与网关封装,换取了极致的吞吐密度与超卖比。
1.8 本章小结
本章系统剖析了 DeepSeek 在智能体执行环境与超大规模沙箱基础设施领域的前沿架构与工程实践:
- 负载特征洞察:揭示了突发创建、极低 CPU 占空比、长驻状态、环境极端多样与低扇出镜像读取等七大本质特征;
- 存储架构革新:剖析了通过 EROFS 将 Base、Workspace 与 Toolkit 三层解耦的可组合分层文件系统,基于 3FS 实现了按需流式大块读取,将维护成本从乘积级降至加和级;
- 极限超卖治理:推导了
virtio-pmemDAX 的 Guest 内核元数据内存损耗公式,阐述了结合 DAMON FPR 与 Linux Core Scheduling 实现单机承载 800 MicroVM / 3,200 容器的高密稳定运行机理; - RL 深度协同:构建了 Agent Loop 与 GPU 训练解耦的三体模式,消除了长程交互因 GPU 抢占而中断的行业难题;
- 系统横向横评:严密对比了 DSec 与 Kubernetes、Ray、Firecracker 及 Modal/E2B 的架构取舍,确立了面向智能体下一代系统的基础设施设计准则。
1.9 思考题与进阶实践
思考题
- 存储架构分析:在智能体训练场景中,为什么传统的 Docker Registry 镜像预拉取方案或 P2P 分发网络(如 Dragonfly)会彻底失效并退化为中心瓶颈?DSec 是如何利用 3FS 的非对称 I/O 特性破局的?
- 内核内存机理推导:如果一个 MicroVM 挂载了 256 GiB 的 EROFS 只读镜像,按照 Linux 4KB 分页机制,Guest OS 内核追踪该空间所消耗的物理内存大小是多少?如果宿主机物理内存告急,这部分内存能否被宿主机的 Swap 机制换出?为什么?
- CPU QoS 辨析:阐述为什么单纯依靠 Linux cgroups 的
cpu.weight无法完全消除后台 Best-Effort 任务对实时 Agent 任务的性能干扰。Linux Core Scheduling 是在处理器的哪个硬件层次解决资源争用的? - 架构解耦分析:简述“Agent Loop 进程与 GPU 训练框架彻底解耦”如何解决强化学习长程 Rollout 的容错难题。
进阶实践实验:利用 Linux Namespaces 与 Overlayfs 手工构建轻量沙箱
实验目标:在 Linux 环境下,编写一段 Bash 或 C 语言脚本,模拟 DSec 的分层存储挂载与进程隔离。
实验要求:
- 构建三层文件系统:准备一个基础系统目录(Base)、一个测试代码目录(Workspace)和一个工具目录(Toolkit);
- 执行动态 Overlay 挂载:使用
mount -t overlay将三层作为只读lowerdir堆叠,并挂载一个独立的upperdir本地目录作为可写层; - 实施轻量隔离运行:利用
unshare命令创建独立的 Mount, PID 和 IPC 命名空间,在隔离根目录下启动一个交互式 Shell; - 验证状态写隔离:在沙箱内部创建新文件并修改源代码,退出沙箱后验证底层 Workspace 与 Base 目录保持绝对纯净未被修改,所有新增状态完全收敛于
upperdir中。