Skip to content

AgentCube × Kubernetes Agent Sandbox:构建云原生 AI Agent Runtime

Published on
AgentCube × Kubernetes Agent Sandbox:构建云原生 AI Agent Runtime

随着 AI Agent 从简单的 LLM 调用逐渐走向代码执行、工具调用、浏览器操作和多步骤任务编排,Agent 的运行环境也开始成为 AI 基础设施中的独立问题。

一个典型 Agent Session 可能持续数分钟甚至数小时。在这个过程中,Agent 会反复执行代码、读写文件、调用工具,并依赖此前产生的运行状态。与此同时,执行内容中往往包含 LLM 动态生成的代码,对资源隔离、安全边界和生命周期管理提出了更高要求。

传统 Kubernetes 工作负载抽象主要围绕几类典型场景设计:

  • Deployment 面向长期运行、无状态、可水平复制的服务;
  • StatefulSet 面向具有稳定序号和持久状态的副本集合;
  • Job 面向执行完成后退出的批处理任务。

Agent Runtime 呈现出另一组特征:long-lived logical session、short/intermittent computation、private execution state、strong isolation 和 high creation frequency。

一个 Agent Session 通常只需要一个运行实例,却要求稳定身份、会话状态、低启动延迟、独立资源边界,以及空闲后的及时回收。

围绕这一问题,Kubernetes SIG Apps 社区正在推进 Agent Sandbox1 项目,为 Kubernetes 提供标准化 Sandbox workload abstraction;Volcano 社区的 AgentCube2 则进一步面向 AI Agent 场景,在 Sandbox 之上构建 Session、Runtime、Router 和生命周期管理能力。

两者组合之后形成了一套清晰的分层:

AgentCube 与 Agent Sandbox 的分层架构

本文将沿着这条链路分析 AgentCube 如何使用 Kubernetes Agent Sandbox,将 Kubernetes 的 Sandbox 原语进一步抽象成面向 AI Agent 的 Runtime。

Agent Sandbox:给 Kubernetes 增加一个 Sandbox 原语

kubernetes-sigs/agent-sandbox 当前由 Kubernetes SIG Apps 推进。项目将自身定位为针对 isolated、stateful、singleton workload 的 Kubernetes-native orchestration layer,Agent Runtime 和强化学习环境都是其重点场景。

它的核心资源只有一个:

apiVersion: agents.x-k8s.io/v1beta1
kind: Sandbox

Sandbox 描述一个具有稳定身份的单实例运行环境。

在当前 API 中,一个 Sandbox 可以包含 PodTemplate、VolumeClaimTemplates、生命周期配置、Running / Suspended operating mode、Ready / Suspended / Finished 等状态、可选 Service,以及稳定的网络与存储状态。

当前 v1beta1 API 已经明确区分 desired operating state 与 observed readiness。例如 operatingMode=Running 表示控制器应该维持 Pod,而 Sandbox 只有在 Pod 进入 Running、Ready 且获得 IP 后才会报告 Ready=True;operatingMode=Suspended 会终止 backing Pod,同时保留 Sandbox 对象及其 Volume,从而为后续恢复保留状态。

这使 Sandbox 更接近一个“由 Kubernetes 管理的轻量状态运行环境”。

Agent Sandbox 管理的是 Orchestration

这里有一个很重要的职责边界。

Agent Sandbox 负责编排隔离环境的创建和管理。

真正执行容器隔离的是底层 Sandbox Runtime。

例如:

flowchart TD
    Sandbox[Sandbox] --> Pod[Pod]
    Pod -->|runtimeClassName| Runtime[Kata Containers<br/>gVisor<br/>other sandbox runtime]

Agent Sandbox 官方文档也明确把自己定义为 sandbox orchestrator,并通过 Kubernetes RuntimeClass 将 Pod 交给 Kata、gVisor 等 Runtime。

