Cua Fleet 中用 Terraform 管理 fleets_pool:静态与自动扩缩容沙箱池的完整实践

Cua Fleet 中用 Terraform 管理 fleets_pool:静态与自动扩缩容沙箱池的完整实践 Cua Fleet 中用 Terraform 管理 fleets_pool静态与自动扩缩容沙箱池的完整实践【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cuafleets_pool是 Cua Fleet Terraform Provider 的核心资源一条声明即可创建一组预热的 computer-use 沙箱池OSGymSandboxWarmPool、其引用的沙箱模板OSGymSandboxTemplate以及同名 Kubernetes 命名空间。读完本文你能掌握静态池与自动扩缩容池两套完整配置、全部参数含默认值与互斥校验规则的语义、terraform import纳管方式以及该资源在 Provider 源码中如何映射到 Fleet API 与底层 CRD。fleets_pool 是什么一条资源对应一对 CR 加一个命名空间Fleet 面向 computer-use 场景把预热好的虚拟桌面/容器沙箱抽象为两个原生 Kubernetes 自定义资源Terraform 侧用一个扁平的fleets_pool资源把它们打包管理。官方文档 pool.md 对资源的定义是Creates anOSGymSandboxWarmPool, theOSGymSandboxTemplateit references (namedpool-template), and their same-named namespace. Destroy removes all three. Import IDs are pool names.也就是说每个fleets_pool在集群里落地为三个对象与池同名的命名空间namespace与池同名的OSGymSandboxWarmPool该 WarmPool 引用的、固定命名为pool-template的OSGymSandboxTemplate。这个命名约定直接体现在 Provider 源码里。pool_resource.go 中定义了模板名后缀// The flat resource is backed by an OSGymSandboxWarmPool and the // OSGymSandboxTemplate it references, both named after the pool. const templateNameSuffix -template创建顺序上WarmPool 拥有两者所在的命名空间所以必须先建池、再向该命名空间写入模板。这一依赖关系在Create方法的实现pool_resource.go#L117-L152中写得很直白// The warm pool owns the namespace both objects live in, so it has to exist // before the template can be posted into that namespace. created, err : r.client.CreatePool(poolRequest) ... if _, err : r.client.CreateTemplate(templateRequest); err ! nil { if deleteErr : r.client.DeletePool(created); deleteErr ! nil { resp.Diagnostics.AddWarning(Fleet pool was left behind, deleteErr.Error()) } ... }值得注意的健壮性细节若模板创建失败Provider 会尝试回滚已创建的池避免残留孤儿资源而Delete则按相反顺序执行——先删模板、再删池删除池会连带删除模板所在的命名空间见 pool_resource.go#L228-L243。底层 CRD 的类型定义位于 warmpool.rs声明了 API grouposgym.cua.ai/v1alpha1、kindOSGymSandboxWarmPool、短名oswp并通过scale(...)属性暴露/scale子资源spec.replicas/status.replicas这正是自动扩缩容可以驱动副本数的机制基础。仓库中另有一份自包含的最小 CRD 夹具 osgym-pool-crd.yaml用于 RBAC e2e 测试时注册osgymsandboxwarmpools.osgym.cua.ai与osgymsandboxtemplates.osgym.cua.ai两个自定义资源定义。安装与认证Provider 源码地址为trycua/fleets在 Terraform 配置中声明后执行terraform init即可从 Registry 安装见 README.mdterraform { required_providers { fleets { source trycua/fleets version 0.2.0 } } }Provider 使用与 Fleet Python SDK、Dashboard 相同的用户级 key OAuth 凭据和租户级授权。在 Cua 中创建用户 API key 后把返回的client_id、client_secret和token_url配置给 Provider短生命周期场景也可以直接提供access_token。所有 Provider 参数都支持环境变量形式CYCLOPS_ENDPOINTCYCLOPS_ACCESS_TOKENCYCLOPS_CLIENT_IDCYCLOPS_CLIENT_SECRETCYCLOPS_TOKEN_URL静态池固定副本数的预热池最简单的形态是给池设定一个固定的期望副本数replicas池内维持恒定数量的预热沙箱resource fleets_pool linux_static { name training-linux-static replicas 3 cpu_cores 4 memory 8Gi container_disk_image public.ecr.aws/k5j5w0x5/cua-ubuntu-24.04:main-e5d853a9 }各字段的落点可以结合 pool_mapping.json 看出replicas映射到 WarmPool 的spec.replicascpu_cores、memory、container_disk_image等则写入模板的spec.vmTemplate.*路径——因为沙箱规格CPU/内存/磁盘镜像属于每个沙箱长什么样的模板语义而副本数属于池子有多大的池语义。自动扩缩容池由 Claim 需求驱动的弹性池当沙箱被业务申领claim时才需要副本可以用autoscaling块替代replicasresource fleets_pool linux_autoscaled { name training-linux-autoscaled cpu_cores 4 memory 8Gi container_disk_image public.ecr.aws/k5j5w0x5/cua-ubuntu-24.04:main-e5d853a9 autoscaling { min_pool_size 0 initial_pool_size 3 max_pool_size 20 } }replicas与autoscaling恰好配置其一否则 plan 阶段就会报错。这不是文档上的口头约定而是 Provider 在ValidateConfig中强制执行的校验pool_resource.go#L78-L98func validatePoolScalingModeDuringPlan(config poolResourceModel) error { if config.Replicas.IsUnknown() || config.Autoscaling.IsUnknown() { return nil } if config.Replicas.IsNull() config.Autoscaling.IsNull() { return errors.New(poolScalingModeExactlyOneMessage) } return nil }其中poolScalingModeExactlyOneMessage exactly one of replicas or autoscaling must be configured。同样的校验在 apply 阶段Create/Update 入口还会再执行一次防止 plan 期 unknown 值解析后出现两者同时存在或同时缺失的情况。从 CRD schema 的字段描述warmpool.rs#L42-L67可以看到三个参数的精确语义min_pool_size对应 ScaledObject 的minReplicaCount是自动扩缩容启用期间持久保留的温地板设为0允许池在无 claim 时缩容到零initial_pool_size一次性预热头部——池创建时 pool-operator 会把spec.replicas播种为该值让第一批 claim 不必冷启动随后spec.replicas归 KEDA 所有随着真实 claim 需求向需求值收敛不低于min_pool_sizemax_pool_size对应maxReplicaCount的硬性上限。Terraform Provider 侧对max_pool_size缺省值的处理在 pool_resource.go#L300-L313maxPoolSize : defaultMaxPoolSize // const defaultMaxPoolSize uint32 50 if !autoscalingValue.MaxPoolSize.IsNull() !autoscalingValue.MaxPoolSize.IsUnknown() { maxPoolSize uint32(autoscalingValue.MaxPoolSize.ValueInt64()) } ... if objectValue(ctx, m.Autoscaling, autoscalingValue, diagnostics) { ... replicas initialPoolSize }即max_pool_size省略时默认50与 warmpool.rs 中default_max_pool_size()返回Some(50)一致且只要配置了autoscaling提交给 API 的spec.replicas会被设置为initial_pool_size作为自动扩缩容接管前的初始目标。从源码结构看spec.autoscaling字段的存在本身就开启了自动扩缩容扩展pool-operator 会管理一个 KEDA ScaledObject通过/scale子资源按存活 claim 数Pending Bound发布为osgym_pool_claim_demand驱动spec.replicas——Pending claim 代表未满足的需求使池增长删除 claim 则使池收缩drain-safe字段缺省即为普通静态热池。参数全集Arguments以下参数表完整继承自 pool.md默认值与枚举取值已与 pool_resource.go 和 pool_mapping.json 对照核实参数说明默认值 / 约束name池与命名空间共用的 DNS label必填修改将触发资源替换requires_replacereplicas静态模式下期望的预热池规模与autoscaling二选一自动扩缩容模式下不要配置apply 并刷新后它报告当前池目标cpu_cores每个沙箱的虚拟 CPU 数必填写入模板spec.vmTemplate.cpuCoresmemory每个沙箱的 Kubernetes 内存量如8Gi必填写入模板spec.vmTemplate.memorycontainer_disk_imageOCI containerDisk 或运行时镜像必填image_pull_secret镜像拉取凭据省略时默认ecr-credentialsruntime沙箱运行时kubevirt、macos、gvisor默认kubevirtfirmware固件bios或efi默认biosreadiness_probe_json/liveness_probe_json以 JSON 字符串编码的 Kubernetes 探针对象可选无效 JSON 会在 apply 前报错service可重复的 service 块含name、target_port与可选protocol协议省略时按TCP处理autoscalingClaim 驱动的自动扩缩容限额与replicas二选一autoscaling.min_pool_size自动扩缩容启用时的最小池规模0 表示允许缩容到零autoscaling.initial_pool_size自动扩缩容启动时的初始池目标作为创建时的spec.replicas播种值autoscaling.max_pool_size自动扩缩容的池规模上限省略时默认50默认值在源码中的对应位置toSDKTemplateSpecpool_resource.go#L321-L363中image_pull_secret为空时回填ecr-credentialsruntime仅在macos/gvisor时显式设置、其余回落kubevirtfirmware仅在efi时设置、其余回落biosservice的protocol非UDP时一律按TCP提交。这些只传非默认值的写法与回读侧runtimeString/firmwareString/serviceProtocolString的归一化逻辑pool_resource.go#L504-L526配合保证省略默认项的声明与从 API 读回的状态不产生 diff。探针参数采用jsontypes.Normalized归一化 JSON提交前 Provider 会用json.Unmarshal校验 JSON 合法性decodeProbepool_resource.go#L546-L556两个探针合并进模板spec.vmTemplate.probes的readinessProbe/livenessProbe键回读时再反解为 Terraform 状态实现无损的 JSON 透传。只读属性观察池的实时规模文档列出的只读属性为namespace、template_name以及自动扩缩容模式下作为状态报告用途的replicas再加current_replicas和ready_replicas。namespace与template_name标识 Fleet 创建的对象——前者恒等于name后者为 WarmPoolspec.sandboxTemplateRef.name读回的实际模板名通常是pool-template自动扩缩容模式下replicas报告当前池目标让扩缩容变化在 Terraform state 中可见current_replicas/ready_replicas报告当前实际拥有与已就绪的沙箱数。回读逻辑在fromSDKPoolpool_resource.go#L413-L437replicas、autoscaling直接取speccurrent_replicas/ready_replicas取status.replicas/status.readyReplicasStatus 为 nil 时归零。这与 CRD 上的 scale 子资源声明spec_replicas_path .spec.replicas、status_replicas_path .status.replicaswarmpool.rs#L89-L93以及kubectl打印列Replicas/Ready是同一套口径所以 Terraform 状态与kubectl get osgym看到的数字天然一致。更新、漂移修复与导入Update路径pool_resource.go#L185-L226按属性归属分成两段池属性replicas、autoscaling、模板引用变化时调UpdatePool模板属性cpu_cores、memory、镜像、探针、service 等变化时调ReconcileTemplate而非 patch——源码注释解释了原因模板若在带外被删除reconcile 能把它恢复出来而不是让 apply 失败。任何写操作完成后Provider 都会refresh一次重新读取池和模板确保 state 反映集群真实状态。对于集群中已存在的池用池名作为 Import ID 纳管terraform import fleets_pool.linux training-linuxImportState实现pool_resource.go#L245-L249会把导入 ID 同时写入id、name、namespace三个属性因为三者取值相同随后一次terraform plan即可从集群读回完整状态。若池在集群中被删除Read检测到 404 后会直接把资源从 state 中移除而不是报错resp.State.RemoveResource(ctx)。生成式 Providerschema 从哪里来fleets_pool的 Terraform 模型、schema、CRD 派生的描述、枚举校验器、数值校验器与嵌套对象类型都是确定性生成的见 README.md生产 CRD bundleREADME 中指明为clusters/base/osgym/crd.yaml读取osgymsandboxwarmpools.osgym.cua.ai与osgymsandboxtemplates.osgym.cua.ai的v1alpha1schemapool_mapping.json——显式的 CRD 到 Terraform 形态映射每个属性都标注其所属 CRcr: warmpool或cr: template与 CRD 路径如crd_path: spec.vmTemplate.cpuCores。执行go generate ./...重新生成 pool_generated.goCI 会重新生成并在漂移时失败。而 CRUD、命名空间所有权、导入行为、默认值归一化与 API 错误处理仍保留在手工维护的 pool_resource.go 中——这种schema 生成 行为手写的分工保证了 Terraform 属性与 CRD 字段不会静默失配。小结fleets_pool用一个扁平资源封装了命名空间 预热池 沙箱模板三件套的生命周期静态模式用replicas固定规模自动扩缩容模式用autoscaling的 min/initial/max 三个参数交给 Claim 需求驱动上限默认 50模板侧的cpu_cores、memory、container_disk_image、runtime默认kubevirt、firmware默认bios、image_pull_secret默认ecr-credentials、探针与 service 都有明确的默认值与校验行为。结合 pool.md 的声明式示例、pool_resource.go 的 CRUD 实现与 warmpool.rs 的 CRD 定义你可以把 computer-use 沙箱池像普通基础设施一样纳入 Terraform 的 plan/apply/import 流程。【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考