追加挂载 Volume

更新时间:
复制 MD 格式

Sandbox 创建后,可按名称追加挂载已有 Volume,无需重新创建 Sandbox。

功能介绍

追加时只需提供 Volume 名称和 Sandbox 内的挂载目录,存储配置从 Volume 中读取。

本文介绍通过 namedVolumeMounts 追加已有 Volume 的方法。如需在请求中直接提供存储配置,请参见追加挂载 OSS、追加挂载 AgenticFS、追加挂载 AgenticBucket或追加挂载 JuiceFS。

适用范围

  • Sandbox 处于运行中(running)状态。已暂停的 Sandbox 需要先恢复运行。

  • 已准备智能体沙箱 API Key,且 API Key、Sandbox 和目标 Volume 属于同一 Team。具体操作,请参见创建 API Key。

  • 目标 Volume 已创建并处于可用状态。

  • Sandbox 已按存储类型准备所需的 RAM(Resource Access Management,访问控制)角色和网络配置。存储客户端推荐通过 Template Build 的 buildConfig.installStorageClients 自动安装,具体操作,请参见使用代码构建和管理自定义模板中的“安装存储客户端”章节。

不同存储类型对 Sandbox 的配置要求如下。客户端、存储授权和连通性要求参见对应的挂载文档。

Volume 类型

RAM 角色

VPC 配置

详细说明

OSS Volume

需要

不要求

挂载 OSS Volume

AgenticFS Volume

需要

需要

挂载 AgenticFS Volume

AgenticBucket Volume

需要

不要求

挂载 AgenticBucket Volume

JuiceFS Volume

不要求

不要求

挂载 JuiceFS Volume

追加挂载沿用 Sandbox 已有的 RAM 角色和 VPC(Virtual Private Cloud,专有网络)配置,Volume 的 mountConfig.role 和 mountConfig.vpcConfig 不会更改这些配置。对于需要 RAM 角色的存储,Sandbox 已有角色必须具备访问新增存储的权限。单个 Volume、多个 Volume 及创建后追加挂载的角色配置方法,参见配置 RAM 角色。

访问需要 VPC 的存储时,Sandbox 必须已配置 vpcId、securityGroupId 和 vSwitchIds(至少包含一个交换机 ID),且能够访问目标存储。缺少所需角色或 VPC 配置时,需要重新创建 Sandbox 后再挂载。

操作步骤

步骤一:安装 SDK

示例使用 httpx 调用追加挂载接口,成功后通过 E2B SDK 连接已有 Sandbox,验证文件读写。

pip install e2b==2.31.0 httpx

步骤二:追加挂载

接口与参数

POST /sandboxes/{sandboxID}/fc-volume-mounts

请求使用 X-API-Key 鉴权,Content-Type 为 application/json。通过 namedVolumeMounts 追加已有 Volume 时,请求参数如下。

参数

类型

是否必填

说明

namedVolumeMounts

对象数组

是

本次需要追加的 Volume 列表,至少包含一项。

namedVolumeMounts[].name

字符串

是

当前 Team 中的 Volume 名称,不是 Volume ID。

namedVolumeMounts[].path

字符串

是

Sandbox 内的本地挂载目录,不是存储服务中的远端目录。

接口成功时返回 204 No Content,响应体为空。

环境变量说明

环境变量

用途

取值来源或填写方式

E2B_API_KEY

调用智能体沙箱接口的 API Key。

在智能体沙箱控制台获取,使用目标 Team 的 API Key。

E2B_API_URL

智能体沙箱 E2B API 地址。

填写 https://api.<REGION>.sandbox.aliyuncs.com,地域与目标 Sandbox 一致。

E2B_DOMAIN

SDK 访问 Sandbox 的域名。

填写 <REGION>.sandbox.aliyuncs.com,与 API 地址使用相同地域,不含协议或 api. 前缀。

SANDBOX_ID

接收追加挂载请求的 Sandbox ID。

从创建 Sandbox 的响应或 Sandbox 列表中获取。

追加一个 Volume

在本地终端设置连接信息,将占位符替换为实际值。各变量的取值参见本文环境变量说明。

export E2B_API_KEY="<YOUR-E2B-API-KEY>"
export E2B_API_URL="https://api.<REGION>.sandbox.aliyuncs.com"
export E2B_DOMAIN="<REGION>.sandbox.aliyuncs.com"
export SANDBOX_ID="<SANDBOX-ID>"

