第 11 章 第二部分:架构原理

Runtime Injection:Nix 自包含的秘密

为什么需要自包含服务、Nix 构建方案、与 OpenHands/SWE-ReX 的对比、Checkpoint 加速

Nexus Nix Docker Runtime Injection 沙箱

问题:镜像维护的噩梦

Code Agent 场景的一个根本工程问题:LLM 输出的动作(执行命令、编辑文件)需要在目标环境中执行。这需要一个程序在环境中接收并执行动作。

主流方案是在容器内启动一个服务(OpenHands 和 SWE-Agent 都这么做)。但这带来了 Scale 难题:

以 SWE-Gym 为例:2438 个实例,每个对应一个不同的 Docker 镜像,总计约 6TB。如果你要在所有镜像上运行 Agent,就需要给 2438 个镜像全部安装运行时依赖——可能遇到依赖冲突、构建失败、维护成本爆炸。

OpenHands 的做法:为每个基础镜像构建新的运行时镜像。要求目标环境基于 Debian,需要安装指定版本的依赖。

SWE-ReX 的做法:两种模式——动态安装(pipx install)或构建新镜像。前者需要网络,后者和 OpenHands 一样要维护镜像映射。

Nexus 的解法:完全自包含的 /nix volume

核心思路:做一个不依赖任何外部系统就能运行的服务,放在一个公共 Docker volume 中。任何镜像挂载这个 volume 就能启动。

第一步:Nix 构建基础依赖

通过 Nix(声明式包管理器)构建所有操作系统级依赖:Python、uv、git、tmux、chromium、sshd 等。Nix 的关键特性是路径确定性——所有依赖存储在 /nix/store 下,路径基于内容哈希生成。

第二步:uv 构建 Python 环境

基于 Nix 提供的 Python,用 uv 创建 venv 并安装所有 pip 依赖。环境存储在 /nix/runtime/。

第三步:Docker volume 挂载

构建一个只包含 /nix 目录的数据镜像。使用时:

# 创建数据容器
docker run -d --name nexus-runtime nexus-runtime:latest true

# 任意镜像挂载 volume 并启动服务
docker run --volumes-from nexus-runtime -it alpine \
  /nix/runtime/nix-env/bin/bash /nix/runtime/nexus/deployment/runtime/start.sh

Alpine 镜像(musl-based)都能跑——因为 Nix 构建的所有东西都是自包含的,不依赖宿主的 glibc。

方案对比

维度OpenHandsSWE-ReXNexusDocker Sandboxesagent-sandboxmcp-boxWASM Sandbox
启动方式构建新镜像动态安装/构建镜像挂载 volumemicroVM 启动Podman rootfsNix 构建 OCI + Docker 运行Wasmtime/Wasmer 实例化
启动时间首次需构建镜像10-20秒+毫秒级秒级秒级秒级微秒-毫秒级(<5ms)
网络依赖构建时需要动态安装需要无无构建时需要构建时可选无(预编译 .wasm 模块)
镜像兼容性仅 Debian仅 glibc任意 x86 LinuxmacOS/Windows/Linux(sbx CLI 独立于 Docker Desktop)任意 Linux任意 Linux(Docker 可运行)任意 WASM 运行时(浏览器/服务器/边缘)
隔离级别容器容器容器microVM容器(rootfs)容器(零 capabilities + 只读根 + 无网络)语言级(线性内存+能力基础安全)
维护成本每个镜像单独构建每个镜像单独构建单一 volumeDocker 管理Nix 包合约单一 flake.nix单一 .wasm 模块
离线部署需预构建需预构建完全支持支持需预构建支持(预构建镜像)完全支持

mcp-box(GitHub)代表了 Nix + Docker 模式在安全敏感场景(MCP Server 执行)的深化——同样利用 Nix 的确定性构建 + Docker 隔离,但增加了零 Linux capabilities(--cap-drop=ALL)、只读根文件系统(--read-only)、tmpfs 临时空间、per-profile 网络策略(按 profile 配置,而非一律切断)等更严格的安全策略。官方口径是”只有显式挂载的目录可写,其余宿主路径不可达”,自我定位为 default-deny by design。比 Nexus volume 更安全,但牺牲了灵活性。

