news 2026/9/23 22:34:56

Agent Substrate Sandbox Demo 实战指南:在 Kubernetes 上构建可挂起/恢复的有状态沙箱执行环境

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent Substrate Sandbox Demo 实战指南:在 Kubernetes 上构建可挂起/恢复的有状态沙箱执行环境

Agent Substrate Sandbox Demo 实战指南:在 Kubernetes 上构建可挂起/恢复的有状态沙箱执行环境

【免费下载链接】substrateAgent Substrate: the core system项目地址: https://gitcode.com/GitHub_Trending/substrate7/substrate

本文档深入讲解 Agent Substrate 仓库中的demos/sandbox示例:一个运行在 Agent Substrate 之上、基于 Alpine Linux 的有状态沙箱执行环境。你将掌握如何构建镜像、部署 WorkerPool 与 ActorTemplate、通过kubectl-ate创建 Actor、用 REPL 客户端交互式执行任意命令,并理解 Actor 挂起(suspend)与恢复(resume)背后的状态保持机制。

一、Demo 概述:什么是有状态沙箱

demos/sandbox/README.md将本示例定位为运行在 Agent Substrate 上的有状态(stateful)沙箱执行环境。它的核心能力是:

  • 在沙箱化、隔离的容器中运行任意命令,该容器基于 Alpine Linux;
  • 在 Actor 挂起(suspend)与恢复(resume)之间完整保留执行状态——你在沙箱里创建的文件、修改的环境,在挂起后重新连接时依然存在。

这种"可挂起、可恢复"的语义来自 Agent Substrate 的 Actor 模型:Actor 占据整个 Worker,其文件系统快照会被持久化到 GCS,从而让"重启后状态不丢失"成为可能。这正是该 Demo 与普通kubectl exec式一次性容器最本质的区别。

[!WARNING]安全声明(原文强制提示):该 Demo不包含任何授权校验,沙箱 Actor 会不加验证地执行客户端传来的任意命令。严禁在生产环境部署或将本 Demo 暴露给不可信网络。它仅用于演示 Agent Substrate 的沙箱与快照能力。

二、组件构成

Demo 由两个组件组成:

  1. Sandbox Server(demos/sandbox/main.go):运行在 Agent Substrate Actor 内部的应用程序,暴露一个简单的、无状态的/processHTTP 端点来执行命令;
  2. Sandbox Client(demos/sandbox/client/main.go):一个 CLI REPL 工具,允许你以交互方式与沙箱 Actor 通信。

2.1 Sandbox Server:无状态的/process端点

Server 端代码非常精简,核心逻辑在handleProcess中:

pattern := "/process" http.HandleFunc("POST "+pattern, handleProcess) port := os.Getenv("PORT") if port == "" { port = "80" } log.Printf("Stateless Sandbox serving at port %s, path: %s", port, pattern) log.Fatal(http.ListenAndServe(":"+port, nil))

它监听PORT环境变量指定的端口(默认80),只接受POST /process请求。请求体结构如下:

type ProcessRequest struct { Command []string `json:"command"` EnvVars map[string]string `json:"envvars,omitempty"` Cwd string `json:"cwd,omitempty"` Timeout string `json:"timeout,omitempty"` }

响应结构:

type ProcessResponse struct { Stdout string `json:"stdout"` Stderr string `json:"stderr"` ExitCode int `json:"exitCode"` Error string `json:"error,omitempty"` }

Server 对请求的处理逻辑(demos/sandbox/main.go):

  • 命令执行:使用exec.CommandContext执行Command[0]及后续参数,若命令不存在则ExitCode-1,正常退出为0,其余情况取进程真实退出码;
  • 超时控制:若请求携带Timeout(Go duration 字符串,如"5s"),则通过context.WithTimeout给命令执行加上截止时间;
  • 工作目录Cwd非空时通过cmd.Dir设置;
  • 环境变量EnvVars非空时在os.Environ()基础上追加键值对,因此可以动态注入环境;
  • 输出收集:stdout 与 stderr 分别以字符串返回,最终以 JSON 编码回写。