以下代码在本地运行,通过 SDK 访问 Sandbox 内的文件。示例会为每个新增挂载创建带随机标识的独立测试文件,写入并读取校验后删除该文件,保留当前 Sandbox。请使用允许读写的 Volume;只读 Volume 的验证方式参见本文步骤三:验证挂载。

Sandbox.connect() 会更新 Sandbox 的超时时间。示例通过 timeout=300 将连接后的超时时间设为 300 秒,可按任务需要调整。

以下示例将已有的 oss-workspace Volume 挂载到 /mnt/oss。请替换为实际的 Volume 名称和未被占用的挂载目录,将代码保存为 append_volume.py:

import os
from uuid import uuid4

import httpx
from e2b import Sandbox


def require_env(name: str) -> str:
    value = os.environ.get(name, "").strip()
    if not value:
        raise RuntimeError(f"缺少环境变量: {name}")
    return value


def verify_read_write(sandbox: Sandbox, mount_dir: str) -> None:
    marker_path = f"{mount_dir}/mount-check-{uuid4().hex}.txt"
    expected = f"append mount check {uuid4().hex}\n"
    sandbox.files.write(marker_path, expected)
    try:
        content = sandbox.files.read(marker_path)
        if content != expected:
            raise RuntimeError(f"文件内容校验失败: {marker_path}")
    finally:
        sandbox.files.remove(marker_path)
    print(f"读写校验通过,测试文件已删除: {mount_dir}")


api_key = require_env("E2B_API_KEY")
api_url = require_env("E2B_API_URL").rstrip("/")
domain = require_env("E2B_DOMAIN")
sandbox_id = require_env("SANDBOX_ID")

mounts = [
    {"name": "oss-workspace", "path": "/mnt/oss"},
]
payload = {"namedVolumeMounts": mounts}

response = httpx.post(
    f"{api_url}/sandboxes/{sandbox_id}/fc-volume-mounts",
    headers={"X-API-Key": api_key},
    json=payload,
    timeout=120.0,
)
if response.status_code != 204:
    raise RuntimeError(f"追加挂载失败: HTTP {response.status_code}, {response.text}")

sandbox = Sandbox.connect(
    sandbox_id,
    timeout=300,
    api_key=api_key,
    api_url=api_url,
    domain=domain,
)

for mount in mounts:
    verify_read_write(sandbox, mount["path"])

运行示例:

python append_volume.py

追加多个 Volume

首次运行前,将上述脚本的 mounts 定义替换为以下内容,可一次追加两个已有 Volume。请替换为实际的 Volume 名称,并确保两者均允许读写。脚本会逐一验证各挂载目录。

mounts = [
    {"name": "project-data", "path": "/mnt/project"},
    {"name": "project-results", "path": "/mnt/results"},
]

同一次请求可以引用不同存储类型的 Volume,但 Sandbox 必须同时满足这些存储的访问条件。各 Volume 中配置的 RAM 角色不会合并生效,也不会替换 Sandbox 已有的角色。

请求中只列出本次新增的挂载。已有挂载会保留,重复提交相同挂载会返回 400。挂载已成功但校验失败时,只需重新执行连接和验证代码,不要再次提交追加请求。

步骤三:验证挂载

示例仅在接口返回 204 后连接 Sandbox,并逐一验证新增挂载的文件读写。每个挂载目录输出“读写校验通过,测试文件已删除”,表示该目录的写入、内容比对和删除均已完成。

只读 Volume 仅执行读取验证。首次运行前,将脚本末尾的验证循环替换为以下代码。此处以 /mnt/oss 为例,需将 <EXISTING-FILE> 替换为挂载目录中已存在的文件相对路径:

file_path = "/mnt/oss/<EXISTING-FILE>"
content = sandbox.files.read(file_path, format="bytes")
print(f"读取成功: {file_path},{len(content)} 字节")

多个 Volume 的读写权限不同时,为只读挂载逐一读取已知文件,对可写挂载调用 verify_read_write(sandbox, 挂载目录)。不要对只读挂载执行写入校验。

连接成功后,还可以通过 SDK 查询 Volume 名称和挂载目录:

print(sandbox.get_info().volume_mounts)

SDK 的 volume_mounts 对应 GET /sandboxes/{sandboxID} 响应中的 volumeMounts。挂载记录和目录存在不代表数据访问正常,仍需通过文件读取或读写验证。

行为说明

释放 Sandbox 不会删除底层存储数据。测试文件和任务数据需要通过对应存储服务或挂载目录单独清理。