因此,对于需要执行 LLM-generated code 的 Agent 系统,Agent Sandbox 负责编排隔离环境,Sandbox Runtime 负责真正执行容器与宿主机之间的隔离。

从一个 Sandbox 扩展到大规模 Sandbox

单个 Sandbox 解决了运行环境的问题,大规模 Agent 平台还需要解决另外一个问题:

当每秒不断有新的 Agent Session 创建时,怎样快速获得一个已经准备好的 Sandbox?

Agent Sandbox 为此提供了三个 Extension API:SandboxTemplate、SandboxWarmPool 和 SandboxClaim。

它们和 Sandbox 的关系如下:

flowchart TD
    Template[SandboxTemplate]
    Pool[SandboxWarmPool]
    Claim[SandboxClaim]
    Sandbox[Sandbox]
    Pod[Pod]
    Runtime[Sandbox Runtime]

    Pool -->|references| Template
    Pool -->|pre-warms| Sandbox
    Claim -->|claims / adopts| Sandbox
    Sandbox --> Pod
    Pod --> Runtime

SandboxTemplate

SandboxTemplate 保存一份可复用的 Sandbox 配置。

可以把它理解成 Sandbox 的 Runtime Template。

其中描述 image、command、resources、RuntimeClass、volume、Pod metadata 和其他运行环境配置。

多个 Session 可以基于同一个 Template 创建结构一致的 Sandbox。

SandboxWarmPool

SandboxWarmPool 维护一定数量提前创建好的 Sandbox。

当前 upstream API 中:

spec:
  replicas: 4
  sandboxTemplateRef:
    name: python-runtime

表示始终维护 4 个基于指定 Template 的 Sandbox。

WarmPool Controller 还维护 status.replicas 和 status.readyReplicas。

当一个 Sandbox 被 Session claim 后,该 Sandbox 会离开 Pool,Pool Controller 再创建新的 Sandbox补足目标容量。当前 upstream 还支持 OnReplenish 与 Recreate 两类更新策略。

SandboxClaim

业务系统通常无需直接选择某一个 Sandbox。

它只需要创建:

kind: SandboxClaim

表达:“我要一个可以使用的 Sandbox。”

当前 upstream v1beta1 API 通过:

spec:
  warmPoolRef:
    name: python-runtime

指定资源池。

Controller 首先尝试获得可用的 warm Sandbox;没有合适的 warm candidate 时,再进入 cold path,从 Template 创建新的 Sandbox。

最新实现中甚至专门为 warm candidate 设置了短暂 grace period,允许刚创建完成的候选 Sandbox 等待 Pod IP 就绪,避免过早退化到 cold start。

因此一次 Sandbox 分配已经可以抽象成:

flowchart TD
    Claim[SandboxClaim] --> Find[Find Ready Sandbox]
    Find -->|found| Adopt[adopt]
    Find -->|missing| Cold[cold create]
    Adopt --> Sandbox[Sandbox]
    Cold --> Sandbox

这套 API 正好给 AgentCube 提供了一个很合适的基础层。

AgentCube:在 Sandbox 上增加 Agent Runtime 语义

Agent Sandbox 能够回答如何获得一个隔离、单实例、有状态的运行环境;AgentCube继续向上抽象,回答如何获得一个可以被 Agent 使用的 Runtime Session。当前 AgentCube 中最核心的两个用户态 CRD 是:

AgentRuntime 与 CodeInterpreter

两者面向不同的 workload profile。

AgentRuntime

AgentRuntime 面向通用 Agent Runtime。

其 podTemplate 基本保留了完整 Kubernetes PodSpec,因此适合需要 Volume、Secret、Sidecar、自定义网络、自定义 Runtime、多容器和特殊资源配置的复杂 Agent。当前源码中 AgentRuntimeSpec.Template 直接包含 corev1.PodSpec。

例如 Claude Code、OpenHands 一类长期运行的 Agent Runtime,都更接近这类 workload。

