挂载 JuiceFS Volume

更新时间:
复制 MD 格式

创建 Sandbox 时,可通过 volume_mounts 按名称挂载已有 JuiceFS Volume。

功能介绍

挂载后,Sandbox 可以通过文件路径访问 JuiceFS,数据不随 Sandbox 释放而删除。

如需直接在创建 Sandbox 时提交完整的 JuiceFS 配置,请参见动态挂载 JuiceFS。

如需向运行中的 Sandbox 追加挂载,请参见追加挂载 Volume。

适用范围

  • 已为目标 Team 创建 JuiceFS Volume,并获取 Volume 名称。

  • 已准备绑定同一 Team 的智能体沙箱 API Key。Volume 和 API Key 不能跨 Team 使用。具体操作,请参见创建 API Key。

  • 已准备与 JuiceFS 服务网络连通的 VPC(Virtual Private Cloud,专有网络)、交换机和安全组。

  • 已准备智能体沙箱 API URL、Domain 和第二代运行时(MicroVM,微型虚拟机)自定义模板。

创建 Sandbox 时使用的 VPC 配置必须包含 vpcId、securityGroupId 和非空的 vSwitchIds,且能够访问目标存储。模板中的 VPC 配置不能替代该挂载配置。

JuiceFS Volume 必须使用第二代运行时自定义模板,源镜像必须预装 JuiceFS 企业版客户端、RADOS(Reliable Autonomic Distributed Object Store,Ceph 底层对象存储)运行库和 FUSE 2(Filesystem in Userspace,用户态文件系统)。

操作步骤

步骤一:准备第二代运行时镜像

已有符合要求的模板时,跳过本步骤,直接进入步骤二:安装 SDK。

JuiceFS Volume 挂载必须使用第二代运行时(MicroVM)。构建自定义模板前,必须在源镜像中预装 JuiceFS 企业版客户端、RADOS 运行库和 FUSE 2。第二代运行时直接使用源镜像,不会在模板构建时注入 JuiceFS 客户端。

JuiceFS Volume 挂载当前仅支持 JuiceFS 企业版。JuiceFS 官方在 Docker Hub 的 juicedata/mount 仓库提供企业版 Mount 镜像,镜像标签以 ee- 开头。镜像中的 /usr/bin/juicefs 是客户端启动器,固定版本的客户端可执行文件位于 /usr/local/juicefs/mount/jfsmount。

以下示例使用 juicedata/mount:ee-5.3.7-58af72b。其中,5.3.7 是客户端版本,58af72b 是对应的构建 commit。版本信息可通过 JuiceFS 命令参考核对。镜像和容器的使用方法参见 在 Docker 中使用 JuiceFS。

先确认镜像可以拉取,并检查其中的企业版客户端:

docker pull --platform linux/amd64 \
  juicedata/mount:ee-5.3.7-58af72b

docker run --rm --platform linux/amd64 \
  --entrypoint /usr/bin/juicefs \
  juicedata/mount:ee-5.3.7-58af72b \
  version

输出的客户端版本应为 5.3.7,构建 commit 应为 58af72b。不要使用 latest 或 ee-nightly 等浮动标签,以免重新构建模板后客户端版本发生变化。如果构建环境不能访问 Docker Hub,请先将该镜像同步到可访问的私有镜像仓库,再替换以下 Dockerfile 中 juicedata/mount 的镜像地址。

以下 Dockerfile 默认使用 Ubuntu 22.04。基于已有的 Sandbox 基础镜像构建时,通过 BASE_IMAGE 构建参数传入该镜像地址:

ARG BASE_IMAGE=ubuntu:22.04

FROM juicedata/mount:ee-5.3.7-58af72b AS juicefs-ee

FROM ${BASE_IMAGE}

ARG DEBIAN_FRONTEND=noninteractive

