本文介绍如何在创建Agent Sandbox时为沙箱挂载OSS及NAS静态存储卷。
前提条件
已完成Agent Sandbox的基础环境搭建,具体操作,请参见创建Agent Sandbox。
在集群组件管理中,确认
ack-agent-sandbox-controller组件版本为v0.5.12及以上。安装组件时,在
sandbox-system命名空间下会自动创建名为sandbox-injection-config的ConfigMap,包含agent-runtime和csi两个配置项。如需特殊定制或配置修改,请在修改前联系阿里云技术支持评估配置的完备性。
在集群组件管理中,确认
ack-sandbox-manager组件版本为v0.5.2及以上。
启用动态存储挂载功能,需要为容器开放特权容器(Privileged Container)和宿主机路径(hostPath,/var/run/csi)的容器安全验证,可以提交工单放开限制,但由此带来的安全风险需要用户承担一定责任,相关机制请参见安全责任共担模型。
使用限制
支持基于E2B的
Create接口、休眠/唤醒功能以及原地升级镜像后的运行时存储挂载,但目前不支持基于Checkpoint机制创建快照后恢复存储挂载。目前OSS静态存储挂载仅支持AccessKey鉴权方式。
在配置网络策略或流量策略时,请务必确保已放行访问 OSS/NAS 管控端点的出方向流量。
挂载共享存储
ACS支持在Sandbox运行时为其挂载存储卷(PV),如阿里云OSS、NAS等。此功能依赖agent-runtime组件,您可以通过E2B SDK(如Sandbox.create、Sandbox.beta_create接口)或SandboxClaim对象两种方式触发挂载。
步骤一:配置存储挂载能力
ACS提供动态注入Sidecar的配置方案。您只需在SandboxSet或Sandbox对象上设置spec.runtimes参数,框架会在Sandbox被创建时自动注入所需的CSI配置,包括agent-runtime和存储相关的CSI Sidecar配置。
以下为SandboxSet配置示例:
apiVersion: agents.kruise.io/v1alpha1
kind: SandboxSet
metadata:
name: code-interpreter-inject-test
namespace: default
spec:
runtimes:
- name: csi # 启用CSI挂载能力,新建的Sandbox会被注入对应的Sidecar
- name: agent-runtime # 注入envd等环境管理工具
replicas: 4
template:
metadata:
labels:
alibabacloud.com/acs: "true"
alibabacloud.com/compute-class: agent-sandbox # Agent Sandbox 实例类型
alibabacloud.com/compute-qos: default # 算力质量 default/best-effort
spec:
automountServiceAccountToken: false
containers:
- image: registry-cn-zhangjiakou-vpc.ack.aliyuncs.com/acs/code-interpreter:v1.6
imagePullPolicy: IfNotPresent
name: sandbox
resources:
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: "1"
memory: 1Gi
terminationGracePeriodSeconds: 30以下为Sandbox对象的配置示例:
apiVersion: agents.kruise.io/v1alpha1
kind: Sandbox
metadata:
name: code-interpreter-inject-test-xxx
namespace: default
spec:
runtimes:
- name: csi # 提供CSI挂载能力
- name: agent-runtime # 注入envd等环境管理工具
...步骤二:创建存储卷
根据您的存储需求,在集群中创建对应的PV对象。以下分别介绍OSS和NAS静态存储卷的创建方法。
创建OSS存储卷
创建一份描述OSS的PersistentVolume对象和对应的访问密钥Secret对象。更多信息,请参见使用OSS静态存储卷。
apiVersion: v1
kind: Secret
metadata:
name: oss-secret
# 密钥对象必须创建在sandbox-system命名空间
namespace: sandbox-system
stringData:
akId: <YOUR_ACCESS_KEY_ID> # 访问OSS的AccessKey ID
akSecret: <YOUR_ACCESS_KEY_SECRET> # 访问OSS的AccessKey Secret
---
apiVersion: v1
kind: PersistentVolume
metadata:
labels:
alicloud-pvname: oss-pv-sandbox-system
name: oss-pv-sandbox-system
spec:
accessModes:
- ReadWriteMany
capacity:
storage: 50Gi
csi:
driver: ossplugin.csi.alibabacloud.com
nodePublishSecretRef:
name: oss-secret
namespace: sandbox-system
volumeAttributes:
bucket: <OSS_BUCKET> # 替换为OSS中实际的Bucket名称
otherOpts: -o umask=022 -o allow_other
url: <OSS_ENDPOINT> # OSS访问端点,请替换为实际OSS Endpoint地址
volumeHandle: oss-pv-sandbox-system
persistentVolumeReclaimPolicy: Retain
storageClassName: test
volumeMode: Filesystem创建NAS存储卷
进入NAS存储接入点页面,复制接入点域名,替换以下<YOUR_NAS_ACCESS_POINT>。更多信息,请参见使用NAS静态存储卷。
apiVersion: v1
kind: Secret
metadata:
name: ap-secret
# 密钥对象必须创建在sandbox-system命名空间
namespace: sandbox-system
stringData:
akId: <YOUR_ACCESS_KEY_ID> # 访问NAS的AccessKey ID
akSecret: <YOUR_ACCESS_KEY_SECRET> # 访问NAS的AccessKey Secret
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nas-pv-sandbox-system
spec:
accessModes:
- ReadWriteMany
capacity:
storage: 50Gi
csi:
nodePublishSecretRef:
name: ap-secret
namespace: sandbox-system
driver: nasplugin.csi.alibabacloud.com
volumeHandle: nas-pv-sandbox-system
volumeAttributes:
accessPoint: <YOUR_NAS_ACCESS_POINT> # 接入点域名
path: / # 需要挂载的接入点子目录,最终挂载的路径为 [接入点根目录]/[path]
mountOptions:
- nolock,tcp,noresvport,tls,ram # 默认配置 accessPoint 需要开启 RAM 鉴权
- vers=3 # 暂不支持vers=4.0配置步骤三:挂载存储卷
根据您的使用场景,选择以下任一方式将存储卷挂载到Sandbox。
通过E2B SDK挂载
挂载单个存储卷
您可以参考以下Python代码,从预热池中获取Sandbox后,将存储卷挂载到沙箱内的指定目录。
为了获得更好的扩展性及对未来新特性的持续支持,建议优先使用挂载多个存储卷方式进行存储挂载,后续新特性将不再支持单存储卷挂载方式(e2b.agents.kruise.io/csi-volume-name)。挂载OSS存储卷示例
from e2b_code_interpreter import Sandbox
sbx = Sandbox.create(template="code-interpreter-inject-test", timeout=300, metadata={
"e2b.agents.kruise.io/csi-volume-name": "oss-pv-sandbox-system", # OSS的PersistentVolume名称
"e2b.agents.kruise.io/csi-mount-point": "/data-oss", # 挂载路径必须为一个空目录,否则将导致挂载失败。
"e2b.agents.kruise.io/csi-subpath": "data-subPath" # 相对路径,表示在OSS Bucket内的相对子目录
})挂载NAS存储卷示例
from e2b_code_interpreter import Sandbox
sbx = Sandbox.create(template="code-interpreter-inject-test", timeout=300, metadata={
"e2b.agents.kruise.io/csi-volume-name": "nas-pv-sandbox-system",
"e2b.agents.kruise.io/csi-mount-point": "/data-nas", # 挂载路径必须为一个空目录,否则将导致挂载失败。
"e2b.agents.kruise.io/csi-subpath": "data-subPath" # 相对路径,必须为已存在的 NAS 目录
})如遇504响应问题,请前往修改sandbox-injection-config,将csi-agent 镜像地址替换为registry-cn-zhangjiakou-vpc.ack.aliyuncs.com/acs/csi-agent:v1.35.4-3c34d4a-aliyun,再重新创建Sandbox即可。metadata参数说明如下:
参数 | 说明 |
| 指定PersistentVolume对象的名称。 |
| 指定存储卷在容器内的挂载目录。 重要 挂载路径必须为一个空目录,否则将导致挂载失败。 |
| 指定存储卷在远端存储内的子目录名(相对路径)。 |
挂载多个存储卷
如果需要一次挂载多个存储卷,可以使用e2b.agents.kruise.io/csi-volume-config参数,通过JSON数组格式指定多个挂载配置。
若同时配置了e2b.agents.kruise.io/csi-volume-config(新协议)和单卷挂载参数(旧协议),新协议的优先级高于旧协议。以下为同时挂载多个存储卷的Python代码示例:
from e2b_code_interpreter import Sandbox
sbx = Sandbox.create(template="code-interpreter-inject-test", timeout=600, metadata={
"e2b.agents.kruise.io/csi-volume-config": '[{"pvName":"nas-pv-sandbox-system","mountPath":"/data-nas","subPath":"data-subPath"},{...}]'
})
print(f"sandbox id: {sbx.sandbox_id}")csi-volume-config相关配置说明如下:
字段 | 类型 | 说明 |
| String | PersistentVolume对象名称。 |
| String | 期望挂载到容器内的目录路径。 |
| String | 远端存储的子目录名(相对路径),可选。 |
| Boolean | 是否以只读方式挂载,可选,默认为false。 |
通过SandboxClaim挂载
SandboxClaim方式适用于通过Claim对象从预热的SandboxSet中分配Sandbox的场景。您可以在SandboxClaim对象上直接声明动态挂载的存储卷配置,被分配的Sandbox将自动按该配置完成挂载。
创建SandboxClaim对象
在SandboxClaim对象的spec.dynamicVolumesMount字段中声明需要挂载的存储卷。Claim完成后,被分配的Sandbox将自动按照该配置挂载存储卷。以下为同时挂载多个存储卷的YAML示例:
apiVersion: agents.kruise.io/v1alpha1
kind: SandboxClaim
metadata:
name: code-interpreter-claim # SandboxClaim名称
namespace: default # 命名空间
spec:
templateName: code-interpreter-inject-test # 关联的SandboxSet名称
replicas: 1 # 期望从SandboxSet内Claim的Sandbox数量
claimTimeout: 5m # Claim超时时间
ttlAfterCompleted: 15m # Claim完成后的TTL
dynamicVolumesMount: # 动态挂载的存储卷列表
- pvName: oss-pv-sandbox-system # 对应的PersistentVolume名称
mountPath: "/data-oss" # 容器内期望挂载的目录路径
subPath: "data-subPath" # 远端存储的子目录,替换为实际的目录名称
readOnly: true # 是否以只读方式挂载
- pvName: nas-pv-sandbox-system
mountPath: "/data-nas"
subPath: "data-subPath"
readOnly: falsedynamicVolumesMount字段说明如下:
字段 | 类型 | 说明 |
| String | PersistentVolume对象名称。 |
| String | 期望挂载到容器内的目录路径。 |
| String | 远端存储的子目录名(相对路径),可选。 |
| Boolean | 是否以只读方式挂载,可选,默认为false。 |
验证挂载结果
SandboxClaim创建成功后,其status状态变为Completed即表示Claim与挂载流程已完成。
您可以通过以下命令查询SandboxClaim分配出的Sandbox。每个被Claim的Sandbox会自动带上agents.kruise.io/claim-name标签,标签值为SandboxClaim的名称。
kubectl get sandbox -n default -l agents.kruise.io/claim-name=code-interpreter-claim预期输出:
NAME STATUS AGE SHUTDOWN_TIME PAUSE_TIME MESSAGE
code-interpreter-inject-test-6vh94 Running 22h替换以下<POD_NAME>查看dynamicVolumesMount中配置的OSS挂载目录。
kubectl exec -it <POD_NAME> -- ls -al / | grep oss预期输出:
lrwxrwxrwx 1 root root 56 Apr 21 11:15 data-oss -> /run/csi/mount-root/oss/f69ed0682da41xxxxxxx80bf6fe851d69