ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

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

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 由两个组件组成Sandbox Serverdemos/sandbox/main.go运行在 Agent Substrate Actor 内部的应用程序暴露一个简单的、无状态的/processHTTP 端点来执行命令Sandbox Clientdemos/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其余情况取进程真实退出码超时控制若请求携带TimeoutGo duration 字符串如5s则通过context.WithTimeout给命令执行加上截止时间工作目录Cwd非空时通过cmd.Dir设置环境变量EnvVars非空时在os.Environ()基础上追加键值对因此可以动态注入环境输出收集stdout 与 stderr 分别以字符串返回最终以 JSON 编码回写。值得一提的是Server 本身是无状态的——它不保存任何会话数据状态的持久化完全由 Agent Substrate 的快照机制承担Actor 挂起时文件系统被整体快照到 GCS恢复时再整体还原因此执行状态跨挂起/恢复保持这一能力来自平台而非应用本身。2.2 Sandbox ClientREPL 交互客户端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 路由服务器地址启动流程结合源码分为两步连接 ateapi 并恢复 Actor通过 gRPC 调用cli.ResumeActor(...)把挂起的 Actor 恢复为运行态进入 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依次完成构建 Sandbox Server 镜像基于 Alpine Linuxko://github.com/agent-substrate/substrate/demos/sandbox创建ate-demo-sandbox命名空间和 WorkerPool清单见 demos/sandbox/sandbox.yaml.tmpl创建ate-demo-sandboxatespace 及sandbox-templateActor 模板清单见 demos/sandbox/sandbox-template.yaml.tmpl通过kubectl ate create actor-template应用等待模板的 golden snapshot 构建完成。部署完成后检查模板kubectl ate get actor-template sandbox-template -a ate-demo-sandbox4.1 核心清单解读WorkerPooldemos/sandbox/sandbox.yaml.tmpl 定义了名为sandbox-workerpool的 WorkerPoolapiVersion: 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 核心清单解读ActorTemplatedemos/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].imageSandbox Server 镜像PORT80与 Server 端默认端口逻辑一致resources.limits沙箱 Actor 本身的资源上限cpu 2 核、内存 1Gi需要等于或低于池内单 Worker 容量snapshotsConfigonPause与onCommit均为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 转发出来# 终端 1API Server kubectl port-forward -n ate-system svc/api 8080:443 # 终端 2Router kubectl port-forward -n ate-system svc/atenet-router 8000:808080端口对应 ateapi gRPC 服务客户端用它执行 Actor 的 Resume / Suspend8000端口对应 atenet HTTP 路由器客户端把/process请求发往这里。七、使用客户端进入sandboxREPL构建并运行客户端go build -o bin/sandbox-client ./demos/sandbox/client ./bin/sandbox-client --ateapilocalhost:8080 --atenetlocalhost:8000 --atespaceate-demo-sandbox --namemy-sandbox-17.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 写入的文件在下次连接后依然存在的原因。若要永久删除已挂起的 Actorkubectl 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-poolWorkerPooldemos/sandbox/manual-test-multi-template.yamlActorTemplate 在容器上挂载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),仅供参考
返回列表