RUN set -eux; \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        fuse \
        librados2; \
    rm -rf /var/lib/apt/lists/*

COPY --from=juicefs-ee /usr/local/juicefs/mount/jfsmount /usr/bin/juicefs

RUN set -eux; \
    chmod 0755 /usr/bin/juicefs; \
    command -v juicefs; \
    command -v fusermount; \
    mkdir -p /mnt/juicefs

WORKDIR /root

# 不设置自定义 USER、ENTRYPOINT 或 CMD,由 Sandbox 管控链路接管。

不要将 JuiceFS Token 或挂载配置写入 Dockerfile 或镜像层。

构建并推送 linux/amd64 镜像前,先将占位符替换为实际值:

docker buildx build \
  --platform linux/amd64 \
  --build-arg BASE_IMAGE="<YOUR-SANDBOX-BASE-IMAGE>" \
  --push \
  -t "<REGISTRY>/<NAMESPACE>/microsandbox-juicefs-ee:<VERSION>" \
  .

构建完成后,检查镜像中的客户端、RADOS 运行库和 FUSE 2:

docker run --rm --platform linux/amd64 \
  --entrypoint /bin/sh \
  <REGISTRY>/<NAMESPACE>/microsandbox-juicefs-ee:<VERSION> \
  -euxc '
    command -v juicefs
    command -v fusermount
    ldconfig -p | grep "librados\.so\.2"
    juicefs version
  '

该检查只验证镜像内容,不代表 VPC、Token 或真实挂载链路已经可用。请使用该镜像重新构建 MicroVM 模板,再运行后续示例。

步骤二:安装 SDK

本文使用 E2B Python SDK 演示。volume_mounts 需要 E2B Python SDK 2.31.0 或以上版本。

python3 -m venv .venv
source .venv/bin/activate
pip install e2b==2.31.0

步骤三:挂载并验证

环境变量说明

环境变量

用途

取值来源或填写方式

E2B_API_KEY

访问智能体沙箱的 API Key。

从智能体沙箱控制台获取,必须绑定 Volume 所属的 Team。

E2B_API_URL

E2B API 请求地址。

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

E2B_DOMAIN

SDK 使用的服务域名。

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

E2B_TEMPLATE

创建 Sandbox 使用的模板。

填写满足前提条件的可用模板 ID 或别名;可从智能体沙箱控制台获取。

JUICEFS_SANDBOX_VOLUME_NAME

要挂载的 JuiceFS Volume 名称。

使用创建 JuiceFS Volume 时设置的名称,或从 Volume 列表查询;不使用 Volume ID。

volume_mounts 中填写 JuiceFS Volume 名称,即 JUICEFS_SANDBOX_VOLUME_NAME,不使用 JuiceFS 文件系统名称或 Volume ID。

挂载示例

在终端中设置以下参数,并将占位符替换为实际值。各变量的取值参见本文环境变量说明。

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 E2B_TEMPLATE="<MICROVM-TEMPLATE-ID>"

export JUICEFS_SANDBOX_VOLUME_NAME="juicefs-workspace"

本地挂载目录位于 Sandbox 内,对应 volume_mounts 的键。建议使用 /home、/mnt、/tmp 或 /data 的子目录,本文使用 /mnt/juicefs。

以下示例复用 Volume 的 mountConfig.vpcConfig,将 JuiceFS Volume 挂载到 /mnt/juicefs。请确保 Volume 已保存完整的 VPC 配置。

示例会在挂载目录中创建带随机标识的独立测试文件,写入并读取校验后删除该文件,再释放本次创建的 Sandbox。请使用具备读写权限的挂载配置。

将以下代码保存为 04_mount_juicefs_volume.py:

import os
from uuid import uuid4

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


mount_dir = "/mnt/juicefs"
marker_path = f"{mount_dir}/hello-juicefs-{uuid4().hex}.txt"
sandbox = None
marker_written = False

try:
    sandbox = Sandbox.create(
        template=require_env("E2B_TEMPLATE"),
        timeout=300,
        api_key=require_env("E2B_API_KEY"),
        api_url=require_env("E2B_API_URL"),
        domain=require_env("E2B_DOMAIN"),
        volume_mounts={
            mount_dir: require_env("JUICEFS_SANDBOX_VOLUME_NAME"),
        },
    )

    info = sandbox.get_info()
    print(f"volume_mounts={info.volume_mounts}")

    sandbox.files.write(marker_path, "hello juicefs\n")
    marker_written = True
    content = sandbox.files.read(marker_path)
    if content != "hello juicefs\n":
        raise RuntimeError(f"文件内容不一致: {content!r}")
finally:
    try:
        if sandbox is not None and marker_written:
            sandbox.files.remove(marker_path)
    finally:
        if sandbox is not None:
            sandbox.kill()

print("JuiceFS Volume 挂载读写验证成功")

运行示例:

python 04_mount_juicefs_volume.py

输出 JuiceFS Volume 挂载读写验证成功 表示本次读写、测试文件清理和 Sandbox 释放已完成。

行为说明

  • volume_mounts 使用 {挂载目录: Volume 名称} 格式,不使用 Volume ID,也不使用 JuiceFS 文件系统名称。

  • 智能体沙箱根据 Volume 名称读取创建 Volume 时保存的 volumeName、baseURL、remoteDir、token 和 args,再转换为 JuiceFS 挂载配置。

  • 本文复用 Volume 的 mountConfig.vpcConfig。需要覆盖时,可在创建 Sandbox 的 metadata 中通过 fc.sandbox.network.vpc 提供完整 VPC 配置;两处均配置时,以 metadata 为准。

  • Sandbox 暂停后再恢复时会恢复 Volume 挂载。

  • 释放 Sandbox 不会删除 JuiceFS 中的数据。测试文件由示例主动删除,其他数据的保留和清理需单独处理。

使用限制

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

  • 挂载目录必须是规范化的绝对 Unix 路径,不能为 /,不能包含前后空格、重复分隔符、. 或 .. 路径段。

  • 挂载目录不能使用 /bin、/opt、/var、/dev 等系统目录及其子目录,也不能包含 .cache 等以 . 开头的隐藏目录。

  • 同一 Sandbox 中的挂载目录不能重复。

  • 同一 Sandbox 内的 JuiceFS 挂载必须使用相同的 baseURL。该要求同时适用于按名称引用 Volume 和直接提供存储配置的挂载。

常见问题

提示找不到 Volume

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

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

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

已配置 VPC,为什么仍提示配置不完整

错误消息包含 mount requires complete VPC config 时,表示本次创建使用的 VPC 配置缺少必填项。

未在 metadata 中指定 VPC 时,检查 Volume 的 mountConfig.vpcConfig;已指定时,检查 fc.sandbox.network.vpc。实际使用的配置必须包含 vpcId、securityGroupId 和非空的 vSwitchIds。metadata 配置优先,不会用 Volume 的字段补齐不完整的 metadata。

Volume 创建成功,但 Sandbox 创建超时或挂载失败

创建 Volume 只保存配置,不执行真实挂载。根据错误消息检查对应配置;消息未明确指出原因时,可按以下顺序排查:

  1. 按本文步骤一:准备第二代运行时镜像验证 JuiceFS 企业版客户端、RADOS 运行库和 FUSE 2。

  2. 检查实际使用的 VPC 路由、安全组和服务地址,确认 Sandbox 能访问 JuiceFS 服务。

  3. 核对 Token、文件系统名称及远端目录,确认 Token 允许访问目标目录。

如需进一步排查,请保留完整错误信息和请求 ID。