值得一提的是,Server 本身是"无状态"的——它不保存任何会话数据,状态的持久化完全由 Agent Substrate 的快照机制承担:Actor 挂起时文件系统被整体快照到 GCS,恢复时再整体还原,因此"执行状态跨挂起/恢复保持"这一能力来自平台而非应用本身。

2.2 Sandbox Client:REPL 交互客户端

Client 端(demos/sandbox/client/main.go)是一个交互式 REPL,启动时接受四个 flag:

参数默认值说明
--name(必填)沙箱 Actor 的名称,如my-sandbox-1
--atespace(必填)Actor 所在的 Atespace,如ate-demo-sandbox
--ateapilocalhost:8080ateapi gRPC 服务器地址
--atenetlocalhost:8000atenet HTTP 路由服务器地址

启动流程(结合源码)分为两步:

  1. 连接 ateapi 并恢复 Actor:通过 gRPC 调用cli.ResumeActor(...)把挂起的 Actor 恢复为运行态;
  2. 进入 REPL 输入循环:逐行读取 stdin,把命令 POST 到 atenet 路由器的/process,打印返回的 stdout / stderr / 错误信息。

退出时的清理动作由defer保证:客户端会在退出前调用cli.SuspendActor(...)挂起 Actor,把当前沙箱文件系统状态快照保存下来——这就是"状态跨挂起保持"的落地实现。

三、前提条件

在开始部署之前,需要准备:

  • 一个安装了Agent Substrate的 Kubernetes 集群;
  • ko已安装,用于构建镜像(参考 hack/install-ate.sh 的构建流程);
  • 一个用于存储快照的GCS bucket(在 demos/sandbox/sandbox-template.yaml.tmpl 中配置);
  • kubectl-ateCLI 已安装(可通过go install ./cmd/kubectl-ate安装,安装入口见 cmd/kubectl-ate/main.go)。

四、构建与部署

