全栈应用服务器

  • 全栈应用服务器 > 使用指南 > 沙箱服务概述 > 资源挂载

    资源挂载

    最近更新时间: 2026-06-12 16:51:33

    概述

    资源挂载是七牛沙箱额外提供的开发者能力,适合在 AI Agent、代码审查、自动化构建和代码迁移等场景中安全地使用外部资源。

    创建沙箱时可以通过 resources 参数声明需要挂载的外部资源:

    参数 能力 说明
    resources 资源挂载 沙箱启动前由平台准备外部资源,并挂载到沙箱内指定路径

    当前 resources 支持 GitHub 仓库资源和 Kodo 存储桶资源。访问外部资源需要的凭证尽量由平台侧持有,不直接暴露给沙箱内进程。

    支持的资源类型

    GitHub 仓库资源

    GitHub 仓库资源用于在沙箱启动前预拉取仓库快照,并挂载到沙箱内指定路径。适合代码审查、自动化构建、AI Agent 改代码等场景。

    字段 是否必填 说明
    type 资源类型;GitHub 仓库资源填写 github_repository
    url GitHub 仓库地址,支持 HTTPS 地址,或 git@github.com:owner/repo.git 这种 GitHub SSH 风格地址;平台会统一转为 HTTPS 处理
    mount_path 沙箱内挂载路径,必须是绝对路径,且同一个沙箱内不能重复
    authorization_token 访问该仓库的 GitHub Token;同一个沙箱内多个 GitHub 仓库资源当前必须使用同一个 Token

    如果创建沙箱时传入 github_repository 资源,平台会使用资源中的 authorization_token 预拉取仓库,并自动派生运行时 GitHub 密钥注入。沙箱内进程不需要、也无法直接读取真实 Token。

    Kodo 存储桶资源

    Kodo 存储桶资源用于把七牛云对象存储 Bucket 通过 NFS 挂载到沙箱内指定路径。适合让沙箱直接读取数据集、构建产物、模型文件、日志归档等对象存储内容。

    Kodo 资源只支持使用七牛 AK/SK 鉴权创建沙箱;仅使用沙箱 API Key 的创建请求不支持挂载 Kodo 资源。凭证用于平台侧访问 Bucket,不会以明文暴露给沙箱内进程。

    字段 是否必填 说明
    type 资源类型;Kodo 存储桶资源填写 kodo
    bucket Kodo Bucket 名称
    mount_path 沙箱内挂载路径,必须是绝对路径,且同一个沙箱内不能重复
    prefix Bucket 内的对象 key 前缀;传入后只暴露该前缀下的内容。服务端会去掉首尾 / 并规范化路径
    read_only 是否只读挂载。显式传 true 时只校验读取权限;未传或传 false 时平台会尝试校验写权限,如果 AK/SK 无写权限,会自动改为只读挂载

    创建沙箱时传入 kodo 资源后,平台会校验 Bucket 可访问性,并为沙箱创建 NFS 代理挂载。沙箱内进程只看到 mount_path 下的文件系统视图,看不到 AK/SK。

    工作原理

    沙箱启动前:
    外部资源 ── 平台使用凭证准备资源 ── 挂载到沙箱内 mount_path
    

    核心行为:

    • 资源在沙箱启动前准备完成,启动后可直接访问 mount_path
    • 凭证由平台侧持有,不以环境变量、文件或命令参数形式进入沙箱
    • GitHub 仓库资源会自动派生运行时 GitHub 注入,后续 git pullgit push 等操作可继续鉴权
    • Kodo 存储桶资源通过平台侧 NFS 代理挂载;prefix 可限制沙箱只能看到 Bucket 中某个前缀下的内容
    • Kodo 挂载的读写能力取决于 AK/SK 权限和 read_only 设置;无写权限时平台会自动降级为只读挂载

    resources 中包含 github_repository 时,不要再显式传入 type: githubinjections。服务端会根据 authorization_token 自动派生 GitHub 注入;如果同时显式传入,会返回 400 github_repository resources do not support explicit github injections

    使用 Go SDK 挂载资源

    以下示例基于 七牛 Go SDK v7.26.13+v7.26.13 起,Go SDK 支持在创建沙箱时挂载 Kodo bucket 资源。

    挂载 GitHub 仓库

    package main
    
    import (
        "context"
        "log"
        "os"
    
        "github.com/qiniu/go-sdk/v7/sandbox"
    )
    
    func stringPtr(s string) *string { return &s }
    
    func main() {
        ctx := context.Background()
    
        apiKey := requiredEnv("QINIU_API_KEY")
        githubToken := requiredEnv("GITHUB_TOKEN")
    
        client, err := sandbox.NewClient(&sandbox.Config{
            APIKey:   apiKey,
            Endpoint: os.Getenv("QINIU_SANDBOX_API_URL"),
        })
        if err != nil {
            log.Fatal(err)
        }
    
        sb, _, err := client.CreateAndWait(ctx, sandbox.CreateParams{
            TemplateID: "base",
            Resources: &[]sandbox.SandboxResourceSpec{
                {
                    GitRepository: &sandbox.GitRepositoryResource{
                        Type:               sandbox.GitRepositoryTypeGithub,
                        URL:                "https://github.com/owner/private-repo.git",
                        MountPath:          "/workspace/repo",
                        AuthorizationToken: stringPtr(githubToken),
                    },
                },
            },
        })
        if err != nil {
            log.Fatal(err)
        }
        defer sb.Kill(ctx)
    
        result, err := sb.Commands().Run(ctx, "cd /workspace/repo && git status --short")
        if err != nil {
            log.Fatal(err)
        }
    
        log.Println(result.Stdout)
    }
    
    func requiredEnv(name string) string {
        value := os.Getenv(name)
        if value == "" {
            log.Fatalf("%s is required", name)
        }
        return value
    }
    

    这个例子中:

    • /workspace/repo 在沙箱启动后已经包含仓库内容
    • GITHUB_TOKEN 不会出现在沙箱环境变量或文件系统中
    • 后续在 /workspace/repo 执行 git pullgit push 时,会复用平台自动派生的 GitHub 注入

    挂载 Kodo 存储桶

    Go SDK 的 sandbox.KodoResource 不包含 access_key / secret_key 字段。创建带 Kodo resource 的沙箱时,需要在 sandbox.Config.Credentials 中配置七牛 AK/SK,SDK 会为创建请求添加 Qiniu 签名鉴权。

    package main
    
    import (
        "context"
        "log"
        "os"
    
        "github.com/qiniu/go-sdk/v7/auth"
        "github.com/qiniu/go-sdk/v7/sandbox"
    )
    
    func stringPtr(s string) *string { return &s }
    func boolPtr(v bool) *bool { return &v }
    
    func main() {
        ctx := context.Background()
    
        client, err := sandbox.NewClient(&sandbox.Config{
            APIKey:   requiredEnv("QINIU_API_KEY"),
            Endpoint: os.Getenv("QINIU_SANDBOX_API_URL"),
            Credentials: auth.New(
                requiredEnv("KODO_ACCESS_KEY"),
                requiredEnv("KODO_SECRET_KEY"),
            ),
        })
        if err != nil {
            log.Fatal(err)
        }
    
        sb, _, err := client.CreateAndWait(ctx, sandbox.CreateParams{
            TemplateID: "base",
            Resources: &[]sandbox.SandboxResourceSpec{
                {
                    Kodo: &sandbox.KodoResource{
                        Bucket:    "my-bucket",
                        MountPath: "/mnt/kodo",
                        Prefix:    stringPtr("datasets/demo"),
                        ReadOnly:  boolPtr(true),
                    },
                },
            },
        })
        if err != nil {
            log.Fatal(err)
        }
        defer sb.Kill(ctx)
    
        result, err := sb.Commands().Run(ctx, "find /mnt/kodo -maxdepth 2 -type f | head")
        if err != nil {
            log.Fatal(err)
        }
    
        log.Println(result.Stdout)
    }
    
    func requiredEnv(name string) string {
        value := os.Getenv(name)
        if value == "" {
            log.Fatalf("%s is required", name)
        }
        return value
    }
    

    这个例子中:

    • /mnt/kodo 在沙箱启动后已经是 Kodo bucket 的文件系统视图
    • KODO_ACCESS_KEYKODO_SECRET_KEY 只用于 SDK 对创建请求签名,不会写入 resource JSON,也不会进入沙箱
    • ReadOnly: true 会让平台只校验读取权限,并以只读方式挂载

    REST API 示例

    创建沙箱并挂载 GitHub 仓库资源:

    curl -X POST "$QINIU_SANDBOX_API_URL/sandboxes" \
      -H "X-API-Key: $QINIU_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "templateID": "base",
        "resources": [
          {
            "type": "github_repository",
            "url": "https://github.com/owner/private-repo.git",
            "mount_path": "/workspace/repo",
            "authorization_token": "'"$GITHUB_TOKEN"'"
          }
        ]
      }'
    

    创建沙箱并挂载 Kodo 存储桶资源:

    curl -X POST "$QINIU_SANDBOX_API_URL/sandboxes" \
      -H "X-API-Key: $QINIU_API_KEY" \
      -H "Authorization: Qiniu <SignedToken>" \
      -H "Content-Type: application/json" \
      -d '{
        "templateID": "base",
        "resources": [
          {
            "type": "kodo",
            "bucket": "my-bucket",
            "mount_path": "/mnt/kodo",
            "prefix": "datasets/demo",
            "read_only": true
          }
        ]
      }'
    

    其中 SignedToken 需要用七牛 AK/SK 生成。只带 X-API-Key、不带 AK/SK 签名的请求不支持创建 Kodo 资源沙箱。

    这个例子中:

    • 沙箱启动后可以通过 /mnt/kodo 访问 my-bucketdatasets/demo 前缀下的对象
    • AK/SK 只用于请求签名,不会出现在请求 JSON、沙箱环境变量或文件系统中
    • read_only: true 会让平台只校验读取权限,并以只读方式挂载

    同一个沙箱也可以同时挂载 GitHub 仓库资源和 Kodo 存储桶资源,只要每个资源的 mount_path 不重复:

    {
      "templateID": "base",
      "resources": [
        {
          "type": "github_repository",
          "url": "https://github.com/owner/private-repo.git",
          "mount_path": "/workspace/repo",
          "authorization_token": "ghp_xxx"
        },
        {
          "type": "kodo",
          "bucket": "my-bucket",
          "mount_path": "/workspace/data",
          "prefix": "datasets/demo"
        }
      ]
    }
    

    常见工作流

    启动即拥有代码

    适合代码审查、构建测试、仓库内容分析:

    1. 创建沙箱时传入 github_repository 资源
    2. 平台预拉取仓库并挂载到 mount_path
    3. Agent 直接在挂载目录内运行测试、分析或修改代码

    修改后推送回仓库

    适合自动修复、批量迁移、文档更新:

    1. 创建沙箱时传入 github_repository 资源
    2. Agent 在挂载目录中修改代码
    3. Agent 配置 Git 作者信息并提交
    4. Agent 直接执行 git push

    示例:

    cd /workspace/repo
    git checkout -b feature/auto-fix
    git config user.name "AI Bot"
    git config user.email "bot@example.com"
    git add .
    git commit -m "fix: update generated files"
    git push -u origin feature/auto-fix
    

    读取对象存储数据

    适合数据分析、模型推理、批量处理对象存储中的文件:

    1. 创建沙箱时传入 kodo 资源
    2. 如果只需要读取,建议显式传入 read_only: true
    3. Agent 直接从 mount_path 读取文件

    示例:

    ls -lah /mnt/kodo
    python /workspace/repo/scripts/analyze.py --input /mnt/kodo/input.jsonl
    

    写入对象存储结果

    适合把沙箱内生成的报告、构建产物或处理结果写回 Kodo:

    1. 创建沙箱时使用有写权限的 AK/SK 签名鉴权
    2. 不传 read_only,或传入 read_only: false
    3. Agent 把结果写入 mount_path 下的目标路径

    如果平台检测到 AK/SK 没有写权限,会自动按只读挂载处理。此时写入操作会在沙箱内失败,需要换用有写权限的 AK/SK 后重新创建沙箱。

    限制与注意事项

    • resources 最多 20 项
    • 所有 mount_path 必须是绝对路径,不能重复,不能包含路径穿越
    • github_repository.authorization_token 当前必填,即使目标仓库是公开仓库
    • 同一个沙箱内多个 GitHub 仓库资源必须使用同一个 authorization_token
    • 使用 github_repository 资源时,不要额外显式传入 GitHub 注入
    • GitHub 仓库资源使用缓存快照,不保证每次创建沙箱都拉取最新 HEAD;如果任务依赖最新代码,请在挂载目录内执行 git pull
    • 如果需要最小化权限,GitHub 建议使用 Fine-grained PAT,并只授予目标仓库需要的读写权限
    • kodo.bucketkodo.mount_path 均为必填;kodo.prefixkodo.read_only 可选
    • 创建带 kodo 资源的沙箱必须使用七牛 AK/SK 鉴权;仅使用沙箱 API Key 不支持 Kodo 资源
    • API 服务必须配置 S3_KODO_ENDPOINT,否则创建带 kodo 资源的沙箱会失败
    • kodo.prefix 不能包含路径穿越;服务端会去掉首尾 /,例如 /datasets/demo/ 会规范化为 datasets/demo
    • Kodo 资源会在创建沙箱时校验 Bucket 可访问性;显式 read_only: true 时只校验读取权限,未显式只读时还会探测写权限
    • Kodo 存储桶通过 NFS 挂载,适合文件式访问对象存储;对一致性、目录遍历和大量小文件访问的性能预期应按对象存储和 NFS 代理特性评估

    相关文档

    以上内容是否对您有帮助?