CodeInterpreter

CodeInterpreter 面向执行动态代码的 Sandbox。

它提供的 Template 更受约束,主要暴露 image、command / args、environment、resources 和 runtimeClassName。

同时还增加:

sessionTimeout:
maxSessionDuration:
warmPoolSize:
authMode:

因此 CodeInterpreter 更适合作为 Python executor、Shell executor、Code Interpreter 和 Tool execution environment。

AgentCube 当前代码也直接把它描述为用于 potentially untrusted、LLM-generated code 的隔离执行环境。

至此,两个项目形成了非常清晰的职责分层:

AgentCube、Agent Sandbox、Kubernetes 与 Sandbox Runtime 的职责分层

一次 Agent 请求背后发生了什么?

接下来沿着真实代码看一次调用链。

假设已经创建一个 CodeInterpreter:

apiVersion: runtime.agentcube.volcano.sh/v1alpha1
kind: CodeInterpreter
metadata:
  name: python
spec:
  template:
    image: <code-interpreter-image>
    runtimeClassName: kata
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: "1"
        memory: 512Mi

  sessionTimeout: 15m
  maxSessionDuration: 8h
  warmPoolSize: 2

这里的关键字段是:

warmPoolSize: 2

它会触发 AgentCube 和 Agent Sandbox 之间最重要的一组协作。

第一层转换:CodeInterpreter → SandboxTemplate + SandboxWarmPool

AgentCube 的 CodeInterpreterReconciler 会 watch CodeInterpreter。

源码中的逻辑非常直接:

CodeInterpreter 到 SandboxWarmPool 的转换

也就是说,用户只需要创建 CodeInterpreter。

AgentCube 会自动产生 SandboxTemplate 和 SandboxWarmPool。

当前实现中,SandboxTemplate 由 CodeInterpreter Template 转换生成,而 SandboxWarmPool.replicas 直接来自 warmPoolSize。

于是 warmPoolSize: 2 在底层大致转化成两个已经 Ready 的运行环境:Sandbox A 对应 Pod A,Sandbox B 对应 Pod B。

这些运行环境在用户真正发送 Agent 请求之前就已经完成 Pod 创建、调度、镜像准备和 Runtime 初始化。

这也是 Warm Pool 降低 Agent cold-start latency 的核心原理。

Router:把 HTTP Invocation 变成 Session

AgentCube 向用户暴露的是 Invocation API。

请求会首先到达 AgentCube Router。

Router 会读取:

x-agentcube-session-id

其逻辑非常简单:session-id 为空时创建一个新的 Sandbox Session;session-id 存在时从 Store 找到已有 Sandbox Session。

当前 Router 的 handleInvoke() 会从 Header 中取出 x-agentcube-session-id,然后调用:

GetSandboxBySession(...)

获取对应 Sandbox。

SessionManager 中对应的实现则明确区分两条路径:

Session ID 的两条处理路径

因此 AgentCube 在 Kubernetes Sandbox 之上增加了一个非常重要的概念:Session。

从应用视角看,Session ID 就是整个 Agent Runtime 的逻辑身份。

从基础设施视角看,Session ID 映射到 SandboxInfo,其中包含 Namespace、Sandbox、Pod IP 和 EntryPoints。

这层映射存储在 Redis 或 Valkey 中。

Router 本身可以保持无状态并进行水平扩展。

Warm Path:Session → SandboxClaim → Ready Sandbox

如果 CodeInterpreter 开启了 Warm Pool,Workload Manager 收到创建请求以后不会直接构造普通 Sandbox。

当前 AgentCube main 的代码中:

if WarmPoolSize > 0 {
    buildSandboxClaimObject(...)
}

因此,Workload Manager 会为新的 Session 创建 SandboxClaim。

接下来控制权进入 Agent Sandbox。

Agent Sandbox Controller 从 WarmPool 中找到一个已经 Ready 的 Sandbox,并完成 claim/adoption。

