ACK One 舰队支持在多个集群间统一管理和调度 Agent Sandbox。本文介绍ACK One 舰队管理 Agent Sandbox的能力,以及部分操作示例,包括 SandboxSet 的多集群分发与差异化配置、SandboxClaim 的多集群调度、通过 E2B SDK 接入 Agent Sandbox 等。
背景信息
Agent Sandbox是面向生产级 AI 智能体的沙箱算力。ACK One 舰队提供对多集群Agent Sandbox 的统一管理能力,支持以下调度特性:
多集群Agent Sandbox是ACK One多集群舰队面向生产级AI智能体提供的多集群沙箱算力方案。它在单集群Agent Sandbox的基础上,通过一个统一的多集群管理平面(Fleet)管理多个ACK集群,突破单集群在容量、故障域上的上限,并借助多集群调度能力提升资源利用率与Sandbox启动效率。
单集群容量控制:每个子集群配置最大可运行 Sandbox 数量(Capacity),超出上限后调度器自动调度到其他尚有容量的集群,防止单集群过载。
水位均衡调度:默认根据各集群当前 Sandbox 使用水位进行均衡分配,充分利用多集群资源。
集群优先级调度:支持将集群划分为优先级分组,优先将 Sandbox 调度到指定集群组,资源不足时自动降级到下一优先级。
多集群故障转移:当某集群出现异常或进入维护状态时,新建的 Sandbox 和 SandboxClaim 会自动调度到其他健康集群,无需人工干预。
E2B 协议接入:舰队提供面向 E2B 协议的 Multi-Cluster Gateway 统一入口与多集群调度能力,您可以通过 E2B SDK 在多个集群间创建和使用 Sandbox,无需感知 Sandbox 所在的具体集群。
准备工作
在ACK One控制台获取舰队的 KubeConfig,并通过 kubectl 连接到舰队。
参见管理关联集群,为舰队添加至少两个关联集群。
参见安装组件,在所有关联集群中安装 Agent Sandbox 相关组件。
重要ack-agent-sandbox-controller 组件版本需为 v0.5.13-release.1或更高。安装该组件时,请在 FeatureGate 中配置
SandboxMultiClusterNaming=true,以确保 Sandbox ID 在多集群间唯一。说明如需使用多集群 Agent Sandbox 的 E2B 能力,在多个子集群中安装 ack-sandbox-manager 组件时,请为每个集群配置不同的 E2B domain。
安装AMC命令行帮助工具。
步骤一:通过 SandboxSet 创建 Sandbox 预热池
将下方示例保存到sandbox-set.yaml,然后执行
kubectl apply -f sandbox-set.yaml,在舰队中创建 SandboxSet。SandboxSet 定义了 Sandbox 的模板和期望的可用副本数。
apiVersion: agents.kruise.io/v1alpha1 kind: SandboxSet metadata: name: code-interpreter spec: persistentContents: - filesystem replicas: 4 runtimes: - name: csi - name: agent-runtime scaleStrategy: {} template: metadata: labels: alibabacloud.com/acs: "true" alibabacloud.com/compute-class: agent-sandbox alibabacloud.com/compute-qos: default spec: automountServiceAccountToken: false containers: - image: registry-cn-zhangjiakou.ack.aliyuncs.com/acs/code-interpreter:v1.6 imagePullPolicy: IfNotPresent name: sandbox resources: limits: cpu: "1" memory: 1Gi requests: cpu: "1" ephemeral-storage: 30Gi memory: 1Gi restartPolicy: Always updateStrategy: maxUnavailable: 20%将下方示例保存到code-interpreter-pp.yaml,然后执行
kubectl apply -f code-interpreter-pp.yaml。创建 SandboxSet 时,同时需要创建 PropagationPolicy 资源,通过
spec.placement.replicaScheduling.replicaSchedulingType字段指定 SandboxSet 分发到关联集群的规则。spec.resourceSelectors.kind配置为SandboxSet时,replicaSchedulingType目前仅支持Duplicated选项,即每个关联集群都会创建一份完整的 SandboxSet 副本。preserveResourcesOnDeletion设为false时,删除舰队上的资源会同步清理子集群上的资源。如需保留子集群资源,请设置为true。apiVersion: policy.one.alibabacloud.com/v1alpha1 kind: PropagationPolicy metadata: name: code-interpreter-pp spec: preserveResourcesOnDeletion: false resourceSelectors: - apiVersion: agents.kruise.io/v1alpha1 kind: SandboxSet placement: replicaScheduling: replicaSchedulingType: Duplicated查看舰队中所有关联集群的 SandboxSet 状态(聚合显示)。
kubectl get sandboxset预期输出:
NAME REPLICAS AVAILABLE UPDATEDREPLICAS UPDATEDAVAILABLEREPLICAS UPDATEREVISION AGE code-interpreter 8 8 8 8 74bfb6****查看不同关联集群中的 SandboxSet 状态。
kubectl amc get sandboxset -M预期输出:
NAME CLUSTER CLUSTER_ALIAS REPLICAS AVAILABLE UPDATEDREPLICAS UPDATEDAVAILABLEREPLICAS UPDATEREVISION AGE ADOPTION code-interpreter <cluster-id-1> sandbox-cluster1 4 4 4 4 56fc44**** 5d Y code-interpreter <cluster-id-2> sandbox-cluster2 4 4 4 4 74bfb6**** 5d Y(可选)使用 OverridePolicy 为不同集群指定不同的 SandboxSet 副本数和资源规格。
以下示例为名为
code-interpreter的 SandboxSet 在两个集群中分别配置了不同的副本数量和规格:CLUSTER_1_ID:5 副本,1CPU、2GiB 内存配置。CLUSTER_2_ID:2 副本,2CPU、4GiB 内存配置。
将下方示例保存到code-interpreter-op.yaml,然后执行
kubectl apply -f code-interpreter-op.yaml。OverridePolicy 通过 JSON Patch 路径精确定位需要覆盖的字段。
/spec/replicas覆盖副本数配置,/spec/template/spec/containers/0/resources覆盖容器资源配置。apiVersion: policy.one.alibabacloud.com/v1alpha1 kind: OverridePolicy metadata: name: code-interpreter-op spec: resourceSelectors: - apiVersion: agents.kruise.io/v1alpha1 kind: SandboxSet name: code-interpreter overrideRules: - targetCluster: clusterNames: - CLUSTER_1_ID overriders: plaintext: - operator: replace path: /spec/replicas value: 5 - path: /spec/template/spec/containers/0/resources operator: add value: requests: cpu: "1" memory: "2Gi" limits: cpu: "1" memory: "2Gi" - targetCluster: clusterNames: - CLUSTER_2_ID overriders: plaintext: - operator: replace path: /spec/replicas value: 2 - path: /spec/template/spec/containers/0/resources operator: add value: requests: cpu: "2" memory: "4Gi" limits: cpu: "2" memory: "4Gi"
步骤二:使用 Agent Sandbox
完成 Sandbox 预热池创建后,您可以通过以下任一方式使用 Agent Sandbox:
SandboxClaim 方式:从预热池中申请 Sandbox 实例,通过 Kubernetes 原生的方式管理和使用,适用于基于 kubectl/CRD 的集群内使用场景。
E2B SDK 方式:通过 E2B SDK 经由舰队的 Multi-Cluster Gateway 创建和使用 Sandbox,适用于 AI Agent 应用开发场景。
E2B SDK 方式
Agent Sandbox 支持对接 E2B 生态。开启多集群 Agent Sandbox E2B 能力后,舰队提供统一的 Multi-Cluster Gateway 入口和多集群调度能力,客户端可以通过 E2B SDK 创建、连接并使用 Sandbox,无需感知 Sandbox 所在的后端集群。
获取 Agent Sandbox
Sandbox 支持通过 E2B SDK 在平台上开发、部署项目并查看效果,包括执行代码(run_code)、读写文件(files.write/files.read)、运行命令(commands.run)等操作。更多 SDK 使用说明,请参见使用 E2B SDK 接入 Agent Sandbox。
使用 E2B 能力前,请先完成步骤一(配置多集群 Agent Sandbox E2B 能力)中的所有配置以及步骤二(通过 SandboxSet 创建 Sandbox 预热池)。
在本地环境中安装 Python。
安装 E2B Python SDK(仅支持小于 v2.25.0 的版本)。
pip install "e2b-code-interpreter==2.7.0" "e2b==2.24.0"配置环境变量。
# your.domain.com 是安装 ack-sandbox-manager 组件时配置的域名,不需要带 *,可按实际配置修改 export E2B_DOMAIN=fleet.your.domain.com # 使用默认生成或更新后的 Fleet Admin API Key export E2B_API_KEY=e2b_0000000000000000000000000000000000000000将以下代码保存为
main.py文件。# Import the E2B SDK from e2b_code_interpreter import Sandbox sbx: Sandbox = Sandbox.create(template="code-interpreter") print(f"sandbox id: {sbx.sandbox_id}") result = sbx.run_code("print('hello, world')") print(f"run code result: {result}") text = input("enter some text to be saved to file 'text.txt' inside sandbox: ") sbx.files.write("text.txt", text) print(f"read file from sandbox via files api: [{sbx.files.read('text.txt')}]") print(f"read file from sandbox via commands api: [{sbx.commands.run('cat text.txt')}]") input("press ENTER to kill the sandbox") print(sbx.kill())create接口metadata参数说明,请参见创建Agent Sandbox。运行
main.py文件,创建并验证 Sandbox。在第一次出现提示后,输入文字如
acs agent sandbox,然后按 ENTER 键,会在名为code-interpreter-29***的 Pod 的/home/user/text.txt文件中写入acs agent sandbox;若再次按 ENTER 键,则会删除当前 Sandbox。python main.py预期输出:
sandbox id: default--code-interpreter-29*** run code result: Execution(Results: [], Logs: Logs(stdout: ['hello, world\n'], stderr: []), Error: None) enter some text to be saved to file 'text.txt' inside sandbox: acs agent sandbox read file from sandbox via files api: [acs agent sandbox] read file from sandbox via commands api: [CommandResult(stderr='', stdout='acs agent sandbox', exit_code=0, error='')] press ENTER to kill the sandbox True
SandboxClaim 方式
在多集群中进行 SandboxClaim 的分发与调度
SandboxClaim 用于从已创建的 SandboxSet 中申请 Sandbox 实例,使用 PropagationPolicy 可以控制 SandboxClaim 在多集群间的调度方式。
将下方示例保存到sandbox-claim.yaml,然后执行
kubectl apply -f sandbox-claim.yaml。apiVersion: agents.kruise.io/v1alpha1 kind: SandboxClaim metadata: name: code-interpreter namespace: default spec: templateName: code-interpreter replicas: 1 claimTimeout: 5m ttlAfterCompleted: 5m根据需求选择调度方式:
Gang调度:会自动选择一个关联集群,将 SandboxClaim 里请求的所有副本调度到该集群。
集群优先级调度:为集群设置调度优先级,调度器会选择优先级较高的集群,将 SandboxClaim 里请求的所有副本调度到该集群。当高优先级集群资源不足时,则会自动降级到低优先级集群。
重要请勿为同一个SandboxClaim资源配置不同的PropagationPolicy。
基本调度(Gang 调度):会自动选择一个关联集群,将 SandboxClaim 里请求的所有副本调度到该集群。操作如下:
将下方示例保存到sandboxclaim-pp.yaml,然后执行
kubectl apply -f sandboxclaim-pp.yaml。apiVersion: policy.one.alibabacloud.com/v1alpha1 kind: PropagationPolicy metadata: name: sandboxclaim-pp spec: preserveResourcesOnDeletion: false resourceSelectors: - apiVersion: agents.kruise.io/v1alpha1 kind: SandboxClaim placement: replicaScheduling: replicaSchedulingType: Divided customSchedulingType: Gang查看舰队上的 SandboxClaim。
kubectl get sandboxclaim预期输出:
NAME PHASE TEMPLATE DESIRED CLAIMED AGE code-interpreter Completed code-interpreter 1 1 6s查看关联集群上的 SandboxClaim。
kubectl amc get sandboxclaim -M预期输出:
NAME CLUSTER CLUSTER_ALIAS PHASE TEMPLATE DESIRED CLAIMED AGE ADOPTION code-interpreter <CLUSTER-ID> sandbox-cluster1 Completed code-interpreter 1 1 3s Y将下方命令中的
CLUSTER_ID替换为上一步骤中获取的集群ID后执行,使用 sandboxClaim name label 获取 Sandbox详情。kubectl amc get sandbox -m CLUSTER_ID -l agents.kruise.io/claim-name=code-interpreter预期输出:
NAME CLUSTER CLUSTER_ALIAS STATUS AGE CLAIMED SHUTDOWN_TIME PAUSE_TIME MESSAGE ADOPTION code-interpreter-47*** CLUSTER_ID sandbox-cluster1 Running 59m true
集群优先级调度:为集群设置调度优先级,调度器会选择优先级较高的集群,将 SandboxClaim 里请求的所有副本调度到该集群;当高优先级集群资源不足时,则会自动降级到低优先级集群。操作如下:
将下方示例保存到sandboxclaim-pp-priority.yaml,然后执行
kubectl apply -f sandboxclaim-pp-priority.yaml。spec.placement.clusterAffinities字段中声明的顺序即为调度优先级顺序。下方示例PropagationPolicy会优先调度到CLUSTER_1_ID(primary),资源不足时再调度到CLUSTER_2_ID(secondary)。apiVersion: policy.one.alibabacloud.com/v1alpha1 kind: PropagationPolicy metadata: name: sandboxclaim-pp-priority spec: preserveResourcesOnDeletion: false resourceSelectors: - apiVersion: agents.kruise.io/v1alpha1 kind: SandboxClaim placement: replicaScheduling: customSchedulingType: Gang replicaSchedulingType: Divided clusterAffinities: - affinityName: primary clusterNames: - CLUSTER_1_ID - affinityName: secondary clusterNames: - CLUSTER_2_ID查看舰队上的 SandboxClaim。
kubectl get sandboxclaim预期输出:
NAME PHASE TEMPLATE DESIRED CLAIMED AGE code-interpreter Completed code-interpreter 1 1 6s查看 SandboxClaim 是否按优先级规则部署到了 CLUSTER-1。
kubectl amc get sandboxclaim -M预期输出:
NAME CLUSTER CLUSTER_ALIAS PHASE TEMPLATE DESIRED CLAIMED AGE ADOPTION code-interpreter <CLUSTER-1-ID> sandbox-cluster1 Completed code-interpreter 1 1 3s Y将下方命令中的
CLUSTER_ID替换为上一步骤中获取的集群ID后执行,使用 sandboxClaim name label 获取 Sandbox详情。kubectl amc get sandbox -m CLUSTER_ID -l agents.kruise.io/claim-name=code-interpreter预期输出:
NAME CLUSTER CLUSTER_ALIAS STATUS AGE CLAIMED SHUTDOWN_TIME PAUSE_TIME MESSAGE ADOPTION code-interpreter-47*** CLUSTER_ID sandbox-cluster1 Running 59m true
步骤三:(可选)配置多集群故障转移(Failover)
SandboxClaim 链路与 E2B 链路的多集群故障转移机制不同,请根据您的使用方式参考对应页签进行配置。
E2B 链路
对于 E2B 场景,ACK One 舰队支持以下两种方式判定集群是否故障:
自动探测:自动探测每个子集群 Sandbox Manager 组件的健康状况。如果连续探测 3 次失败(探测间隔 5s),判定为 unhealthy;连续探测成功 2 次,判定为 healthy。
手动配置:在
sandbox-system/sandbox-e2b-scheduler-config中为集群配置disabled: true,代表运维 drain 的语义。
故障确定方式 | 说明 | 判断规则 | 效果 |
自动探测 | 周期性(探测间隔 5s)探测每个子集群 Sandbox Manager 组件的健康状况。 |
| 集群被判定为
|
手动配置 | 在 |
| 集群配置为
|
如需手动 drain 集群,请在 sandbox-e2b-scheduler-config ConfigMap 中,为对应集群配置添加 disabled: true:
apiVersion: v1
kind: ConfigMap
metadata:
name: sandbox-e2b-scheduler-config
namespace: sandbox-system
data:
config: |
...
# Fields per cluster:
# disabled — bool, optional — drain the cluster (exclude from create scheduling)
clusters:
- name: $clusterid
disabled: true
...如需手动恢复集群,请将该集群的配置修改为 disabled: false。
SandboxClaim 链路
ACK One舰队会利用OCM机制自动检测子集群与舰队之间的网络,如果出现异常(5min没有收到子集群中ocm agent心跳),则会自动为关联集群添加NoSelect污点(Taint),以将 SandboxClaim 转移到其他可用关联集群。
如需对某个关联集群进行维护,请参见下方操作,为关联集群手动添加污点:
添加和移除污点的操作影响已在该集群运行的 Sandbox 实例。
将下方命令中的
CLUSTER_ID替换为目标关联集群ID后执行,为指定集群添加污点,使调度器不再将 SandboxClaim 分配到该集群:kubectl patch managedcluster CLUSTER_ID --type=merge -p '{ "spec": { "taints": [ {"key": "maintenance", "value": "true", "effect": "NoSelect"} ] } }'集群维护完成后,执行下方命令移除污点,恢复该关联集群的调度。
kubectl patch managedcluster CLUSTER_ID --type=json -p '[{"op":"remove","path":"/spec/taints"}]'