文章摘要
当Agent需要运行Python、Shell、数据处理脚本或第三方代码时,很多团队第一反应是“用Docker包起来”。容器启动快、生态成熟,但容器共享宿主机内核,隔离强度取决于Rootless、Namespace、Cgroup、Seccomp、AppArmor、Capability、挂载和网络策略是否正确配置。对于公开用户提交的任意代码,仅有一个普通容器通常不应被视为充分安全边界。
MicroVM使用虚拟机边界隔离工作负载,在安全性上更接近虚拟机,同时保持较快启动与较低资源开销,适合高风险、多租户和公开代码执行。远程执行服务则进一步把沙箱基础设施独立出来,通过队列、Worker池、Artifact接口和策略控制运行任务,适合规模化、异构运行时和多团队复用。
本文从隔离边界、启动延迟、吞吐、镜像生态、网络、文件、GPU、冷启动、调试、成本、运维和合规等维度,对进程隔离、容器、Rootless容器、gVisor类用户态内核、MicroVM、Kubernetes Job与独立远程执行平台进行系统比较,并给出企业内部脚本、公开Code Interpreter、浏览器自动化、数据科学和GPU任务的选型建议。
一、先明确威胁模型
选沙箱前必须回答:
代码由谁提供? 代码是否可信? 是否跨租户? 是否允许联网? 是否需要访问企业数据? 是否执行副作用? 是否需要GPU? 任务运行多久? 失败后能否重试?同一种运行时不适合所有场景。
二、五档风险
L1:可信平台代码
由团队开发、固定版本、经过审查。
可以使用:
普通服务进程 或 标准容器L2:租户自定义脚本
企业客户上传,来源受控但内容不完全可信。
建议:
加固容器 +独立Workspace +严格网络 +资源限制L3:公开用户任意代码
互联网用户可提交任意Python、Shell或包。
建议:
MicroVM 或 高强度远程沙箱L4:恶意代码研究
预期对抗、漏洞利用、逃逸尝试。
需要:
专用隔离集群 +强虚拟化 +无企业网络 +人工安全运营L5:不可接受风险
无法提供足够隔离时:
不执行三、方案一:同进程执行
示例:
exec(user_code)风险:
- 读取进程内存;
- 修改全局状态;
- 读取Secret;
- 终止进程;
- 无限循环;
- 导入危险模块;
- 文件与网络完全共享;
- 逃逸限制几乎不可控。
生产中不应对不可信代码使用。
四、方案二:子进程
主服务 →子进程可限制:
- 超时;
- 环境变量;
- 当前目录;
- UID;
- 资源。
但仍共享宿主机内核与文件系统视图,隔离不足。
适合:
可信工具 +故障隔离不适合作为公开代码安全边界。
五、方案三:普通容器
容器提供:
- Mount Namespace;
- PID Namespace;
- Network Namespace;
- User Namespace可选;
- Cgroup;
- 镜像;
- 生命周期。
优势:
- 启动快;
- 工具成熟;
- 镜像丰富;
- 调试容易;
- 资源效率高。
六、容器的核心局限
容器共享宿主机内核。
若出现:
- 内核漏洞;
- Runtime漏洞;
- 错误挂载;
- Docker Socket泄露;
--privileged;hostNetwork;- 高风险Capability;
- Seccomp关闭;
隔离可能被突破。
七、Rootless容器
Rootless模式让Docker守护进程和容器以非Root用户运行,降低守护进程和运行时漏洞带来的宿主机权限风险。
收益:
- 不需要Root守护进程;
- 容器Root映射到非特权宿主用户;
- 降低攻击面。
但Rootless不是完整沙箱:
- 仍共享内核;
- 网络性能和功能可能不同;
- 错误挂载仍会泄露数据;
- 应用漏洞仍存在;
- 外部系统权限仍需治理。
八、Seccomp
Seccomp限制可调用的系统调用。
Docker默认Seccomp Profile会阻止一部分高风险系统调用,但生产代码执行应评估自定义Profile。
配置目标:
允许业务必需调用 拒绝不需要的高风险调用不要为了兼容直接:
seccomp=unconfined九、AppArmor与SELinux
它们提供强制访问控制。
可限制:
- 文件路径;
- Capability;
- 网络;
- 挂载;
- 执行权限。
沙箱应把:
Namespace +Cgroup +Seccomp +LSM组合使用,而不是只依赖其中一层。
十、Capability
默认:
drop ALL按需增加。
危险Capability:
SYS_ADMINSYS_PTRACENET_ADMINSYS_MODULEDAC_READ_SEARCH
绝大多数代码解释器不需要它们。
十一、用户命名空间
容器内UID 0映射到宿主非特权UID。
可降低:
容器Root →宿主Root风险。
但必须检查挂载目录的UID/GID和宿主权限,避免映射错误。
十二、只读根文件系统
readOnlyRootFilesystem:true配合:
/tmp /work /output独立临时卷。
防止修改镜像层和跨任务污染。
十三、方案四:用户态内核沙箱
这类方案在容器与宿主内核之间增加用户态系统调用拦截或兼容层。
优势:
- 减少直接暴露给宿主内核的系统调用;
- 比完整VM轻;
- 可继续使用容器镜像。
代价:
- 系统调用兼容;
- 性能;
- 调试;
- 某些工作负载不支持;
- 运维复杂度。
适合:
中高风险代码 +容器生态 +可接受兼容成本十四、方案五:MicroVM
MicroVM使用硬件虚拟化提供独立Guest内核。
优势:
- 更强内核隔离;
- 每任务独立Guest;
- 适合多租户不可信代码;
- 可控制设备模型;
- 比传统通用VM更轻。
代价:
- 启动和资源高于容器;
- 镜像构建更复杂;
- Guest内核维护;
- 网络与存储编排;
- 调试更难;
- GPU支持更复杂。
十五、Firecracker的定位
Firecracker面向安全、多租户和轻量虚拟化场景,通过MicroVM提供比传统容器更强的工作负载隔离,同时追求较快启动和较低开销。
生产使用仍需:
- Jailer;
- cgroup;
- seccomp;
- 网络;
- 镜像;
- Guest安全;
- 宿主补丁;
- 生命周期管理。
MicroVM不是无需配置的安全按钮。
十六、方案六:传统虚拟机
优势:
- 强隔离;
- 兼容完整OS;
- 可运行复杂软件;
- 安全团队熟悉。
代价:
- 启动慢;
- 资源重;
- 镜像大;
- 密度低;
- 调度复杂。
适合:
- 长任务;
- 特殊内核;
- 高合规;
- 低并发;
- 复杂桌面或企业软件。
十七、方案七:Kubernetes Job
Kubernetes Job提供:
- 一次性Pod;
- 重试;
- 调度;
- 资源配额;
- 节点池;
- 状态;
- 清理。
它是调度方式,不是自动安全边界。
必须配置:
- Restricted Pod Security;
- SecurityContext;
- RuntimeClass;
- NetworkPolicy;
- ResourceQuota;
- 独立节点池;
- 非Root;
- Seccomp;
- 只读Root;
- 禁止HostPath。
十八、RuntimeClass
可以将不同风险任务路由到:
runc 用户态内核 MicroVM RuntimeSupervisor依据风险选择Runtime Profile。
十九、方案八:远程执行服务
架构:
Agent应用 →Execution Gateway →任务队列 →Sandbox Worker池 →Artifact Store优势:
- 安全边界与业务服务分离;
- 多语言运行时;
- 统一配额;
- 独立扩缩容;
- 统一审计;
- 多团队复用;
- 可使用不同沙箱技术。
二十、远程执行服务的代价
- 网络延迟;
- 基础设施复杂;
- Artifact传输;
- 队列;
- 版本;
- 多租户治理;
- 运行时镜像供应链;
- 成本归因。
但生产规模扩大后,通常比每个业务团队自行启动容器更可控。
二十一、执行网关职责
身份认证 策略决策 风险分级 运行时选择 预算 Artifact签发 网络策略 任务排队 状态查询 取消 审计Worker只负责执行,不直接相信Agent传来的权限参数。
二十二、运行时Profile
publicrecordSandboxProfile(StringprofileId,IsolationTechnologyisolation,StringimageDigest,booleannetworkEnabled,Set<String>allowedDomains,ResourceLimitslimits,DurationmaximumRuntime,booleangpuEnabled,RiskLevelmaximumRisk){}二十三、选型维度一:隔离强度
从低到高大致:
同进程 < 子进程 < 加固容器 < 用户态内核 < MicroVM/VM具体安全性仍取决于配置和运维。
二十四、选型维度二:启动延迟
通常:
进程最快 容器较快 MicroVM中等 完整VM较慢可以通过:
- Warm Pool;
- 镜像预拉取;
- Snapshot;
- 预创建网络;
- 分层缓存;
降低冷启动。
二十五、Warm Pool风险
预热运行时可能残留:
- 文件;
- 进程;
- 网络;
- Secret;
- 内存;
- 内核状态。
高风险任务不应跨租户复用同一个运行实例。
可以预热:
干净模板而不是复用执行过用户代码的实例。
二十六、选型维度三:吞吐与密度
容器密度高,适合大量短任务。
MicroVM密度低一些,但隔离更强。
需要基于:
- P50/P95启动;
- 内存;
- CPU;
- 任务长度;
- 峰值;
- 成本;
压测,而不是凭概念选型。
二十七、选型维度四:镜像生态
容器镜像可直接使用:
- Python;
- Node;
- Java;
- 数据科学库。
MicroVM需要:
- Rootfs;
- Guest Kernel;
- Agent;
- 启动配置。
远程执行平台可在内部把复杂性封装掉。
二十八、选型维度五:网络
代码执行默认:
无网络必须联网时使用:
- Egress Proxy;
- Allowlist;
- DNS策略;
- 私网阻断;
- Metadata阻断;
- 带宽限制;
- 请求审计。
MicroVM和容器都需要网络治理。
二十九、选型维度六:文件
所有方案都要处理:
- 输入只读;
- Workspace;
- 输出;
- 配额;
- 对象存储;
- 清理;
- 下载授权。
更强运行时隔离不能替代Artifact权限。
三十、选型维度七:GPU
GPU任务带来:
- 驱动;
- 设备直通;
- 显存隔离;
- 多租户;
- 高成本;
- 较长启动。
公开不可信GPU代码风险更高。
建议:
独立GPU节点池 +专用Runtime +严格配额 +无企业网络三十一、选型维度八:可观察性
需要采集:
- 状态;
- stdout/stderr;
- 资源;
- 文件;
- 网络;
- 系统调用告警;
- OOM;
- 超时;
- 退出码;
- Artifact;
- 清理。
但日志不能包含Secret和其他租户内容。
三十二、选型维度九:调试
容器调试方便,MicroVM故障定位更复杂。
生产安全不能因为调试困难就永久开放:
- SSH;
- Privileged;
- HostPath;
- Docker Socket;
- 全网。
使用受控调试Profile和审批。
三十三、选型维度十:合规
关注:
- 数据区域;
- 租户隔离;
- 日志;
- 密钥;
- 保留;
- 删除;
- 审计;
- 镜像来源;
- 漏洞响应;
- 供应链。
三十四、场景一:企业内部数据分析
代码由内部员工生成,数据敏感。
推荐:
加固容器 +独立Workspace +无公网 +企业数据代理 +严格权限高敏数据可升级MicroVM。
三十五、场景二:公开Code Interpreter
用户可提交任意代码和附件。
推荐:
远程执行平台 +MicroVM或高强度沙箱 +默认无网络 +短生命周期不建议业务Web服务直接操作Docker Socket创建容器。
三十六、场景三:浏览器Agent
需要Chromium和较大共享内存。
可使用:
加固容器或MicroVM +独立Browser Context +网络策略 +下载隔离浏览器自身沙箱不能替代外层运行时隔离。
三十七、场景四:批量文档处理
任务来源可信、文件不完全可信。
推荐:
Kubernetes Job +加固容器 +文件扫描 +无公网三十八、场景五:恶意样本分析
推荐:
专用MicroVM/VM集群 +隔离网络 +一次性环境 +安全运营不与普通业务节点混部。
三十九、风险路由
publicSandboxProfileselect(ExecutionRequestrequest){if(request.publicUntrustedCode()||request.risk()==RiskLevel.CRITICAL){returnprofiles.require("microvm-isolated");}if(request.requiresBrowser()){returnprofiles.require("browser-hardened");}returnprofiles.require("container-restricted");}模型不能自己选择更宽松Profile。
四十、策略决策输入
- 用户;
- 租户;
- 代码来源;
- 语言;
- 文件;
- 网络;
- Tool;
- 数据敏感度;
- 副作用;
- 运行时;
- 风险;
- 历史滥用。
四十一、执行请求
publicrecordExecutionRequest(StringrequestId,StringtenantId,StringsubjectId,StringrunId,Stringlanguage,StringcodeArtifactId,List<ArtifactRef>inputs,booleannetworkRequested,Set<String>requestedDomains,ResourceLimitsrequestedLimits,RiskLevelrisk,Stringpurpose){}四十二、策略结果
publicrecordExecutionPolicyDecision(booleanallowed,StringsandboxProfileId,ResourceLimitslimits,NetworkPolicynetworkPolicy,Set<String>deniedCapabilities,booleanhumanApprovalRequired,List<String>reasons){}四十三、资源限制
publicrecordResourceLimits(doublecpuCores,longmemoryBytes,longdiskBytes,intmaximumPids,intmaximumFiles,DurationwallTime,longnetworkBytes){}四十四、超时与取消
超时:
发送优雅终止 →短暂等待 →强制销毁 →收集有限日志 →清理取消不能只停止API轮询,必须实际终止运行时和后代进程。
四十五、镜像治理
- 固定Digest;
- 签名;
- SBOM;
- 漏洞扫描;
- 最小依赖;
- 定期重建;
- 禁止Latest;
- 镜像仓库访问控制;
- 供应链审计。
四十六、运行时更新
容器Runtime、Guest Kernel、Host Kernel和浏览器都需要补丁。
安全平台要有:
版本清单 漏洞影响 灰度 回滚 强制淘汰四十七、节点池隔离
高风险沙箱节点:
- 不运行核心业务;
- 不挂载企业Secret;
- 不访问生产数据库;
- 独立网络;
- 独立IAM;
- 自动替换;
- 更严格监控。
四十八、Docker Socket
向业务容器挂载:
/var/run/docker.sock相当于授予强大的宿主控制能力。
更安全:
业务服务 →远程Execution Gateway网关本身也需严格隔离。
四十九、Kubernetes HostPath
沙箱Pod禁止HostPath,尤其:
//var/run/etc/proc- 容器运行时目录;
- Kubelet目录。
五十、Pod Security
使用Restricted基线:
- 非Root;
- 禁止提权;
- Seccomp RuntimeDefault;
- Capability Drop;
- 合法Volume;
- 无Host Namespace。
五十一、逃逸检测
监控:
- 禁止系统调用;
- 异常进程;
- 尝试访问敏感路径;
- 网络扫描;
- Metadata访问;
- Fork Bomb;
- 加密货币挖矿特征;
- 大量下载;
- Runtime异常。
检测不是隔离的替代品。
五十二、成本模型
运行时启动成本 +空闲Warm Pool +CPU/内存 +网络 +存储 +镜像 +安全运营容器便宜但事故成本可能更高。
选型要纳入风险成本。
五十三、指标
sandbox_execution_total{ profile, status } sandbox_startup_seconds{ profile } sandbox_runtime_seconds{ profile } sandbox_resource_usage{ profile, type } sandbox_policy_denied_total{ reason } sandbox_escape_signal_total{ type } sandbox_warm_pool_hit_total{ profile } sandbox_cleanup_total{ profile, result } sandbox_cost_total{ profile }五十四、压测矩阵
- 短Python;
- 大依赖;
- 浏览器;
- 大文件;
- 多子进程;
- 内存峰值;
- 网络;
- 高并发;
- 冷启动;
- Warm Pool;
- 失败清理;
- 节点故障。
五十五、安全测试
- 路径逃逸;
- 容器逃逸模拟;
- Capability;
/proc;- Metadata;
- DNS Rebinding;
- Fork Bomb;
- 磁盘耗尽;
- Socket;
- 符号链接;
- 恶意包;
- 侧信道评估。
五十六、选择决策树
代码是否完全可信? ├─是:标准容器或进程隔离 └─否:继续 是否公开用户任意代码? ├─是:MicroVM/高强度远程沙箱 └─否:继续 是否跨租户且数据敏感? ├─是:加固容器以上,按风险升级MicroVM └─否:加固容器 是否大量长Timer与异构运行时? →远程执行平台 是否需要GPU? →专用节点池与专用Profile 是否预期主动恶意? →专用VM/MicroVM安全集群五十七、最终选型清单
□ 先定义威胁模型而非先选Docker □ 不可信代码不在主服务进程执行 □ 普通容器不被错误宣称为绝对安全边界 □ Rootless、Seccomp、LSM、Capability和只读Root组合使用 □ 高风险公开代码升级MicroVM或专用远程沙箱 □ 业务服务不直接持有Docker Socket □ 沙箱使用独立节点池和IAM □ 默认无网络 □ 文件与Artifact权限独立治理 □ Warm Pool不复用执行过高风险代码的实例 □ 运行时Profile由策略服务选择 □ 镜像固定Digest并有SBOM □ 取消能终止全部后代进程 □ 清理失败不会复用环境 □ 对Runtime、内核和浏览器持续补丁 □ 压测同时比较隔离、延迟、密度和成本总结
容器、MicroVM和远程执行服务并不是“快、稳、安全”三个简单标签,而是不同层次的架构选择:
容器 提供高密度与成熟生态 MicroVM 提供更强内核边界 远程执行服务 提供统一策略、调度和运营对于企业生产Agent,常见最佳组合是:
Execution Gateway +按风险选择容器或MicroVM +独立Artifact与网络控制 +统一预算、审计和清理真正的安全来自多层防御与清晰威胁模型,而不是运行命令中出现了docker run或microvm这个名称。