最终资源关系变成 CodeInterpreter 使用 SandboxWarmPool 中的 Sandbox A 和 Sandbox B;新的 Session 创建 SandboxClaim,随后认领 Sandbox A,最终使用 Pod A。

与此同时,SandboxWarmPool 发现 ready capacity 减少,并创建新的 Sandbox C。

这样 Pool 又回到 ready = 2。

AgentCube 如何确认 Claim 已经真正可以工作?

创建 SandboxClaim 成功,只能说明 Kubernetes API object created,Agent Runtime 此时还不一定可以接收请求。AgentCube Workload Manager 会持续读取 SandboxClaim 的 claim.status.sandbox.name,获得 agent-sandbox 最终分配的 Sandbox 后继续读取 Sandbox 的 Ready 状态;只有 adopted Sandbox 进入 Ready 状态后,Workload Manager 才继续获得对应 Pod IP,并检测 EntryPoint 是否真的可以连接。当前 waitForClaimSandboxReady() 的实现就是读取 SandboxClaim,获取 claim.status.sandbox.name,再读取 Sandbox,确认 Sandbox Ready 后返回。

随后:

Sandbox、Pod IP、EntryPoint Probe 与 Session Store

到这里,Session 才真正对 Router 可用。这也是为什么 Agent Runtime 的“Ready”需要跨越多层状态:

从 CR 创建到 Session Ready 的就绪链路

对于低延迟 Agent 基础设施而言,真正值得衡量的 startup latency 也应该覆盖这整条链路。

Cold Path:没有 Warm Pool 时发生什么?

关闭 Warm Pool:

warmPoolSize: 0

Workload Manager 会直接创建 Sandbox。

其 PodTemplate 来源于 AgentRuntime 或 CodeInterpreter 配置。

AgentCube 当前 buildSandboxObject() 直接使用:

sigs.k8s.io/agent-sandbox/api

中的 Sandbox 类型,并把 Session ID、PodSpec 和 lifecycle 等信息写入 Sandbox。

这条路径需要等待 Scheduling、Image preparation、Container start、Sandbox runtime initialization 和 Readiness。

而 Warm Path 可以复用已经完成这些工作的 Sandbox。

因此:

Cold Path 与 Warm Path

Warm Pool 的本质就是把启动成本提前支付。

Agent Sandbox 面向 isolated stateful singleton workload,AgentCube 面向 AI Agent Runtime Session。一个 Sandbox 本身并不知道哪些请求属于同一个 Agent Session、一个 HTTP 请求应该被路由到哪个 Sandbox、Session 最后一次 Invocation 是什么时候、一个 Agent Runtime 暴露哪些 API、Code Interpreter 怎样进行身份认证、多个 Router 副本怎样共享 Session,以及 Agent SDK 怎样访问这一运行环境;这些能力由 AgentCube补齐。

例如 Router 每次 Invocation 前后都会更新 LastActivityAt。Workload Manager 的 GC 再根据 SessionTimeout 和 MaxSessionDuration,判断是否需要删除对应 Sandbox 或 SandboxClaim;当前实现会分别查询 inactive session 和 expired session,再按 SessionID 去重并进行回收。

这里的设计价值在于每一层都拥有自己的清晰语义。

Session 与 Sandbox:两个不同层级的状态

AgentCube 当前基本采用 1 Session : 1 Sandbox 的运行模型。

这使 Session 成为上层业务身份,而 Sandbox 成为下层物理运行实例。

例如一个 Agent 连续调用 execute python、write file、execute shell 和 read result。

客户端始终携带:

x-agentcube-session-id: xxx

Router 就会把这些请求持续送到同一 Sandbox。

因此代码执行生成的 /files/result.csv、/tmp/cache、workspace 和 process state,可以在多轮 Invocation 中继续存在。