使用限制

  • 由于安全问题,OSS 挂载暂不支持 KMS(Key Management Service,密钥管理服务)服务端加密(SSE-KMS)。

  • 不能删除、替换或解绑已有挂载。需要移除挂载时,应释放并重新创建 Sandbox。

  • 本次新增目录必须互不相同,也不能与已有挂载目录重复或重叠。

  • 使用规范化的绝对 Unix 路径,不能为 /,不能包含前后空格、. 或 .. 路径段,也不能包含 .cache 等隐藏目录。建议使用 /mnt、/data、/home 或 /tmp 的子目录;不能使用 /bin、/opt、/var、/dev 等系统目录及其子目录。

  • 同一 Sandbox 中,OSS、AgenticFS、AgenticBucket 和 JuiceFS 各自最多 5 个挂载点。数量包含创建时和后续追加的挂载,也包含直接提供存储配置的挂载。

  • 新增 AgenticFS 挂载的 UID(User ID,用户 ID)/GID(Group ID,用户组 ID)不得与当前 Sandbox 已有配置冲突;已有和新增 JuiceFS 挂载必须使用相同的服务地址。

  • 不要并发修改同一 Sandbox 的挂载。

常见问题

请求被 API Key 策略拒绝

错误消息为 request is not allowed by API key policy 时,检查 API Key 策略是否允许本次挂载方式和存储类型,参见创建 API Key。这类拒绝发生在接口授权阶段,调整存储 RAM 角色不能解决。

追加挂载 AgenticFS 时提示 UID/GID 冲突

核对新增 Volume 的 UID/GID 配置,确保与当前 Sandbox 已有配置兼容。详细说明参见追加挂载 AgenticFS。

追加挂载 JuiceFS 时提示服务地址冲突

核对新增 Volume 的 baseURL,确保与当前 Sandbox 已有 JuiceFS 挂载使用的服务地址一致。详细说明参见追加挂载 JuiceFS。

追加挂载提示 Sandbox 未运行

错误消息为 sandbox must be running 时,确认目标 Sandbox 已进入 running 状态。已暂停的 Sandbox 需先恢复运行;已释放的 Sandbox 需重新创建。

提示找不到 Volume

错误消息为 volume not found 时,核对请求中的 Volume 名称、API Key 所属 Team 和 API 地址的地域。按名称挂载需使用同一 Team 中已有的 Volume,不能填写 Volume ID。

Volume 已存在,为什么仍提示不可用

错误消息包含 is not available 时,表示 Volume 存在,但状态尚不满足挂载要求。通过 GetVolume 查询其状态和状态原因,确认处于可用状态后再挂载;存在失败原因时,应先处理该原因。重复提交挂载请求不会使 Volume 变为可用。

追加挂载提示缺少 RAM 角色

错误消息包含 FC Function execution Role is required,表示当前 Sandbox 未配置所需的 RAM 角色。追加接口沿用当前角色,不会从新增 Volume 的 mountConfig.role 为 Sandbox 设置角色。

需要准备具备目标存储访问权限的角色,并在重新创建 Sandbox 时配置。具体方法参见配置 RAM 角色。

追加挂载提示 Sandbox 的 VPC 配置不完整

错误消息包含 FC Function complete VPC configuration is required 时,缺少配置的是当前 Sandbox。追加请求或新增 Volume 的 mountConfig.vpcConfig 不会补齐它。

需要在重新创建 Sandbox 时配置完整的 vpcId、securityGroupId 和非空 vSwitchIds。创建时可直接通过 metadata 提供,或在引用 Volume 时使用该 Volume 保存的 VPC 配置。

追加挂载提示目录重复

错误消息包含 duplicate mount path 或 duplicate mount dir 时,检查本次请求内是否有重复的本地挂载目录,以及目录是否已被 Sandbox 中的其他挂载占用。不同存储类型也不能共用同一个本地挂载目录。

已有挂载无需再次提交;新增挂载应使用未占用的目录。追加接口不能覆盖或替换已有挂载。

本次只追加一个挂载点,为什么仍提示数量超限

挂载数量按 Sandbox 中已有和本次新增的挂载累计计算,直接配置和引用 Volume 的挂载都需计入。不能只检查本次请求的数量。

按本文使用限制核对相应存储类型的挂载数量。达到上限时,可将新增存储挂载到另一个 Sandbox;更换本地挂载目录不会减少已有挂载数量。

若问题仍未解决,或接口提示服务暂时不可用,请保留完整错误信息和请求 ID,联系产品支持。