Agent容器里再套microVM:真正要守住哪几层边界
把代码放进容器,不等于把风险交给了另一台机器。10月23日OpenAI披露了训练环境的隔离加固。对开发者更有用的问题是:任务进程、来宾内核、宿主机与出站网络分别由谁约束?
先画资源图,再挑沙箱产品
普通容器共享宿主内核。microVM有独立来宾内核,由虚拟化层隔开宿主资源;容器还可以运行在microVM内部,继续限制文件、进程和能力。每增加一层,都多了一套配置与补丁责任,不能用“硬件隔离”四个字代替威胁模型。
任务也许需要下载依赖、写临时文件,却不需要访问宿主控制API、其他租户目录或云元数据。先列出这几类资源,才能解释为什么某条路要关闭。只看容器内部的防火墙不够,代理、解析器和宿主可达的内部服务也可能形成间接路径。
AppArmor、seccomp和网络策略解决不同问题。运行时告警能帮助发现异常,但不能承诺在未知内核漏洞发生前总能杀死进程。更不能把某个UID当作容器的唯一身份。
图只表达职责分层:蓝色通道需要独立的代理策略;红色出站路径被阻断。图中的嵌套关系不是已部署环境的截图。
离线检查一份任务资源声明
先让声明中的需求和允许集合做精确比较。这个检查器只审查结构化配置,不创建容器,也不提供执行隔离。
def validate(spec): required = {"filesystem", "network", "control_api"} if set(spec) != required: return False return ( spec["filesystem"] == "task-only" and spec["network"] in {"none", "proxy-only"} and spec["control_api"] is False ) base = { "filesystem": "task-only", "network": "proxy-only", "control_api": False, } assert validate(base) assert not validate(dict(base, network="host")) assert not validate(dict(base, control_api=True)) assert not validate(dict(base, undocumented=True)) print("4 resource declaration cases passed")未知字段直接拒绝,避免控制面误把未识别的选项当成默认安全值。配置声明正确仍不代表内核、VMM和网络设备真的执行了它,需要从宿主侧读取实际状态并做授权范围内的连通性测试。
退出后还要有回收证据
实例停止、凭证撤销、临时盘处理和网络撤销是四件事。API返回成功只能证明该调用的结果;还应核对实例是否残留、凭证是否仍可用。若清理失败,把实例隔离待查,不能继续分给下一个租户。
本例没有KVM、Firecracker、eBPF或Linux策略实测,也没有测启动耗时。选型时应使用自己的工作负载测兼容性和开销,保留宿主补丁、侧信道及控制面仍可能失效的边界。
参考资料
- OpenAI containment
- Firecracker design
- Linux seccomp manual