这正是 Agent Runtime 与普通 request/response serverless function 差异最大的地方之一:

Session 将两者连接起来。

安全隔离需要多层共同完成

Agent Runtime 经常需要执行 LLM 自动生成的代码,因此安全设计不能只关注容器本身。

AgentCube × Agent Sandbox 的安全边界至少包含四层:

AgentCube × Agent Sandbox 的安全边界

AgentCube 的 CodeInterpreter 还支持 authMode=picod。

当前实现会从 Router identity Secret 中获取 public key,并将 PICOD_AUTH_PUBLIC_KEY 注入 CodeInterpreter Sandbox;Router 再为请求签发 JWT,从而限制对 Sandbox runtime API 的直接访问。相关 public-key injection 同样会应用到 warm-pool Template。

同时,runtimeClassName 可以进一步选择 Kata 等 Runtime,为执行不可信代码建立更强的内核隔离。

这里需要特别强调:

Sandbox CRD 本身表达安全运行环境的生命周期,最终隔离强度仍然取决于实际 Runtime、Kubernetes 安全配置以及网络策略。

为什么选择复用 upstream Agent Sandbox

从工程角度看,AgentCube直接管理 Pod 当然也可以完成基本功能。

随着系统逐渐演进,会很快需要自己解决 stable identity、persistent storage、pause / resume、scheduled shutdown、warm pool、claim、resource adoption、sandbox status 和 runtime integration。

这些能力具有明显的通用性。

Agent Sandbox 将它们沉淀成 Kubernetes SIG Apps 社区维护的标准 primitive:Sandbox、SandboxTemplate、SandboxWarmPool 和 SandboxClaim。

AgentCube 可以把研发重心继续放在更靠近 AI Agent 的领域:Agent Runtime、Session Management、Invocation Routing、Authentication、Agent SDK、Scheduling、Startup Acceleration 和 Large-scale Sandbox Management。

于是整个系统形成了一种很典型的 Kubernetes ecosystem 分层:

flowchart LR
    Domain[Domain Layer<br/>AgentCube] -->|Agent semantics| Primitive[Infrastructure Primitive<br/>Agent Sandbox]
    Primitive -->|Sandbox semantics| Kubernetes[Kubernetes]
    Kubernetes --> Runtime[Runtime]

底层社区能力继续演进时,上层也可以持续获得收益。

从 Agent Runtime 看未来的 Kubernetes

过去 Kubernetes 的核心抽象主要围绕 Service、Batch Job 和 Stateful Application。

AI Agent 带来了一类新的 workload:long-lived logical session、short/intermittent computation、private execution state、strong isolation 和 high creation frequency。

它既需要 Kubernetes 的调度、资源管理与生态能力,也需要比 Pod 更符合 Agent 语义的抽象。

Agent Sandbox 正在尝试把 isolated stateful singleton environment 沉淀成 Kubernetes primitive。

AgentCube继续向上提供 Agent Runtime Session。

最终形成:

AgentCube 与 Kubernetes Agent Sandbox 的完整架构

从这个角度看,AgentCube 与 Kubernetes Agent Sandbox 的组合代表了一种很清晰的云原生 Agent Infrastructure 路径: Kubernetes 继续负责资源与调度,Agent Sandbox提供标准化隔离运行环境,AgentCube负责把这些运行环境组织成真正可被 AI Agent 使用的 Runtime Session。

随着 Agent workload 规模增长,后续真正值得继续优化的方向也逐渐清晰,包括更低延迟的 Sandbox allocation、Warm Pool 动态伸缩、Sandbox suspend / resume、snapshot-based startup、更高密度的安全隔离、面向大规模 Session 的调度,以及 Agent Runtime 的可观测性与资源治理。

参考资料

Footnotes

  1. Agent Sandbox:https://github.com/kubernetes-sigs/agent-sandbox 返回正文

  2. AgentCube:https://github.com/volcano-sh/agentcube 返回正文