资讯动态

在 Agent Substrate 上运行 Jupyter Notebook:透明挂起与按需恢复的完整实践指南

发布时间:2026/9/23 21:09:38 来源:尧图企业网站定制
在 Agent Substrate 上运行 Jupyter Notebook透明挂起与按需恢复的完整实践指南【免费下载链接】substrateAgent Substrate: the core system项目地址: https://gitcode.com/GitHub_Trending/substrate7/substrate导读本文基于 Agent Substrate 仓库中的 Jupyter Notebook Demo完整讲解如何把标准的、未经任何改造的 Jupyter 官方镜像jupyter/base-notebook作为 Substrate Actor 部署到本地 Kind 集群并通过浏览器访问、挂起、恢复这套完整生命周期。你将掌握kubectl-ate的 Actor 创建/挂起/恢复命令、ate-target-actor路由头的注入原理、NGINX 代理配置以及snapshotsConfig中onPause/onCommit快照策略的底层实现最终能独立复现空闲即挂起、访问即恢复的交互式开发环境。Demo 要解决的问题在传统 Kubernetes 中一个 Jupyter 容器只要 Deployment 存在就会持续占用 CPU 与内存。Agent Substrate 的思路是把容器当作可挂起、可恢复的 Actor——空闲时对工作负载做内存快照并挂起到对象存储访问时再从快照透明恢复浏览器侧完全无感。本 Demo 的意义在于验证两个关键能力标准镜像零改造接入使用官方jupyter/base-notebook镜像jupyter-template.yaml.tmpl 中按 digest 固定版本无需定制 Dockerfile 或注入 Agent Sidecar即可被 Substrate 纳管。透明恢复transparent resume挂起状态下浏览器发起的请求能自动触发恢复流程用户刷新页面即可继续使用无需手动干预。前置条件根据 demos/jupyter/README.md本 Demo 需要一个本地 Kubernetes 集群Kind或 GKE安装ko用于构建并推送镜像到本地 registry一个 GCS Bucket 用于存放快照若使用 Kindinstall-ate-kind.sh 会自动使用默认 bucket 名ate-snapshots搭建集群内快照仓库无需额外准备。注意ko构建镜像依赖本地 Go 工具链kubectl-ate的安装同样通过go install完成因此开发机需具备 Go 环境。在 Kind 上快速启动1. 创建 Kind 集群./hack/create-kind-cluster.sh该脚本会创建一个名为ate-demo的本地集群并配置本地 registry端口 5001供后续ko推送镜像使用。2. 安装 Agent Substrate 核心系统./hack/install-ate-kind.sh --deploy-ate-system脚本内部install-ate-kind.sh做了这些环境预设KO_DOCKER_REPOlocalhost:5001镜像推送到本地 registryKO_DEFAULTPLATFORMSlinux/host-arch按宿主机架构构建ATE_INSTALL_KINDtrue使用 Kustomize overlay 适配 KindBUCKET_NAMEate-snapshots快照落盘到集群内仓库KUBECTL_CONTEXTkind-cluster确保安装落到本地 Kind 集群而非误操作其他 kubeconfig context。3. 部署 Jupyter Demo./hack/install-ate-kind.sh --deploy-demo-jupyter该命令在 install-demo-jupyter.sh 中注册为demo-jupyter实际调用deploy_substrate_demo渲染两个清单demos/jupyter/jupyter.yaml.tmpl创建ate-demo-jupyterNamespace、jupyterWorkerPool、jupyter-proxyNGINX 反向代理 Deployment/Service、以及 nginx 配置 ConfigMapdemos/jupyter/jupyter-template.yaml.tmpl创建名为jupyter的 ActorTemplate。理解部署产物WorkerPool 与 ActorTemplateWorkerPoolActor 的运行底座jupyter.yaml.tmpl中定义了 WorkerPoolapiVersion: ate.dev/v1alpha1 kind: WorkerPool metadata: name: jupyter namespace: ate-demo-jupyter labels: workload: jupyter spec: replicas: 1 workerImage: ko://github.com/agent-substrate/substrate/cmd/ateom-gvisorworkerImage指向cmd/ateom-gvisor即 gVisor 沙箱运行时组件——Actor 实际运行在 gVisor 隔离的沙箱内labels.workload: jupyter与 ActorTemplate 中的workerSelector匹配将 Actor 调度到该 WorkerPool。ActorTemplateActor 的规格与快照策略jupyter-template.yaml.tmplprotojson 形状的ateapipb.ActorTemplate通过kubectl ate create actor-template -f -应用定义了镜像、启动参数、就绪探针与快照配置metadata: atespace: ate-demo-jupyter name: jupyter workerSelector: matchLabels: workload: jupyter containers: - name: jupyter image: quay.io/jupyter/base-notebooksha256:23fbe16371af3c0fdc833fa0962b42fd07811e152b821ff51d19a8d6e9cc86cf command: - jupyter - lab - --allow-root - --ServerApp.token - --ServerApp.password - --ServerApp.allow_origin* - --ServerApp.disable_check_xsrfTrue - --port80 - --ip0.0.0.0 readyz: httpGet: path: /api port: 80 snapshotsConfig: onPause: SNAPSHOT_CONTENT_SCOPE_FULL onCommit: SNAPSHOT_CONTENT_SCOPE_FULL storageLocation: gs://${BUCKET_NAME}/ate-demo-jupyter/ sandboxConfig: sandboxClass: SANDBOX_CLASS_GVISOR configName: gvisor-default关键点解读镜像按 digest 固定jupyter/base-notebooksha256:...保证可复现性ko resolve会原样透传免密配置--ServerApp.token与--ServerApp.password使浏览器访问时无需登录README 中明确说明因此无密码就绪探针readyz.httpGet /api:80供 Substrate 判定 Jupyter 是否真正就绪快照策略onPause: SNAPSHOT_CONTENT_SCOPE_FULL表示挂起时对工作负载做全量内容快照onCommit: SNAPSHOT_CONTENT_SCOPE_FULL表示提交如停止时同样做全量快照storageLocation指定快照存放于gs://ate-snapshots/ate-demo-jupyter/Kind 场景下即集群内快照仓库。从源码看快照作用域并非摆设。在 cmd/ateapi/internal/controlapi/workflow_suspend.go 的ensureMarkedSuspending中只有当模板commitSnapshotScope返回SNAPSHOT_CONTENT_SCOPE_FULL时Actor 在挂起前才会被标记为需要提交全量快照MaybeCommitOnSuspend相关逻辑这决定了挂起前是否保留一份可回滚的持久快照。创建并访问 Jupyter Actor1. 安装 kubectl-ate 插件go install ./cmd/kubectl-ate2. 创建 Actorkubectl ate create actor jupyter-notebook -a ate-demo-jupyter --template jupyter-a ate-demo-jupyter指定 Atespace--template jupyter指定在该 Atespace 内解析的 ActorTemplateActor 名称jupyter-notebook与后续代理配置中的ate-target-actor值一一对应需保持一致。3. 通过反向代理访问Substrate 使用ate-target-actor: atespace/actor请求头做 HTTP 路由。浏览器在地址栏导航或 WebSocket 升级时无法携带自定义请求头因此本 Demo 在浏览器与 Substrate Routeratenet-router.ate-system.svc.cluster.local之间放置了一个轻量 NGINX 反向代理jupyter-proxy由其注入路由头proxy_pass http://atenet-router.ate-system.svc.cluster.local; proxy_set_header Host $http_host; proxy_set_header ate-target-actor ate-demo-jupyter/jupyter-notebook; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade;完整配置位于 jupyter.yaml.tmpl 的jupyter-proxy-configConfigMap 中。三个proxy_set_header各司其职Host $http_host保留浏览器的原始 Host 作为应用元数据ate-target-actor ate-demo-jupyter/jupyter-notebook指定路由目标必须与创建 Actor 的名称一致Upgrade/Connection upgrade保留 Jupyter 前端与内核之间的 WebSocket 升级保证 Notebook 交互不中断。README 特别强调若 Actor 改名或换 Atespace须同步更新ate-target-actor且绝不能从浏览器不可信的头中派生该值防止路由劫持。路由头的语义在源码中有明确定义internal/atenet/headers.go 声明了常量TargetActorHeader ate-target-actor并通过ParseTargetActor按atespace/actor格式解析校验——包含多个/或非法资源名都会被拒绝。4. 端口转发并打开浏览器保持以下命令在独立终端运行kubectl port-forward --address 0.0.0.0 -n ate-demo-jupyter svc/jupyter-proxy 8888:80浏览器访问http://localhost:8888即可免密进入 Jupyter Notebook 界面新建 Notebook 执行print(hello world)挂起与恢复透明生命周期管理手动挂起kubectl ate suspend actor jupyter-notebook -a ate-demo-jupyter查看状态确认已挂起kubectl ate get actor jupyter-notebook -a ate-demo-jupyter输出中的状态字段会显示STATUS_SUSPENDED。挂起背后是一套完整的状态机工作流。在 cmd/ateapi/internal/controlapi/workflow_suspend.go 的SuspendActor中执行链路依次为ensureMarkedSuspending校验 Actor 处于RUNNING或PAUSED状态并依据snapshotsConfig决定是否标记全量快照提交workflow_suspend.goensureAteletSuspended调用 atelet 将工作负载 checkpoint 到 Actor 持久化位置workflow_suspend.go期间若检测到 WorkerAssignment 损坏会触发crashActor将 Actor 置为崩溃态ensureVolumesDetached分离卷ensureSuspendedFinalized释放 Worker提交SUSPENDED状态。显式恢复kubectl ate resume actor jupyter-notebook -a ate-demo-jupyter透明恢复重点挂起状态下直接刷新浏览器页面或再次访问 URLSubstrate 会自动恢复状态并响应请求全程无感。README 称之为 transparent resume。源码印证了这条热路径的设计workflow_resume.go 的ResumeActor注释明确写道 Routed requests call ResumeActor even when the actor is already running——即被路由的请求即使在 Actor 已运行时也会调用 ResumeActor此时为幂等 no-op用于规避冷恢复延迟。恢复流程通过loadActorForResume根据模板snapshotsConfig.onResume决定引导来源默认从持久化快照恢复见 workflow_resume.go再由ensureAteletRestored调用 atelet 还原工作负载workflow_resume.go。也就是说浏览器发起的请求到达 Router → Router 发现 Actor 处于SUSPENDED→ 触发恢复工作流 → 从快照还原并响应。对用户而言只是刷新了一下页面。清理# 卸载 Demo删除 Demo 的 Actor、ActorTemplate 以及 ate-demo-jupyter Atespace ./hack/install-ate-kind.sh --delete-demo-jupyter # 卸载整个本地 Kind 集群 ./hack/delete-kind-cluster.sh小结与扩展思路通过本 Demo 你可以确认标准 Jupyter 镜像无需改造即可成为可挂起/恢复的 Substrate Actor挂起释放资源、访问自动恢复特别适合用完即走的交互式计算环境。在此基础上可进一步探索修改snapshotsConfig.storageLocation指向真实 GCS Bucket将快照持久化到集群外调整onPause/onCommit作用域如仅快照数据卷而非全量内容权衡恢复速度与存储成本参考 sandbox 与 egress 等 Demo将同一 Actor 模型扩展到 CLI 应用与网络出口场景。【免费下载链接】substrateAgent Substrate: the core system项目地址: https://gitcode.com/GitHub_Trending/substrate7/substrate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价