[!NOTE]不要手动编辑demos/sandbox/*.yaml.tmpl清单。安装脚本会在部署时自动注入你的${BUCKET_NAME}环境变量(模板中以gs://${BUCKET_NAME}/ate-demo-sandbox/占位)。

使用核心安装脚本构建镜像并把 Demo 部署到集群:

./hack/install-ate.sh --deploy-demo-sandbox

从 hack/install-demo-sandbox.sh 的源码可以看到,该命令实际调用deploy_substrate_demo render_demo_manifest,依次完成:

  1. 构建 Sandbox Server 镜像(基于 Alpine Linux,ko://github.com/agent-substrate/substrate/demos/sandbox);
  2. 创建ate-demo-sandbox命名空间和 WorkerPool(清单见 demos/sandbox/sandbox.yaml.tmpl);
  3. 创建ate-demo-sandboxatespace 及sandbox-templateActor 模板(清单见 demos/sandbox/sandbox-template.yaml.tmpl,通过kubectl ate create actor-template应用);
  4. 等待模板的 golden snapshot 构建完成

部署完成后,检查模板:

kubectl ate get actor-template sandbox-template -a ate-demo-sandbox

4.1 核心清单解读:WorkerPool

demos/sandbox/sandbox.yaml.tmpl 定义了名为sandbox-workerpool的 WorkerPool:

apiVersion: ate.dev/v1alpha1 kind: WorkerPool metadata: name: sandbox-workerpool namespace: ate-demo-sandbox labels: workload: sandbox spec: replicas: 2 workerImage: ko://github.com/agent-substrate/substrate/cmd/ateom-gvisor template: resources: limits: cpu: "2" memory: 2Gi requests: cpu: 500m memory: 2Gi

关键点(模板注释与 internal/sizing 的语义一致):

  • workerImage指向cmd/ateom-gvisor,即 gVisor 沙箱运行时对应的 Worker 实现(同目录还有 microvm 实现,参见 cmd/ateom-microvm);
  • 调度容量来自 limits,而非 requestsworkerCapacity只读取 limits;而 kube-scheduler 按 requests 装箱,因此 CPU request 刻意设得远低于 limit,让 Worker 池在小节点上也易于调度,同时不改变单个 Actor 可用的资源上限;
  • 内存不可压缩,所以 memory 的 request 与 limit 保持一致;
  • Actor 占据整个 Worker,因此沙箱本身的大小(见下文 ActorTemplate 的resources)应设置在该池单 Worker 容量之下。

4.2 核心清单解读:ActorTemplate

demos/sandbox/sandbox-template.yaml.tmpl 定义了 Actor 模板(注意:ActorTemplate 不是 CRD,它通过 ate API 以kubectl ate create actor-template创建):

metadata: atespace: ate-demo-sandbox name: sandbox-template workerSelector: matchLabels: workload: sandbox containers: - name: sandbox image: ko://github.com/agent-substrate/substrate/demos/sandbox env: - name: PORT value: "80" resources: limits: - name: cpu quantity: "2" - name: memory quantity: 1Gi snapshotsConfig: onPause: SNAPSHOT_CONTENT_SCOPE_FULL onCommit: SNAPSHOT_CONTENT_SCOPE_FULL storageLocation: gs://${BUCKET_NAME}/ate-demo-sandbox/ sandboxConfig: sandboxClass: SANDBOX_CLASS_GVISOR configName: gvisor-default

逐项说明:

  • workerSelector.matchLabels.workload: sandbox:模板只会被调度到带workload: sandbox标签的 WorkerPool 上,与上文 WorkerPool 的 labels 一一对应;
  • containers[0].image:Sandbox Server 镜像,PORT=80与 Server 端默认端口逻辑一致;
  • resources.limits沙箱 Actor 本身的资源上限(cpu 2 核、内存 1Gi),需要等于或低于池内单 Worker 容量;
  • snapshotsConfigonPauseonCommit均为SNAPSHOT_CONTENT_SCOPE_FULL,即挂起与提交时都做全量文件系统快照,快照存放于gs://${BUCKET_NAME}/ate-demo-sandbox/
  • sandboxConfig:使用 gVisor 沙箱类与gvisor-default配置(集群级 gVisor 配置由 manifests/ate-install/sandboxconfig-gvisor.yaml 提供)。

五、创建沙箱 Actor

在 Demo 的 atespace 中创建一个沙箱 Actor,名称自选(如my-sandbox-1):

# 若尚未安装 CLI,先安装为 kubectl 插件 go install ./cmd/kubectl-ate kubectl ate create actor my-sandbox-1 -a ate-demo-sandbox --template sandbox-template

--template指定 Actor 模板名称,模板会在 Actor 所在的 atespace 中解析。

六、端口转发

如果客户端在本地运行,需要分别在两个终端中把 API 与 Router 转发出来:

# 终端 1:API Server kubectl port-forward -n ate-system svc/api 8080:443 # 终端 2:Router kubectl port-forward -n ate-system svc/atenet-router 8000:80
  • 8080端口对应 ateapi gRPC 服务(客户端用它执行 Actor 的 Resume / Suspend);
  • 8000端口对应 atenet HTTP 路由器(客户端把/process请求发往这里)。

七、使用客户端:进入sandbox>REPL

构建并运行客户端:

go build -o bin/sandbox-client ./demos/sandbox/client ./bin/sandbox-client --ateapi=localhost:8080 --atenet=localhost:8000 --atespace=ate-demo-sandbox --name=my-sandbox-1

7.1 路由原理:ate-target-actor请求头

客户端会把每个/process请求发送到 Router,并自动根据--name--atespace设置路由头:

req.Header.Set(atenet.TargetActorHeader, actorRef.String())

TargetActorHeader定义于 internal/atenet/headers.go,值为ate-target-actor,其格式为<atespace>/<actor>(如ate-demo-sandbox/my-sandbox-1),并通过ParseTargetActor做合法性校验。

任何替代的 HTTP 客户端都必须发送等价的ate-target-actor头;URL 与Host头并不能选中目标 Actor。请求由 Router 依据该头路由到对应沙箱,这一点与常规 HTTP 反向代理有本质区别。

7.2 REPL 交互示例

进入sandbox>提示符后,即可逐条执行命令(每条命令最终以sh -c <command>形式发送):

sandbox> ls -la sandbox> pwd sandbox> echo "Hello" > test.txt sandbox> cat test.txt

由于命令实际由sh -c执行(见 demos/sandbox/client/main.go 中的runCommand),支持管道、重定向、变量展开等 shell 特性。

输入exit退出 REPL。退出时会自动触发 Actor 的挂起:客户端在defer中调用 ateapi 的SuspendActor,把沙箱文件系统快照写入 GCS。下次再运行客户端连接同一 Actor 时,会先调用ResumeActor恢复快照——这就是"echo 写入的文件在下次连接后依然存在"的原因。

若要永久删除已挂起的 Actor:

kubectl ate delete actor my-sandbox-1 -a ate-demo-sandbox

八、卸载 Demo

从集群中移除沙箱 Demo 的全部资源(Actor、模板、atespace、WorkerPool 与命名空间):

./hack/install-ate.sh --delete-demo-sandbox

该命令在 hack/install-demo-sandbox.sh 中对应delete_substrate_demo render_demo_manifest,按清单反向清理ate-demo-sandbox命名空间与sandbox-template

九、进阶参考:多卷挂载的手动测试清单

仓库还提供了两个手动测试清单,用于验证带卷挂载的沙箱(可作为自定义沙箱模板的起点):

  • demos/sandbox/manual-test-multi.yaml:定义ate-manual-test-multi命名空间与sandbox-poolWorkerPool;
  • demos/sandbox/manual-test-multi-template.yaml:ActorTemplate 在容器上挂载vol-hostpathcsi-hostpath-sc)与vol-nfscsi-nfs-sc)两个外部卷,分别挂载到/hostpath-data/nfs-data

这两个清单展示了如何在 ActorTemplate 中声明externalVolumeTemplate,实现沙箱与持久化存储的结合(如 CSI 卷的接入方式可参考 docs/csi-volumes.md)。

十、小结

通过demos/sandbox,你可以完整地走通 Agent Substrate 的核心工作流:WorkerPool 提供调度容量 → ActorTemplate 声明容器、资源与快照策略 →kubectl ate create actor实例化 Actor → REPL 客户端通过ate-target-actor路由头与 Router 交互 → 退出时全量快照挂起、重连时恢复。这套"任意命令执行 + 状态跨挂起保持"的能力组合,为构建更复杂的 Agent 执行环境提供了最小可复用的参考实现。相关架构背景可进一步阅读 docs/architecture.md 与 docs/request-parking.md。

【免费下载链接】substrateAgent Substrate: the core system项目地址: https://gitcode.com/GitHub_Trending/substrate7/substrate

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 22:30:05

IPD集成产品开发流程培训PPT怎么策划?从骨架到避坑的全套方案

简介&#xff1a;面向企业研发管理人员、产品经理及项目管理人员&#xff0c;这份 IPD 培训PPT系统讲解集成产品开发的核心方法论&#xff0c;针对许多公司新产品开发过程效率低、缺乏跨职能协作的痛点&#xff0c;阐明如何通过结构化开发流程与投资评审机制提升产品商业化成功…

作者头像 李华
网站建设 2026/9/23 22:30:01

分布式存储EDS实战手册解读:存储池、NFS/CIFS/iSCSI与数据保护

简介&#xff1a;这是深信服企业级分布式存储 aStor-EDS 3.0.5 的官方用户手册&#xff0c;面向技术服务工程师、运维人员及存储管理员。手册系统介绍了产品的架构组成、高可用/高性能/高安全关键特性&#xff0c;并覆盖安装前环境检查、存储节点与元数据服务器部署、集群配置及…

作者头像 李华
网站建设 2026/9/23 22:28:51

Atlas 300V部署YOLO全流程:从模型转换到推理优化

只要碰过AI部署这摊事的人&#xff0c;十有八九会在某个阶段撞上"Atlas"这个词。有人问atlas 300V 24G到底是不是一张运算加速卡&#xff0c;有人问它能不能跑YOLO&#xff0c;还有人拿着YOLOv8的权重文件在Atlas环境里折腾几天都转不出一个能跑的模型。我自己的感受…

作者头像 李华