本节摘要:2.1 节的四道边界挡得住文件系统、网络与资源攻击,挡不住第四类——内核漏洞:容器与宿主共享同一个内核,runc 历史上出现过真实逃逸漏洞(CVE-2019-5736、CVE-2024-21626,均为官方 CVE 记录),而任意执行型 Agent 恰恰是最有动机利用它们的那类负载。本节给出两条补丁路线:gVisor(runsc)在用户态实现一个 Sentry 内核拦截并重新实现系统调用,Docker 换个 runtime 参数即可接入,代价是系统调用密集型负载的性能损耗;Firecracker 干脆给每个 microVM 一个独立内核,隔离最彻底、启动不超过 125 毫秒(官方数据),但要自管内核镜像、rootfs 与网络。最后用一张三路线选择表收束,并以 E2B 展示「Firecracker + 快照池」的产品化形态。
容器的所有进程最终都运行在宿主内核上。这意味着:内核暴露给容器内代码的每一个攻击面,都是你的攻击面。这不是理论担忧——
(文字流程图)容器逃逸的共性 容器内恶意代码 ──▶ 利用 runc / 内核漏洞 ──▶ 在宿主以高权限执行 ──▶ 沙箱整体失守 ▲ 这一步发生在「共享内核 / 共享运行时」地带, 2.1 节的四道边界管不到这里
⚠️ 校准风险感:这类漏洞的利用有条件、有窗口期,普通后端容器长期未升级也未必被打穿。但 Agent 沙箱的负载是「刻意尝试越狱的自动化代码」,威胁模型不同——第 1 章选了微 VM 级别的读者,这一节就是你的落地路径。
原理:runsc 提供一个用户态内核 Sentry。容器内应用发出的系统调用被 Sentry 截获、在用户态重新实现,再以受控的最小接口与宿主打交道。内核漏洞攻击打到的是 Sentry 的重新实现,宿主内核不直接暴露。数字:典型容器启动延迟约 50~100 毫秒(社区资料,2026);GKE Sandbox 以 runsc 跑不可信负载(官方资料)。
接入三步(写法示意,以 gVisor 官方快速上手为准):
# install_runsc.sh —— runsc 接入 Docker(写法示意,具体版本与路径以官方文档为准) # 1) 从官方 GitHub Releases 下载对应架构的 runsc 压缩包并解压到 /usr/local/bin # 2) 注册 runtime:执行 runsc install 会改写容器运行时配置;等价的手工写法如下 # 在 /etc/docker/daemon.json 中加入: # { "runtimes": { "runsc": { "path": "/usr/local/bin/runsc" } } } sudo systemctl restart docker # 3) 验证:用 runsc 跑一个断网容器 docker run --rm --runtime=runsc --network none agent-sandbox:py3.12 python -c "print('inside runsc')"
开销与兼容性:系统调用密集型任务(高频文件操作、网络系统调用)有感变慢,计算密集型接近原生(社区实测,量级与负载强相关);多数常用系统调用已支持,冷门 ioctl、ptrace 类仍有缺口(官方兼容性文档)——所以接入后要重跑 2.1 节的四组验证实验,确认你的负载不掉坑。
💡 成本收益一句话:runsc 的接入成本约等于「改一行配置」,换来的是把「内核漏洞」这一类攻击面从暴露变为收敛——单租户、内部使用的任意执行型 Agent,这是性价比最高的升级。
原理:AWS 开源的极简 microVM:最小设备模型 + KVM 虚拟化,每个 VM 拥有独立内核,隔离边界是硬件虚拟化,不再依赖「共享内核上的约定」。官方规格:启动不超过 125 毫秒、每 VM 内存开销小于 5 MiB、每秒可创建约 150 个 microVM(官方数据)。AWS Lambda 与 Fargate 基于它运行(公开资料)。
运维代价:不接入 Docker,需要自备——
这些是一次性平台工程投入,适合多租户平台,不适合单团队快速起步。
💡 平台工程判断:Firecracker 的投入是一次性的(镜像、网络、快照池),产出是每租户独立内核——团队规模与租户数量决定这笔投入值不值。
产品化参照 E2B(公开设计资料):开源 Agent 沙箱基础设施,每个沙箱是一个 Firecracker microVM,用快照池把冷启动压到约 150 毫秒(官方宣称),支持暂停恢复与长会话,对外提供 SDK 与 MCP 接入。它验证了两件事:Firecracker 路线在 Agent 场景可行;「每会话一个 VM」正在成为多租户 Agent 执行的产业默认。
(文字流程图)从容器到 microVM 的职责变化 你负责:应用镜像 ──────────────────▶ 你负责:应用镜像 + 内核镜像 + rootfs + 网络 + 快照 运行时负责:共享内核(漏洞共享) 运行时负责:每 VM 独立内核(漏洞不共享)
| 维度 | 加固容器(2.1) | + runsc(本节) | Firecracker microVM(本节) |
|---|---|---|---|
| 内核漏洞攻击面 | 暴露于宿主内核 | 收敛(Sentry 拦截) | 基本消除(独立内核) |
| 接入成本 | 低(Docker 即用) | 极低(换 runtime 参数) | 高(内核 / rootfs / 网络 / 快照自管) |
| 启动速度 | 数百毫秒(示意) | 约 50~100 毫秒(社区) | 不超过 125 毫秒(官方) |
| 运行开销 | 接近原生 | 系统调用密集型有感 | 原生级 + 虚拟化少量开销 |
| 多租户 | 不建议 | 可用(谨慎) | 推荐(产业默认) |
| 适用 | 单租户读写型 Agent | 单租户任意执行型 | 多租户 / 面向外部 / 平台化 |
决策快查:沿用第 1.2 节的三行隔离决定——选了「加固容器」的读本节了解升级路径即可;选了 runsc 的照第二节接入并重跑验证;选 Firecracker 的先把 2.3 节网关搭好(VM 池由网关调度),再投入镜像与网络工程。原理层的完整论述见《Harness 工程:从零打造智能体运行环境》第 6 章《沙箱与执行隔离》。
(文字流程图)升级路径可进可退:加固容器 ──▶ 加 runsc ──▶ 多租户需求出现再上 Firecracker;反向降级则必须重做一遍威胁模型,不能简单摘参数。
沙箱本体与隔离层都已就位,还剩最后一个架构问题:执行权放在谁手里?如果 Agent 直接调用 docker,白名单、审计、结果截断就都无从谈起。下一节把执行权收进网关,搭出 Agent → 网关 → 沙箱的三段式底座。