
NVIDIA 发起的 OpenShell 成为 CNCF 沙箱项目,为 AI 代理提供安全运行时
来源标题:OpenShell on Kubernetes: A guide for platform engineers
由 NVIDIA 发起、现为 CNCF Sandbox 项目的 OpenShell 是一个用于安全运行 AI 代理的运行时,它把每个代理放进沙箱,由沙箱外的可信 supervisor 决定代理能访问什么。用户通过 YAML 声明文件系统、进程、网络和凭证四类控制,例如网络默认拒绝出站流量、代理只能看到 API key 的占位符。OpenShell 不自带调度器,面向 Kubernetes 管理员。
以下正文由 AI 翻译自 CNCF Blog(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
OpenShell 是什么
AI agent 不只调用 API。它们会运行 shell、安装软件包、读取文件、建立网络连接,而且常常是基于一分钟前刚从互联网上抓来的文本行事。因此,每个 agent 都是持有真实凭据的不可信代码。
OpenShell 由 NVIDIA 发起,现为 CNCF Sandbox 项目,是一个用于安全运行这类 agent 的运行时。OpenShell 把每个 agent 放进沙箱中运行。沙箱之外有一个可信的 supervisor,决定 agent 可以访问什么。你在 YAML 中声明四类控制:
- 文件系统:Landlock 限制 agent 能读写哪些路径。在演示中,/usr、/etc 等几个路径为只读,只有 /sandbox、/tmp 和 /dev/null 可写。
- 进程:agent 启动前,沙箱运行时将其降权为非 root 用户,剥夺所有 capabilities,并应用 seccomp。
- 网络:出站流量默认拒绝。规则可以按二进制、主机、端口和 HTTP 方法放行流量。
- 凭据:agent 只能看到每个 API key 的占位符。由 supervisor 替换为真实 key,且仅限提供商允许的端点。
对 Kubernetes 管理员来说,关键一点是 OpenShell 不自带调度器。它的 Kubernetes 后端使用 Agent Sandbox,即 SIG Apps 提供的 agents.x-k8s.io Sandbox 资源。agent 以 Pod、Service、PVC、Secret 和 NetworkPolicy 的形式出现,这些都是你已经熟悉的运维对象。OpenShell 补上了 Kubernetes 看不到的部分:是哪个 agent 在调用、是哪个二进制发出的请求、某个 POST 是否允许离开集群。
NetworkPolicy 可以规定“这个 Pod 可以访问 api.github.com 的 443 端口”,但无法规定“curl 可以读取 issue,但不能创建 issue”。OpenShell 可以做到,而且能在运行中的沙箱上修改规则而无需重启。
沙箱如何创建和运行
在 Kubernetes 上,OpenShell gateway 拥有所有沙箱,Agent Sandbox 把每个沙箱变成 Pod。nirmata/demo-openshell 仓库在一个双节点 kind 集群上跑通了整个流程,环境为 Kubernetes 1.35、Cilium 1.20、Agent Sandbox v1.0.5、OpenShell 0.1.3 和 Kyverno 1.18.2。其 openshell-sandbox-lifecycle.md 文件详细描述了每一步。
注 1:目前 OpenShell 沙箱只能通过调用 Gateway API 创建,不能通过 Kubernetes API 创建。有一个 open issue(openshell/#1719)提议增加 Kubernetes OpenShellSandbox CRD 和 operator。
注 2:每个 agent 一个 Supervisor Pod 能提供强隔离,但在大规模环境中可能扩展性不佳。路线图包含灵活的部署选项(见 RFC 0018)。
OpenShell on Kubernetes · 控制路径与数据路径
gateway 创建 Kubernetes 对象,Agent Sandbox 创建 agent Pod。agent Pod 自身没有出站网络访问权限。supervisor 打开通往它的唯一连接,agent 发出的每个请求都经这条连接返回以做策略检查。Kyverno 在准入阶段检查 Kubernetes 对象。
- 准备集群。安装一个同时执行 ingress 和 egress NetworkPolicy 的 CNI。演示用 Cilium 替换了 kindnet。然后安装 Agent Sandbox controller 和 CRD,再安装 OpenShell gateway Helm chart。
- 创建沙箱。openshell sandbox create –workspace demo –name policy-demo –from nicolaka/netshoot@sha256:… –no-auto-providers 通过 mTLS 把请求发给 gateway。客户端从不直接访问 Kubernetes API。workspace(这里是 demo)用于对沙箱、策略和日志分组。
- gateway 检查并记录请求。它认证调用方,解析镜像、策略、提供商和资源,并拒绝不安全的设置。然后在 Provisioning 阶段保存一条沙箱记录。这条记录才是事实来源,而不是 Pod。
- 网络策略先行。Kubernetes driver 在该命名空间中创建两个 NetworkPolicy,如果已存在则进行检查。一个针对工作负载 Pod:完全禁止出站流量,入站仅允许 supervisor 在 TCP 5500 上访问。另一个针对 supervisor Pod。之后 driver 才以挂起状态创建 Sandbox 资源。
- Agent Sandbox 创建工作负载。controller 创建工作负载 Pod 以及 /sandbox 的 PVC。一个 scheduling gate 会暂时阻止 Pod 调度。
- OpenShell 检查已准入的 Pod。准入之后,driver 回读 Pod,检查非 root UID 和 GID、无额外 capabilities、RuntimeDefault seccomp、无 host namespace、无 ServiceAccount token,以及预期的标签和卷。如果某个准入 webhook 改动了其中任何一项,创建就会失败。
- 创建 supervisor。driver 创建一个 supervisor Pod、一个指向工作负载 Pod 5500 端口的 Service、此沙箱的 TLS 和 bootstrap Secret,以及一个给 supervisor 的短期 token。工作负载永远不会拿到 gateway 凭据。随后移除 scheduling gate。
- supervisor 建立连接。supervisor 使用与命名空间、Sandbox UID、自身 Pod UID 和运行时 generation 绑定的身份向 gateway 认证。它接收策略,并通过 Service 连接工作负载。在工作负载内部,沙箱运行时应用文件系统、进程、socket 和 DNS 控制。在这些控制确认生效之前,agent 的命令不会启动。
- 运行与更新。agent 的每个出站请求都先到 supervisor,由它检查目标、端口、调用二进制和 HTTP 请求,然后才打开上游连接。Exec、SSH、日志和文件同步也都经过 supervisor。openshell policy update 加载新版本策略并等待沙箱确认,无需重启。在演示中,curl 一开始被阻止。更新之后,它可以从 api.github.com 读取,但对 /issues 的 POST 会返回 policy_denied。openshell logs policy-demo –source sandbox 会显示每个被允许和被拒绝的请求。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。