⚠️ 一处必须澄清的归属:mcp-box 官方 README 原文——“Nix is used for deterministic image builds when present, but it is entirely optional. Without Nix, mcp-box pulls the same pinned OCI image definitions from GHCR and runs them under the same Docker isolation model. Docker is the only hard requirement.” 也就是说,mcp-box 证明的是”容器隔离 + 默认拒绝对 MCP Server 有效”,不能算作 Nix 普适性的证据。它真正说明的是另一件事(见下):Nix 在这里是可插拔的。

WASM Sandbox 代表了一个不同的隔离哲学——不是从完整 OS 开始层层收紧(Docker),也不是从一无所有开始按需构建(Nix),而是通过语言运行时在编译期和运行期双重保障安全。核心特征:线性内存隔离(无法逃逸到宿主机地址空间)、能力基础安全(零环境权限+显式能力注入)、跨平台一致性。代表实现包括 agent-sandbox(Rust+Wasmtime,内置 80+ CLI 工具+Shell+JS 运行时)、BoxAgnts 工具系统(每个工具是独立 WASM 模块)、Wassette(Microsoft 开源,WASM+MCP 协议)。但 WASM 沙箱目前有三大局限:Python 执行需 Pyodide 先编译为 WASM(“解释器之上的解释器”性能损耗)、重度 C 绑定库(numpy/pandas/torch)难以编译进 WASM、WASI 标准仍在 Preview 1→2 剧烈变动期。这些局限使 WASM 适合”Agent 工具调用”场景(每次调用实例化一个 WASM 模块,执行完毕后销毁),但无法替代 Docker/微VM 的”全 OS 语义”需求(文件系统操作、多进程管理、GPU 计算)。

Docker Sandboxes 的 2026-08 进展:Docker Sandboxes 于 2026-08-11 已支持 macOS/Windows/Linux 三平台,sbx CLI 免费(含商用),且独立于 Docker Desktop。两个关键设计值得关注:(1) Docker-in-sandbox——每个 sandbox 自带独立 Docker daemon,规避传统 Docker-in-Docker 的权限逃逸风险;(2) 凭证代理注入——宿主侧代理持有真实凭证,sandbox 内 agent 只接触占位符,代理在出站请求时拼接真实 Authorization header,避免把 API Key 暴露给不可信的 agent 进程。

Checkpoint 加速

Nix Agent 生态验证

Nexus 的 Nix 方案并非孤例——Nix 在 AI Agent 生态中的应用正呈现四个层次:

  1. 运行时依赖构建(Nexus /nix volume)——构建 Python/uv/git 等系统依赖,注入任意 Docker 镜像。这是当前 Nexus 的核心用法。

  2. Agent 完整部署(Hermes Agent)——NousResearch 的 Hermes Agent 完全基于 Nix 部署:nix profile install github:NousResearch/hermes-agent 一行安装,提供 NixOS 服务模块声明式管理。这比 Nexus 的 volume 挂载更简洁——Nix 不仅是运行时注入手段,更是 Agent 的完整包管理器。

  3. MCP Server 沙箱化(mcp-box)——Docker 严格隔离 + 默认拒绝;Nix 在其中只用于确定性镜像构建,且完全可选(无 Nix 时从 GHCR 拉同一套 pinned OCI 镜像)。

  4. 微VM 原生部署(microvm.nix)——将 Nix 声明式构建与微VM 强隔离结合。通过 virtiofs 共享 /nix/store(避免每次重建镜像)、sops-nix 注入密钥、unbound DNS 日志+nftables 连接日志实现网络可观测性。代表案例:OpenClaw 微VM 部署(2026)和通用 Coding Agent VM 方案。

microvm.nix 对 Nexus 的启示:Nexus 的 /nix volume 方案挂载到 Docker 容器(容器级隔离),而 microvm.nix 挂载到微VM(hypervisor 级隔离)。两者的共同前提——Nix 的路径确定性和自包含——使得从容器级升级到微VM 级仅需替换运行时(Docker→microvm.nix),无需修改 /nix 内容。这是 Nexus 沙箱安全性的可选升级路径。

四个层次验证了 Nix 自包含特性的普适性:从”运行时注入”(仅构建依赖)扩展到”全生命周期管理”(部署 + 配置 + 更新 + 回滚)。Agentbox(基于 NixOS Flakes 构建 ARM Agent 容器,1.4GB headless runtime,支持云端 API 和本地 GPU 双模式)进一步证明 Nix 可承载异构硬件场景的 Agent 部署。

其中第 3 层需要按上面的限定来读:mcp-box 说明的不是 Nix 的普适性,而是Nix 是可插拔的——它在没有 Nix 时用 pinned OCI 镜像达到同样的确定性。这与 Nexus 的 /nix volume 是两条不同的确定性路线:前者靠镜像哈希,后者靠内容哈希路径,可以互为对照而非互相印证。

Nix 的自包含特性还带来一个额外收益:容器 checkpoint 可以跨镜像复用。

在容器 + 无外部挂载的语境下,传统方案确实做不到——不同镜像的库路径不同,checkpoint restore 会失败。但这个全称判断现在需要加限定:对带外部挂载的沙箱,该限制已被上游解除——CubeSandbox v0.7.1(2026-09-11,#1654 / #1656)起,Host Mount 与 Volume Plugin 的沙箱同样支持快照 / 恢复 / 回滚 / 克隆;v0.7.2(2026-09-24)另新增 JuiceFS 卷插件,提供完整 POSIX 语义的共享持久卷。而 Nix 的路径是确定的(基于内容哈希),所以:

  1. 启动 Runtime Server,等待初始化完成
  2. 做 container checkpoint
  3. 在任意挂载了相同 /nix volume 的容器中 restore

这可以节省 几秒到十几秒 的启动时间——Python 解释器启动、import、FastAPI 路由注册全部跳过。

Checkpoint 产业化进展

CRIU(Checkpoint/Restore In Userspace)版本线(核于 2026-10-23,回 releases.atom 逐条核实):v4.1(CRISC-V,2025-03-25)→ v4.1.1(2025-07-29)→ v4.2(CRIUTIBILITY,2025-11-13)→ v4.2.1(2026-07-21)→ v4.2.2(2026-10-19) → v4.3(CRIURBO,2026-10-19)。最近一次发布为 v4.3 / v4.2.2,均为 2026-10-19。AI/ML 工作负载的 checkpoint 已成为产业焦点:

⚠️ 一条写法上的订正。 本章此前写的是”2026-10-06 复测 releases.atom 仍为 v4.2.1,无新版本”——这句在 17 天后失效,而且是同一天冒出两个版本(一个 minor、一个 patch)。这是本章第三次遇到同一类腐烂(2026-09-01 的”时态教训”、2026-10-06 立的判据、本轮再应验)。“截至某日无新版本”与”截至某日 N 天”同属会腐烂的写法,一律改为”最近一次发布为 X(YYYY-MM-DD),核于 YYYY-MM-DD”。上面这句已按此改写。

v4.3(CRIURBO)的内容值得单独记一笔,因为它正对着 AI/ML 工作负载(官方 release notes 原文):

  • 内存压缩:支持 LZ4 内存页与块压缩,解压多线程;
  • 性能:用 Linux native AIO 恢复 VMA 页、并行恢复 memfd 与匿名共享内存、优化无硬件断点时的任务停止;
  • AArch64 Guarded Control Stack(GCS) 支持;
  • CUDA 与 AMDGPU 增强:CUDA Driver API backend、restore 时的 GPU device mapping、AMDGPU DRM buffer object 与 DMA-BUF 支持。

最后一条对本章的 checkpoint 论述是实质性的:GPU 状态(而不只是 CPU 与内存)进入可恢复范围。本章下面讨论的”从检查点恢复继续训练”,此前默认的是 CPU/内存侧的代价,v4.3 之后 GPU 侧也有了官方路径。

⚠️ 本轮只取 release notes 的 Major changes 段落,v4.2.2 的补丁内容未读,故不写 v4.2.2 改了什么。

  • KubeCon EU 2025 专题讨论 AI 工作负载的 checkpoint/restore,涵盖 GPU 迁移和大规模 Agent 批量执行场景
  • ISC 2025 高性能容器工作坊讨论 GPU checkpoint 在 AI 推理中的应用
  • PhoenixOS 论文提出并发 OS 级 GPU checkpoint,探索 GPU 状态的即时保存与恢复

⚠️ 不要把 CRIU 的版本线读成沙箱快照能力的进度条。 本章下面列举的产业落地证据(CubeSandbox 等)并不依赖 CRIU——microVM 侧的快照走的是 CoW 文件系统 + 内存回收(整机状态的复制与恢复),与 CRIU 的进程级 checkpoint 是两条技术路线。CRIU 停更不代表沙箱快照停滞,反之亦然。(此为本书分析推论 📌。)

这些进展说明 checkpoint 不仅节省启动时间,更在大规模 Agent 批量执行中发挥关键作用——fault tolerance(故障恢复)和 preemption recovery(抢占恢复)成为核心场景。当训练集群需要同时管理数千个沙箱实例时,checkpoint 能让被抢占的实例快速恢复执行,而非从零重启。

2026 年,checkpoint 已从会议议题变成产品能力。 腾讯云 CubeSandbox(v0.5.0,2026-07-03)给出了目前最完整的落地:CubeCoW 引擎基于 XFS reflink + FICLONE ioctl,快照是 O(1) 的元数据操作配合增量脏页持久化,因此保存一个 2GB rootfs 状态、克隆一个运行中沙箱、回滚到历史状态都在秒级;AutoPause/Resume 让空闲沙箱自动快照挂起(零资源消耗)并在下次请求时百毫秒级透明唤醒;跨机暂停与恢复(Preview) 配合 S3 快照后端,使已暂停的沙箱可在集群内任意兼容节点恢复。

值得留意的是,它的可行前提与本章 /nix volume 的论证同构:CubeSandbox 能跨机恢复,是因为沙箱状态被完整封装在可复制的镜像里;Nexus 的 checkpoint 能跨镜像复用,是因为 Nix 的 /nix/store 路径由内容哈希决定。两者是同一条原理——确定性路径 → 状态可迁移——在两个层面的实现。(此为本书基于官方材料的分析推论,非厂商原话。)

这也把 checkpoint 的价值从本章原写的”节省几秒到十几秒启动时间”扩展到三个新场景:① 分叉探索分支——从同一检查点克隆多条 rollout 路径(RL 训练直接需要);② 跨机迁移——节点维护或故障不再困住长跑任务;③ 空闲降本——长跑评测中的空闲沙箱可挂起到零资源消耗。第 ① 点对 Nexus 尤其相关:Nexus 的主要用途之一就是 RL 训练环境。

🔄 2026-10-23 补第四种,而且是编排层官方示例级的:RL 回合间停放。 agent-sandbox v1.0.8(2026-10-22,#1540):ClusterConfig(snapshots=True) 下,SandboxHandle 与 SandboxFleet 暴露 snapshot / suspend / resume / restore 与快照清理。官方原话:

An RL loop can park a sandbox between turns and bring back its exact memory and filesystem state, or roll an episode back to a checkpoint.

两条限定必须同时写:需要 GKE Pod Snapshot CRD 与 gVisor runtime class;未开启 snapshots 时行为不变。

与上面三种场景的区别在于粒度:①②③ 都是”整个沙箱的生命周期管理”,这一种是单个 RL 回合之间的状态停放——它把 checkpoint 从”省启动时间”变成了”训练循环的内层操作”。

⚠️ 它要求 gVisor,这一点要和 Ch10 那条对照着读。 Ch10 本轮写入的 OpenSandbox #2241 是:gVisor 默认 --overlay2=root:self 下 docker commit 会报 READY 却一个写入都没恢复。也就是说,本章把 gVisor 当作快照/恢复的前提条件来推荐,而 Ch10 记的是 gVisor 上快照会静默失败——两者不矛盾(一个是 K8s Pod Snapshot CRD 路径,一个是 docker commit 路径),但同一章里出现”gVisor 是前提”与”gVisor 有陷阱”时,必须把两条路径分开写,否则读者会把陷阱安到官方示例上,或反过来以为官方示例也不安全。

方向性判断(本书推论 📌,非厂商原话):把 CubeSandbox 的 v0.7.1 外部挂载快照与 v0.7.2 的 JuiceFS 卷插件放在一起看,“共享只读卷 + 快照”这一形态正从Nexus 的自研技巧下沉为沙箱层的通用能力——JuiceFS 插件本质上就是”一份共享文件系统挂给一堆沙箱”,与 /nix volume 同一形态,只是换到了 microVM 侧且带快照。因此 Nexus 真正难以被替代的不是”能 checkpoint”,而是”零网络依赖 + 任意 x86_64 Linux 镜像可直接挂载”这一条。(同一结论已同步写入 Ch10 文末,两处须一起读。)

沙箱方案选择决策树

不同场景对沙箱的需求差异巨大。基于上述五种方案的特性,以下决策树帮助选择:

需要运行不可信代码(LLM 生成的工具调用)?
  ├─ 是 → 需要完整 OS 环境(文件系统/多进程/GPU)?
  │        ├─ 是 → 需要最强隔离(零信任环境)?
  │        │        ├─ 是 → Docker Sandboxes / microvm.nix(microVM 隔离)<!-- edit: 2026-09-15 补限定:microVM 只解决内核逃逸,不解决宿主文件挂载语义 -->
  │        │        └─ 否 → Nexus /nix volume(自包含,零网络依赖)
  │        └─ 否 → WASM Sandbox(<5ms 冷启动,语言级隔离)<!-- edit: 2026-07-22 新增 WASM 分支 -->
  └─ 否 → 标准容器/动态安装方案...

关键考量:

  • 隔离 vs 速度:microVM 隔离性最强但启动最慢(秒级 vs 毫秒级)
  • 离线 vs 在线:Nix volume 和 bubblewrap 支持完全离线,其他方案需要网络
  • 维护 vs 灵活:单一 volume 维护成本最低,但灵活性不如动态安装
  • 内核逃逸 vs 挂载语义(2026-09-15 新增):选了 microVM 不等于拿到”最强隔离”。microVM 解决的是内核逃逸(独立 Guest 内核),不解决宿主文件的挂载语义。CVE-2026-18171(CVSS v4.0 5.7 / MEDIUM,2026-08-12 披露,已回 NVD 官方 API 核实)中,Docker Sandboxes 只把只读意图应用到客机内的容器 bind,底层 virtio-fs 的宿主侧授权却以”无访问模式”加入共享允许列表,攻击者经另一条可写导出路径即可改写运维本以只读方式挂载的宿主目录。结论:上了 microVM 之后,仍需审计”同一宿主路径在容器内的所有可达路径”。Ch10 的五层纵深防御框已同步补注。
  • 进程收殓(2026-10-06 新增):本章通篇没有讨论”客户端断开后沙箱内进程如何收殓”。上游运行时专门修过一类问题——agent-sandbox v1.0.3(#1379)把 sandboxd 的默认进程取消方式改为进程组终止(-PGID),修的正是客户端断开后孤儿子孙进程泄漏。Nexus 的 RemoteRuntime 同样存在”Host 断开 / 重连”路径(见 Ch12 RPCReplayGuard),该路径下沙箱内由 Executor 派生的子进程如何收殓,本章未体现。📌 需对照 nexus/runtime/server 的实际进程管理代码核实——这是内部事实,外部不可核,因此只登记为待核查项,不作缺陷断言。
  • 退出状态语义(2026-10-23 新增,本章最有价值的一条):本章通篇讨论的是”能不能跑起来”,没有讨论”结果有没有被读对”。同一个月内三个上游各自修了同一类问题:

    上游版本 / PR问题
    k8s agent-sandboxv1.0.7(10-15)#1897被信号 n 杀掉的进程报 128+n(如 SIGKILL → 137)而不是 -1;官方理由是把被杀 / OOM 被杀与守护侧失败分开
    OpenSandbox1.2.0-rc.2 #2270shim 先创建 exit 文件再写入,Inspect 忽略解析错误 → 被杀或写失败的 task 被报成 Succeeded
    OpenSandbox1.2.0-rc.2 #2303fork/exec: argument list too long 这类进程根本没起来的失败,与”跑了但非零退出”报同一个错误事件 → 读 evalue 判断状态的客户端会把启动失败报成成功

    📌 判据:评测框架必须能区分三种结局——「进程没起来」「进程被杀(含 OOM)」「进程跑完但非零退出」;把三者压缩成一个布尔 success,等于给失败开了一条通往”通过”的静默通道。 这条与上面的「进程收殓」是不同层:收殓管的是上一轮的进程有没有被清干净,语义管的是这一轮的结果有没有被读对。对 Nexus 的直接含义:RemoteRuntime 侧凡用退出码判定 task 成败的地方,都要能表达三种而不是两种结局。

  • 输出截断的形状(2026-10-23 新增,与 Ch09 交汇):Ch09 §Token 效率第 1 条写的”按 token 预算而非字符长度截断,并保留结构化摘要(如『前 50 行 + 错误信息』)“是本书的设想;上游已经给出了实作——agent-sandbox v1.0.8(#1978,核于 2026-10-23):合计 stdout + stderr 默认上限 30,000 Unicode 码点(max_output_chars 接受 128–300,000),超限部分以头尾摘录 + [... N characters omitted ...] 标记返回,并新增四个必填字段 stdout_total_chars / stderr_total_chars / stdout_truncated / stderr_truncated;新默认立即生效,无弃用期。

    三条可比之处值得写进设计:① 上游保留的是头 + 尾,不是本章设想的”前 N 行”——长输出的错误信息通常在尾部,这个选择有理由;② 上游把”截了多少”做成响应字段而非只改文本——截断必须是可机读的,否则调用方无法知道自己拿到的是不是完整输出;③ 无弃用期本身是信号:严格校验响应 schema 的 MCP 客户端会被直接打断。⚠️ Ch09 第 1 条与本条须一起读,否则一处仍写”设想”、另一处写”上游已有”。

  • 预热池会误删”正在等调度”的成员(2026-10-23 新增):agent-sandbox v1.0.7(#1817)——等待 SchedulingGated(例如 Kueue 准入)的池成员,此前会在就绪宽限期到期时被当作”卡住”删掉,现在与 Unschedulable 同样被保留。官方实测:Kueue 配额不足的测试里,4 副本池从”11 个沙箱被当卡住删掉”变成 0。 📌 含义:预热池的”卡住”判定必须区分”调度未就绪”与”真故障”,否则大规模评测会在配额紧张时静默损失沙箱——而这恰恰是跑批评测最常遇到的状态。

  • 有一类失效叫”从来就没工作过”(2026-10-23 新增):agent-sandbox v1.0.6(#1475)——v1beta1 Sandbox CRD 现在拒绝 spec.service: true 且名字超过 63 字符的 Sandbox。官方原话:“These Sandboxes never worked: the controller gives the headless Service the Sandbox’s name, so Service creation failed and the Sandbox never became Ready.” 且该 CEL 规则覆盖整个对象、不豁免既有对象。 它与 Ch08 的”工具被静默从 tools/list 丢掉”、Ch10 的”gVisor 快照静默丢写入”同族,但形态更极端:不是中途出错,而是配置组合从一开始就注定失败,却一直表现为”还在创建中”。对 Nexus 的推论:凡是”创建后长时间处于 creating”的状态,除了超时告警,还应能回答”这个配置组合是否根本不可能成功”。

沙箱编排标准化与安全动因

除表格中的七种方案外,2026 年还有两个值得关注的进展。

其一,Kubernetes 原生 agent-sandbox controller 已于 2026-08-28 发布 v1.0.0(最近一次发布为 v1.0.8,2026-10-22,核于 2026-10-23;版本线 v0.5.5 → v0.5.6 → v1.0.0(2026-08-28)→ v1.0.1(2026-09-03)→ v1.0.2(2026-09-11)→ v1.0.3(2026-09-17)→ v1.0.4(2026-09-24)→ v1.0.5(2026-10-01)→ v1.0.6(2026-10-08)→ v1.0.7(2026-10-15)→ v1.0.8(2026-10-22)),隶属 SIG Apps。

这改变了它的选型含义:它不再是”要不要赌一个新项目”,而是”要不要对齐一个已经定版的生态标准”。它引入原生 Sandbox CRD 作为核心抽象,并在 extensions 模块提供 SandboxTemplate(可复用模板)、SandboxClaim(从预热池申领)、SandboxWarmPool(预热池管理)。其定位是沙箱编排器而非隔离实现:低级容器隔离委托给 gVisor 或 Kata Containers 等”Sandbox Runtime”,通过 RuntimeClass 配置 Pod 来达成。这恰好印证了它与表格中 agent-sandbox(Podman rootfs)的分层差异——前者是编排层标准,后者是单机沙箱实现。

⚠️ 一条可复用的引用判据(2026-10-06):该项目的发布节奏是约每周一个 patch——2026-08-28 到 2026-10-01 的 34 天里发了 v1.0.0 到 v1.0.5 六个版本。任何”当前最新版本”的表述在本书出版周期内的存活期都以周计。因此本章此后一律写”最近一次发布为 YYYY-MM-DD,核于 YYYY-MM-DD”,不写”最新”。

🔄 这条判据已经第三次自我应验,可以把”以周计”具体化。 核于 2026-10-23:v1.0.6(2026-10-08)、v1.0.7(2026-10-15)、v1.0.8(2026-10-22)——v1.0.8 发布于本轮扫描的前一天。与 v1.0.3(09-17)/ v1.0.4(09-24)/ v1.0.5(10-01)连起来看,是连续 6 个版本、间隔稳定在 7 天,节奏 34 天未变。

因此判据可从”存活期以周计”精确为:按当前节奏,任何日期戳的存活期约 7 天。三次应验的时点分别是:2026-09-01(时态教训)、2026-10-06(立判据)、2026-10-23(再应验)。一条判据在 17 天内应验在自己身上两次,这本身就是它应当常设的理由。

GA 对 Nexus 的含义:此前”对接 K8s 运行时”是一个可选优化,现在它是有标准可依的对接——SandboxClaim + SandboxWarmPool 的组合正好对应 Ch10 §池化调度与批量交付 里 Nexus 缺的预热池化能力,且 API 已经冻结。

🔄 可对接的层次又扩了两格(v1.0.6 / v1.0.7,核于 2026-10-23):① 多集群 warm-pool fleet planner——v1.0.6 落地第一部分,v1.0.7 里”multi-cluster fleet example is now complete”;② v1.0.7 新增三个示例,其中 RL 集群的 namespace 级网络策略正是本章讨论 RL rollout 时完全没有的运维维度(另有 KubeRay RLlib 示例与”生命周期超过沙箱的 agent memory”示例)。

含义:上面那句”对接 K8s 运行时”的可选集,已经从单集群预热池扩到多集群舰队 + RL 集群的网络边界。后者对 Nexus 尤其值得记——本章通篇讨论 RL rollout 的生命周期(起、停、快照、恢复),但没有讨论 rollout 之间的网络隔离。

v1.0.3–v1.0.5 把可对接的层次从编排扩到了执行(均取自官方 release notes 正文):

  1. 执行层已就位——v1.0.5(2026-10-01)起 TypeScript SDK 具备完整运行时层:经 gRPC 的 sandbox.commands.run()、文件系统操作(read / write / exists / list / delete)、sandbox.health() 与 sandbox.metadata(),另有流式文件传输;v1.0.4(2026-09-24)起 Python 侧支持 async sandboxd。含义:上文”对接 K8s 运行时”此前讨论的只是编排层(claim / warmpool),现在连执行层(跑命令、传文件)都有官方 SDK——Nexus 若要对接,不必只借编排层。
  2. RL 成为一等集成对象——v1.0.4 增强了 RL SDK 的并发隔离,v1.0.5 又新增 OpenAI Agents 集成(#1388,含 workspace hydration 与 session resumption),并给出 Ray RLlib PPO 端到端示例。本章与 Ch10 都把 RL 训练列为 Nexus 主要用途之一;这条让”K8s 沙箱编排”从编排标准进一步变成 RL 训练环境的事实底座。
  3. 进程组清理——v1.0.3(2026-09-17,#1379)把 sandboxd 默认的进程取消方式改为进程组终止(-PGID),修的是”客户端断开后子孙进程泄漏”。这条对 Nexus 是一个本章未覆盖的对照项,见决策树的「进程收殓」一条。

另有两个官方细节值得记下。一是 Sandbox Router——一个把 SDK 与外部客户端流量路由到 sandbox pod 的 HTTP 反向代理;它的存在理由对 Nexus 有直接用处:在 Kata Containers / gVisor 这类 runtime 下无法直接 port-forward,必须走 Router。Nexus 的 RemoteRuntime 同样靠 HTTP 端点通信,若未来对接 Kata/gVisor,会遇到完全相同的问题,Router 是现成答案。二是安装可分两套 manifest:核心(sandbox-with-extensions.yaml)与扩展(extensions.yaml,API group 为 extensions.agents.x-k8s.io)。

⚠️ “现成答案”不等于”稳定答案”——Router 已连续三个版本改变使用方式。 上面推荐 Router 的那句本身仍成立,但它缺少护栏。三条破坏性变更按时间排列:

版本变更PR
v1.0.2(2026-09-11)authz.Authorizer 签名由两字符串改为 authz.AuthorizationTarget 结构体;deployment manifest 从 default 迁到 agent-sandbox-system#1497 / #1537
v1.0.6(2026-10-08)Scoped-token v2 改为授权 router 从 Pod 缓存解析出的 Sandbox UID,不再信任调用方的 X-Sandbox-UID 头;为已删除 Sandbox 铸造的 v2 token 不能再访问同名的新 Sandbox;path-routed 请求改用 v2 鉴权(此前直接 403);v2 下缓存未命中与 X-Sandbox-Pod-IP 覆盖被拒绝。out-of-tree 的 proxy.Lookup 实现必须改 Resolve、向 Invalidate 传 dialed cache.Entry、删除 InvalidateByName#1498
v1.0.8(2026-10-22)sandbox-router/deploy/ 现在是 Kustomization,kubectl apply -f 会失败,必须用 kubectl apply -k;默认安装不再含 rbac-tokenreview.yaml;router 的 API token 改为 projected token,1 小时过期(此前在开启 token 过期扩展的集群上最长可达一年)#1499

📌 护栏一句:采纳 Router 要把它的升级变更列为常设跟踪项,并按 1 小时 token 有效期设计长跑会话的重认证路径。 第三条对评测任务尤其致命——一个跑几小时的 rollout 若持有的是一年期 token 的心智模型,会在第 61 分钟断掉。另注意 v1.0.8 还留下一个手动清理项:kubectl apply 不会移除早期安装留下的 sandbox-router-auth-delegator ClusterRoleBinding,需手工删除。

⚠️ 本轮未核:1 小时 token 有效期是否可配置(官方只说现在是 projected token)。

🔄 与 Ch10 的联动(本轮两处须一起改,核于 2026-10-23):

  1. CubeSandbox v0.7.3(2026-10-12)新增沙箱内 MCP gateway(E2B 兼容的 mcp 参数)。
  2. OpenSandbox 1.1.1(2026-10-09)起可桥接 agents.x-k8s.io/v1beta1 的 spec.operatingMode 实现 pause/resume(#1975),而这两个端点此前都返回 “not supported”。

第 2 条直接改写上面那句分层判断——本章原写”前者(k8s agent-sandbox)是编排层标准,后者(OpenSandbox)是……”,并把二者当作分层/并列关系。现在两者出现了显式耦合:OpenSandbox 可以驱动 agent-sandbox 的 CRD。选型时的读法因此要改:不再是”选编排层还是选平台”,而是”是否接受平台层已经把编排层包进去了”。Ch10 同轮已作同样改写。

⚠️ 若按上文建议走 Router,须先处理 v1.0.2(2026-09-11)的两条破坏性变更(官方 release notes 的 Breaking Changes / Action Required 小节):

  1. sandbox-router 的公开 authz.Authorizer 接口签名由 (namespace, name) 两个字符串参数改为单个 authz.AuthorizationTarget 结构体(#1497)——自定义实现必须改 Authorize 方法。
  2. Go sandbox-router 的部署 manifest 从 default 命名空间迁至 agent-sandbox-system(#1537,理由是特权分离并对齐 SDK 默认与 NetworkPolicy)——裸 manifest 部署者须同步修改脚本。

两条都属于”升级后静默失效”类型:前者编译期报错还算友好,后者会让你 apply 到旧命名空间而 Router 实际不在那里。

其二,容器隔离的安全边界正被重新审视:CVE-2025-59528(Flowise CustomMCP 节点远程代码执行,CVSS v3.1 baseScore 10.0 / CRITICAL)暴露约 12,000-15,000 个互联网实例,60% 攻击流量转向 MCP endpoint 侦察。其成因具有普遍性——CustomMCP 节点允许用户为连接外部 MCP server 输入配置,却对该配置解析不当,导致攻击者可在宿主机上执行任意代码。共享内核容器在不可信 agent 代码场景下的隔离不足,是 microVM/WASM 等强隔离方案兴起的重要安全动因。