Skip to main content

什么是 Daytona

Daytona是一个开源的安全弹性基础设施运行时,专为AI生成代码的安全执行与智能体工作流设计,项目地址为 https://github.com/daytonaio/daytona

Daytona的核心抽象是沙箱(Sandbox)——一种完全隔离的可组合计算单元,具备独立的内核、文件系统、网络栈以及独立分配的vCPURAM与磁盘资源。沙箱从创建到可执行代码的时间不超过90ms,原生支持PythonTypeScriptJavaScript三种语言的代码执行。基于OCI/Docker兼容性、大规模并行化能力以及无限持久化特性,沙箱为智能体工作流提供了一致且可预测的运行环境。

智能体和开发者可以通过Daytona SDKREST APICLI与沙箱进行编程交互,覆盖沙箱生命周期管理、文件系统操作、进程与代码执行以及运行时配置等各类操作。Daytona的有状态环境 快照(Snapshot) 机制支持跨会话的持久化智能体操作,使其成为构建AI智能体架构的理想底层基础设施。

Daytona

解决的核心问题

AI智能体(Agent)系统日趋成熟的今天,让LLM(大语言模型)直接生成并在生产环境中执行代码是一个显著的安全隐患。现有方案在安全性、弹性与开发体验上存在以下痛点:

问题Daytona 的解法
LLM生成的代码直接运行在宿主机,存在系统命令注入、文件越权等安全风险每个沙箱拥有独立内核与网络栈,完全隔离于宿主机和其他沙箱
传统Docker容器启动缓慢(秒级),无法满足智能体实时响应需求沙箱冷启动时间不超过90ms,显著降低智能体响应延迟
代码执行环境难以跨会话保持状态,智能体任务中断后无法恢复提供有状态快照机制,支持沙箱状态持久化与跨会话恢复
多智能体并发执行时资源竞争严重,扩缩容复杂基于弹性计算平面(Compute Plane),支持大规模并行沙箱调度
开发者需要同时维护多套语言运行时和环境配置统一的SDK接口支持Python/TypeScript/Go/Ruby/Java等多语言
缺乏对智能体与沙箱交互的细粒度观测与审计能力内置OpenTelemetry支持、审计日志及Webhook事件机制

核心优势

极速冷启动

沙箱从创建到可执行代码的时间控制在90ms以内,无论是单次按需执行还是大批量并行任务,都能获得极低的启动延迟。这一特性是通过预热池(Warm Pool)机制实现的:系统提前创建并保持一批待命的沙箱实例,在接受请求时直接分配,而非从零创建。

完全资源隔离

每个沙箱都是一个完整的虚拟计算节点,拥有独立分配的vCPU、内存和磁盘配额。沙箱之间以及沙箱与宿主机之间在默认情况下完全网络隔离,从根本上杜绝了跨租户数据泄露及宿主机被攻击的风险。

有状态快照

Daytona支持将沙箱当前状态(文件系统、已安装软件包、运行上下文等)保存为快照(Snapshot),后续创建沙箱时可直接基于快照启动,无需重复初始化环境,大大缩短了依赖项安装等预热时间。

多语言 SDK 支持

官方提供PythonTypeScriptGoRubyJava五种语言的SDK,以及基于OpenAPI自动生成的REST API客户端和Toolbox API客户端,可无缝集成到现有的智能体框架和应用代码中。

开放可扩展

DaytonaApache-2.0/AGPL-3.0协议开源,支持完全自托管部署(基于Docker Compose),也可使用官方托管服务app.daytona.io,还支持混合模式——Daytona控制平面托管,计算节点在自有机器上运行。

架构设计

Daytona平台采用三平面架构,各平面职责清晰、边界明确:

接口平面(Interface Plane)

接口平面为用户和智能体提供与Daytona平台交互的所有入口,包括:

  • CLIGo实现的命令行工具,提供沙箱管理的核心操作入口
  • Dashboard:基于Web的可视化控制台,用于沙箱管理、日志查看与实时监控
  • SDK:多语言客户端库,是智能体与沙箱交互的主要编程接口
  • REST API:基于OpenAPI规范的HTTP接口,所有SDK底层均调用此API

控制平面(Control Plane)

控制平面负责编排所有沙箱操作,是Daytona平台的"大脑"。

API Service

基于NestJS框架实现的RESTful服务,是所有平台操作的主要入口点。负责:

  • 沙箱的生命周期管理(创建、启动、停止、归档、删除)
  • 快照的构建、存储与版本管理
  • 用户认证(OIDC/JWT)与API Key管理
  • 组织级配额与计费管理
  • 路由请求至计算平面的Runner节点

Snapshot Manager

快照管理器负责协调沙箱快照的创建流程:

  • 触发Runner对指定沙箱执行快照操作
  • 将快照镜像推送至OCI镜像仓库(内置Harbor/Registry
  • 维护快照的元数据与区域分发信息

SSH Gateway

独立运行的SSH网关,接受已认证的SSH连接请求,将其转发至对应沙箱内的Daemon进程,提供完整的终端访问能力。

Proxy Service

反向代理服务,为沙箱内运行的Web应用提供预览URL路由(格式如http://{{PORT}}-{{sandboxId}}.proxy.domain)及自定义域名代理能力。

计算平面(Compute Plane)

计算平面负责实际运行和管理沙箱实例。

Runner(计算节点)

RunnerDaytona计算平面的核心组件,以Go实现,部署在实际的计算节点上。每个Runner

  • 接受控制平面的调度指令,负责沙箱的创建、启停、销毁
  • 维护本节点上所有沙箱的运行状态
  • 上报节点资源使用情况(CPU/内存/磁盘),供控制平面进行调度决策
  • 管理沙箱镜像的本地缓存与镜像拉取

Sandbox(沙箱)

沙箱是Daytona的核心执行单元,基于OCI容器技术实现,每个沙箱拥有:

  • 独立分配的vCPU、内存和磁盘资源
  • 完整的独立网络栈(可配置网络隔离模式)
  • 持久化文件系统(支持挂载持久化卷)
  • 内置Git支持与代码仓库操作能力

沙箱的底层容器实现

Daytona的沙箱底层是标准的Docker容器。Runner组件直接调用Docker SDKgithub.com/docker/docker/client)来创建和管理容器,每个沙箱对应宿主机上的一个独享Docker容器。以多个Claude Code编码智能体为例,其运行关系如下:

几个关键实现细节值得关注:

  • 启动即容器:调用daytona.create()时,Runner会执行docker create + docker start,在宿主机上创建一个独立的Docker容器,容器的Hostname即为沙箱ID
  • Daemon 注入:容器的entrypoint被替换为Daytona Daemon二进制(以只读bind-mount方式注入),Daemon在容器内启动后作为Toolbox API服务端运行,SDK通过HTTP与之通信
  • 特权模式:容器以--privileged特权模式运行,这是Daemon进程能执行任意代码所必需的
  • 冷启动加速<90ms冷启动依赖**预热池(Warm Pool)**机制——Runner提前创建并保持一批待命容器,新请求到来时直接分配,而非从零执行docker create
  • 网络双重隔离:容器间网络隔离不仅依赖Docker原生网络,还在宿主机上通过iptables规则(NetRulesManager)对每个容器的IP单独设置出入站访问控制,实现更细粒度的网络管控
  • 资源配额CPUQuotaMemoryMemorySwap直接映射到container.HostConfig.Resources,磁盘配额在xfs文件系统上通过StorageOpt size实现
  • Docker-in-Docker(DinD)Runner本身以docker:28.2.2-dind-alpine3.22为基础镜像构建,容器启动时先运行dockerd-entrypoint.sh在容器内拉起Docker守护进程,再启动daytona-runner二进制。因此Runner自带完整的Docker引擎,部署时runner服务无需挂载宿主机的/var/run/docker.sock,只需设置privileged: true即可。

运行时支持范围

Daytona目前仅支持Docker作为容器运行时后端,不支持直接对接裸containerd守护进程或通过CRI接口(如cri-containerdCRI-O)接入容器运行时,也没有Kubernetes Adapter。尽管项目的go.mod中可以看到github.com/containerd/containerd/v2等大量containerd相关包,但它们全部是github.com/docker/docker客户端SDK传递依赖Daytona自身代码只引用了containerd/errdefs用于错误类型判断(如errdefs.IsConflict(err)),并不调用containerd的运行时API

值得了解的是,Docker Engine1.11版本起已在内部将containerd作为默认容器运行时(通过shim调用),所以Daytona通过Docker间接使用了containerd,但这对用户完全透明——部署Daytona只需保证宿主机(或DinD容器内)有可用的Docker Engine即可,无需额外安装containerd客户端。

同理,Daytona没有Kubernetes集成API Servicerunner-adapter目录中只有v0v2两个版本的适配器(均为HTTP API封装),无K8s OperatorPod调度能力。计算节点的选择完全由API Service内置的自研调度器管理(基于CPU使用率、内存、磁盘、已分配资源等七维加权打分),与Kubernetes调度器无关。

Daemon(执行代理)

Daemon是运行在每个沙箱内部的代码执行代理,以Go实现,提供Toolbox API服务:

功能模块说明
process进程执行(exec命令、code_run代码解释)
fs文件系统操作(上传、下载、搜索、替换)
gitGit仓库操作(克隆、提交、推送等)
lsp语言服务器协议支持(代码补全、诊断)
terminal伪终端(PTY)会话管理
session有状态代码解释器会话
computeruse计算机使用能力(屏幕截图、鼠标键盘控制)
recording终端会话录制
sshSSH服务端,供SSH Gateway转发连接

数据存储与中间件

Daytona控制平面依赖以下存储与中间件组件:

组件用途
PostgreSQL沙箱、快照、组织、用户等核心元数据存储
Redis分布式锁、缓存与会话状态
MinIOS3兼容)快照镜像的对象存储后端
OCI RegistryHarbor沙箱镜像的OCI格式存储与分发
DexOIDC Provider身份认证与SSO集成

核心功能详解

沙箱(Sandbox)

沙箱是Daytona最核心的概念。每个沙箱在创建时可以配置以下关键参数:

参数类型说明
imagestring基础镜像(如python:3.12-slim
languagestring代码解释器语言(python/javascript/typescript
resources.cpuint分配的vCPU核数
resources.memoryint分配的内存(单位:GB
resources.diskint分配的磁盘(单位:GB
volumeslist挂载的持久化卷列表
network_block_allbool是否完全阻断网络访问
network_allow_liststring网络白名单(CIDR格式)
labelsdict自定义标签,用于分类与筛选
auto_archivebool是否自动归档(暂停不活跃沙箱)
auto_deletebool是否自动删除(归档后自动清理)

沙箱规格(Class)

Daytona使用class字段区分三种预置规格,对应不同的资源配置:

规格vCPU内存磁盘
small(默认)4 核8 GB30 GB
medium8 核16 GB60 GB
large12 核24 GB90 GB

自托管部署时,以上配额直接映射到Docker容器的HostConfig.ResourcesCPUQuotaMemory),可视宿主机配置自行调整。

沙箱是"任务粒度"而非"用户粒度"

Daytona的沙箱不是"每个开发者永久占用一个容器",而是按智能体任务的生命周期来创建和销毁容器。以Codex CLI为例:Codex CLI本身运行在开发者的本地机器上,它调用Daytona SDK在沙箱中安全执行所生成的代码——一个Codex CLI编码会话通常对应一个Daytona沙箱,会话内的多次命令执行(代码生成、测试、修复……)都在同一个沙箱中进行,状态持续保留,会话结束后沙箱被删除。

这种"任务粒度"的优势在于并行扩展能力:同一个开发者或AI Agent可以同时持有并行的多个沙箱——例如批量运行1000个独立测试用例时同时启动1000个沙箱,每个沙箱独占隔离的CPU、内存和文件系统,互不干扰,运行结束后统一销毁。

规模上限与水平扩展

Daytona没有内置的"最大并发容器数"硬限制,实际容量由以下三个层次共同决定:

层次控制机制
物理资源单台Runner宿主机的CPU/内存/磁盘总量,Runner 调度以 7 维加权评分选最优节点
水平扩展向集群注册更多Runner节点即可线性扩容,无需改动控制平面
组织配额管理员可为每个组织设置totalCpuQuotatotalMemoryQuota(跨 Runner 汇总),超限则拒绝新建沙箱

官方托管服务app.daytona.io通过多区域(SHARED/DEDICATED/CUSTOM)多Runner集群,理论上可以支持数千个沙箱同时运行,具体上限取决于用户购买的资源计划。

闲置资源自动回收(Auto-Archive)

容器运行是有成本的,Daytona通过自动归档机制避免资源浪费:沙箱在无活跃 API 调用超过autoArchiveInterval分钟后会被自动归档(默认7天,最长30天),归档时将容器文件系统快照到对象存储(MinIO/S3),容器本身被销售,从而释放Runner上的CPU和内存。下次使用时从快照恢复,整个过程对调用者透明。这意味着长期不活跃的沙箱不会持续占用算力资源,只有真正"在跑"的沙箱才消耗宿主机资源。

快照(Snapshot)

快照是沙箱状态的持久化镜像,支持:

  • 声明式构建:通过YAML配置描述沙箱的依赖环境,由Daytona自动构建快照
  • 按需创建:对正在运行的沙箱手动触发快照
  • 基于快照创建沙箱:以某个快照为基础,快速创建新沙箱,跳过依赖安装步骤
  • 多区域分发:快照可在多个计算区域之间分发,加速就近启动

卷(Volume)

持久化卷(Volume)使数据可以在多个沙箱之间共享或跨生命周期持久化,支持:

  • 将同一卷挂载到不同沙箱的不同路径
  • 通过subpath参数实现多租户数据隔离(每个租户只看到卷的特定子路径)
  • 跨沙箱的数据共享(如共享模型文件、数据集等大体积资源)

网络控制

Daytona提供细粒度的网络访问控制:

  • 完全隔离模式:设置network_block_all=True,沙箱无法访问任何外部网络
  • 白名单模式:通过network_allow_list指定允许访问的IP段或域名
  • 默认模式:沙箱可访问互联网,但与其他沙箱之间网络隔离

MCP Server

Daytona内置MCPModel Context Protocol)服务器支持,允许LLM通过标准MCP协议直接调用沙箱能力(代码执行、文件操作等),无需额外编写工具封装层。

计算机使用(Computer Use)

沙箱支持图形化操作能力,通过VNC协议和PTY终端,AI智能体可以操控沙箱内的鼠标、键盘,获取屏幕截图,实现"计算机使用"(Computer Use)类任务。

安装与配置

托管服务快速上手

最快的使用方式是注册Daytona官方托管服务:

  1. 访问 app.daytona.io 注册账号
  2. DashboardAPI Keys页面创建API Key
  3. 配置环境变量:
export DAYTONA_API_KEY="your-api-key"
export DAYTONA_API_URL="https://app.daytona.io/api"

自托管部署(Docker Compose)

Daytona支持通过Docker Compose完整本地部署,以下是关键部署步骤:

第一步,克隆仓库并进入docker目录:

git clone https://github.com/daytonaio/daytona.git
cd daytona/docker

第二步,修改docker-compose.yaml中的关键配置项:

配置项说明示例值
ENCRYPTION_KEY数据加密密钥(必须修改)your-32-char-secret-key
ENCRYPTION_SALT加密盐值(必须修改)your-salt-value
DB_PASSWORDPostgreSQL数据库密码your-db-password
OIDC_CLIENT_IDOIDC客户端IDdaytona
PROXY_DOMAIN代理域名(预览URL格式用)proxy.yourdomain.com
DEFAULT_RUNNER_DOMAIN计算节点Runner地址runner:3003
SMTP_HOST邮件服务器(用于邮件通知)smtp.example.com

第三步,启动所有服务:

docker compose up -d

服务正常启动后,API服务监听3000端口,Dashboard可通过 http://localhost:3000/dashboard 访问。

SDK 安装

各语言SDK均可通过对应包管理器安装:

# Python
pip install daytona

# TypeScript / Node.js
npm install @daytona/sdk

# Go
go get github.com/daytonaio/daytona/libs/sdk-go

# Ruby
gem install daytona

SDK 初始化配置

SDK支持环境变量和代码两种配置方式:

环境变量方式(推荐用于生产环境):

export DAYTONA_API_KEY="your-api-key"
export DAYTONA_API_URL="https://app.daytona.io/api"
export DAYTONA_TARGET="us" # 指定目标区域

代码初始化方式(适用于多环境切换):

import (
"log"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

client, err := daytona.NewClientWithConfig(&types.DaytonaConfig{
APIKey: "your-api-key",
APIUrl: "https://app.daytona.io/api",
Target: "us",
})
if err != nil {
log.Fatal(err)
}

使用示例

示例一:创建沙箱并执行代码

最基础的使用场景——创建一个沙箱,在其中执行Go代码并获取结果:

package main

import (
"context"
"fmt"
"log"
"time"

"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

func main() {
client, err := daytona.NewClient()
if err != nil {
log.Fatal(err)
}

ctx := context.Background()

// 创建自定义资源配置的沙箱
params := types.ImageParams{
SandboxBaseParams: types.SandboxBaseParams{
Name: "go-sandbox",
},
Image: "golang:1.22-bookworm",
Resources: &types.Resources{
CPU: 1,
Memory: 2,
Disk: 5,
},
}
sandbox, err := client.Create(ctx, params, options.WithTimeout(150*time.Second))
if err != nil {
log.Fatal(err)
}
defer sandbox.Delete(ctx)

// 执行 shell 命令
response, err := sandbox.Process.ExecuteCommand(ctx, `echo "Hello, Daytona!"`)
if err != nil {
log.Fatal(err)
}
if response.ExitCode != 0 {
fmt.Printf("执行失败:%d - %s\n", response.ExitCode, response.Result)
} else {
fmt.Println(response.Result) // 输出:Hello, Daytona!
}

// 编写并运行 Go 程序
goCode := []byte(`package main
import "fmt"
func main() { fmt.Println("Hello from Daytona sandbox!") }`)
if err := sandbox.FileSystem.UploadFile(ctx, goCode, "/tmp/main.go"); err != nil {
log.Fatal(err)
}
result, err := sandbox.Process.ExecuteCommand(ctx, "go run /tmp/main.go",
options.WithExecuteTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Result) // 输出:Hello from Daytona sandbox!
}

示例二:沙箱生命周期管理

演示沙箱的完整生命周期操作——创建、停止、重启、列举以及删除:

package main

import (
"context"
"fmt"
"log"
"time"

"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

func main() {
client, err := daytona.NewClient()
if err != nil {
log.Fatal(err)
}

ctx := context.Background()

// 创建沙箱并添加标签
sandbox, err := client.Create(ctx, types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Labels: map[string]string{"project": "my-agent", "env": "dev"},
},
}, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}

// 停止沙箱(状态保留,不删除资源)
if err := sandbox.Stop(ctx); err != nil {
log.Fatal(err)
}

// 重新启动沙箱
if err := sandbox.Start(ctx); err != nil {
log.Fatal(err)
}

// 通过 ID 获取已有沙箱
existing, err := client.Get(ctx, sandbox.ID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("沙箱状态: %s\n", existing.State)

// 列举所有沙箱
page, limit := 1, 10
result, err := client.List(ctx, nil, &page, &limit)
if err != nil {
log.Fatal(err)
}
fmt.Printf("当前共有 %d 个沙箱\n", result.Total)

// 删除沙箱
if err := sandbox.Delete(ctx); err != nil {
log.Fatal(err)
}
}

示例三:文件系统操作

演示在沙箱内进行文件上传、下载、搜索以及内容替换等文件系统操作:

package main

import (
"context"
"encoding/json"
"fmt"
"log"
"time"

"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

func main() {
client, err := daytona.NewClient()
if err != nil {
log.Fatal(err)
}

ctx := context.Background()
sandbox, err := client.Create(ctx, types.SnapshotParams{},
options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
defer sandbox.Delete(ctx)

// 创建目录
if err := sandbox.FileSystem.CreateFolder(ctx, "project",
options.WithMode("0755")); err != nil {
log.Fatal(err)
}

// 上传脚本文件(从本地路径)
if err := sandbox.FileSystem.UploadFile(ctx,
"local_script.go", "project/script.go"); err != nil {
log.Fatal(err)
}

// 上传配置文件(从内存字节)
configData, _ := json.MarshalIndent(
map[string]any{"debug": true, "maxConnections": 10}, "", " ")
if err := sandbox.FileSystem.UploadFile(ctx,
configData, "project/config.json"); err != nil {
log.Fatal(err)
}

// 搜索文件
matches, err := sandbox.FileSystem.FindFiles(ctx, "project", "*.json")
if err != nil {
log.Fatal(err)
}
fmt.Println("找到的 JSON 文件:", matches)

// 替换文件内容
if _, err := sandbox.FileSystem.ReplaceInFiles(ctx,
[]string{"project/config.json"},
`"debug": true`, `"debug": false`); err != nil {
log.Fatal(err)
}

// 下载文件到本地
localPath := "local-config.json"
if _, err := sandbox.FileSystem.DownloadFile(ctx,
"project/config.json", &localPath); err != nil {
log.Fatal(err)
}
}

示例四:网络隔离与白名单控制

演示如何控制沙箱的网络访问权限,适用于沙箱执行不可信代码时的安全加固:

package main

import (
"context"
"fmt"
"log"
"time"

"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

func main() {
client, err := daytona.NewClient()
if err != nil {
log.Fatal(err)
}

ctx := context.Background()

// 完全阻断网络(最高安全级别,适合执行完全不可信的代码)
sandboxIsolated, err := client.Create(ctx, types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
NetworkBlockAll: true,
},
}, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
defer sandboxIsolated.Delete(ctx)

// 仅允许访问指定网段(如内网服务)
allowList := "10.0.0.0/8,192.168.1.100/32"
sandboxRestricted, err := client.Create(ctx, types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
NetworkAllowList: &allowList,
},
}, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
defer sandboxRestricted.Delete(ctx)

// 在隔离沙箱中测试网络访问
result, err := sandboxIsolated.Process.ExecuteCommand(ctx,
`curl -s --max-time 3 https://example.com && echo "网络访问成功" || echo "网络访问被阻断"`)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Result)
}

示例五:持久化卷跨沙箱共享数据

演示如何利用持久化卷在多个沙箱间共享数据,以及通过subpath实现多租户隔离:

package main

import (
"context"
"fmt"
"log"
"time"

"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

func main() {
client, err := daytona.NewClient()
if err != nil {
log.Fatal(err)
}

ctx := context.Background()

// 创建持久化卷并等待就绪
volume, err := client.Volume.Create(ctx, "shared-data")
if err != nil {
log.Fatal(err)
}
volume, err = client.Volume.WaitForReady(ctx, volume, 60*time.Second)
if err != nil {
log.Fatal(err)
}
defer client.Volume.Delete(ctx, volume)

// 第一个沙箱:写入数据到卷
sandbox1, err := client.Create(ctx, types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Volumes: []types.VolumeMount{
{VolumeID: volume.ID, MountPath: "/data"},
},
},
}, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
defer sandbox1.Delete(ctx)

if err := sandbox1.FileSystem.UploadFile(ctx,
[]byte("Hello from sandbox1!"), "/data/message.txt"); err != nil {
log.Fatal(err)
}

// 第二个沙箱:从同一卷读取数据
sandbox2, err := client.Create(ctx, types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Volumes: []types.VolumeMount{
{VolumeID: volume.ID, MountPath: "/shared"},
},
},
}, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
defer sandbox2.Delete(ctx)

content, err := sandbox2.FileSystem.DownloadFile(ctx, "/shared/message.txt", nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("读取到的数据:", string(content)) // 输出:Hello from sandbox1!

// 多租户隔离:通过 subpath 让不同沙箱只看到卷的特定子路径
subpath := "users/alice"
sandboxAlice, err := client.Create(ctx, types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Volumes: []types.VolumeMount{
{VolumeID: volume.ID, MountPath: "/home/daytona", Subpath: &subpath},
},
},
}, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
defer sandboxAlice.Delete(ctx)
}

示例六:在 AI 智能体工作流中集成沙箱执行

以下示例展示如何将Daytona Go SDK集成到AI智能体工作流中,构建一个能在沙箱中安全执行LLM所生成Go代码的代码生成智能体:

package main

import (
"context"
"fmt"
"log"
"time"

"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

// executeLLMCode 在沙箱中安全运行 LLM 生成的 Go 代码,返回执行输出
func executeLLMCode(ctx context.Context, sandbox *daytona.Sandbox, code string) (string, error) {
// 将代码写入沙箱临时文件
if err := sandbox.FileSystem.UploadFile(ctx, []byte(code), "/tmp/llm_result.go"); err != nil {
return "", fmt.Errorf("上传代码失败: %w", err)
}
// 编译并执行
result, err := sandbox.Process.ExecuteCommand(ctx, "go run /tmp/llm_result.go",
options.WithExecuteTimeout(30*time.Second),
)
if err != nil {
return "", err
}
if result.ExitCode != 0 {
return "", fmt.Errorf("代码执行失败 (exit %d): %s", result.ExitCode, result.Result)
}
return result.Result, nil
}

func main() {
client, err := daytona.NewClient()
if err != nil {
log.Fatal(err)
}

ctx := context.Background()

// 为本次智能体任务创建专属沙箱(整个对话周期共享同一沙箱)
sandbox, err := client.Create(ctx, types.ImageParams{
SandboxBaseParams: types.SandboxBaseParams{
Labels: map[string]string{"task": "code-generator", "agent": "llm"},
},
Image: "golang:1.22-bookworm",
}, options.WithTimeout(150*time.Second))
if err != nil {
log.Fatal(err)
}
defer sandbox.Delete(ctx)

// ------- 此处调用 LLM 接口获取生成代码(示意,实际替换为 LLM API 调用) -------
generatedCode := `package main

import "fmt"

func fibonacci(n int, memo map[int]int) int {
if n <= 1 { return n }
if v, ok := memo[n]; ok { return v }
memo[n] = fibonacci(n-1, memo) + fibonacci(n-2, memo)
return memo[n]
}

func main() {
memo := make(map[int]int)
fmt.Println(fibonacci(10, memo)) // 输出:55
}`
// -----------------------------------------------------------------------

// 在沙箱中安全执行 LLM 生成的代码,不影响宿主机
output, err := executeLLMCode(ctx, sandbox, generatedCode)
if err != nil {
fmt.Printf("执行失败: %v\n", err)
return
}
fmt.Printf("智能体验证结果:\n%s\n", output)
}

平台功能总览

Daytona的功能体系按用途分为五大类:

平台管理(Platform)

面向组织和运维管理员的治理与运营控制功能:

功能说明
组织管理多组织隔离,支持成员、权限与配额管理
API Key管理生成、撤销和查看API密钥
配额与限制每个组织可设置CPU/内存/磁盘/快照的总量与单沙箱上限
计费按实际资源使用量计费
审计日志记录所有操作行为,支持合规审计
OpenTelemetry基于OTEL协议的链路追踪与指标采集
集成与主流AI框架和工具的官方集成指南

沙箱能力(Sandboxes)

沙箱本身提供的核心计算与存储能力:

功能说明
环境配置基础镜像、资源规格、环境变量等配置
快照有状态环境快照,支持跨会话恢复
声明式构建器通过YAML描述依赖环境,自动构建快照
卷存储持久化卷,支持跨沙箱数据共享
多区域部署在不同地理区域启动沙箱,降低延迟

智能体工具(Agent Tools)

智能体通过SDKAPI调用的编程能力:

功能说明
进程与代码执行exec命令执行与有状态代码解释器
文件系统操作文件上传、下载、搜索、替换等
语言服务器协议LSP支持,为AI编码智能体提供代码感知能力
计算机使用截图、鼠标键盘操控、屏幕交互
MCP Server标准MCP协议服务端,供LLM直接调用
Git操作仓库克隆、提交、分支管理等
伪终端交互式PTY会话
日志流式传输实时流式获取沙箱执行日志

人工工具(Human Tools)

供人类用户直接访问和操控沙箱的界面:

功能说明
DashboardWeb可视化控制台
Web终端浏览器内嵌终端,直接访问沙箱
SSH访问标准SSH客户端连接沙箱
VNC访问图形桌面远程访问
VPN连接通过VPN组网接入沙箱
预览代理为沙箱内Web应用生成可公开访问的预览URL
操场(Playground在线快速体验沙箱能力

系统工具(System Tools)

平台级钩子和控制能力:

功能说明
Webhook沙箱生命周期事件的Webhook通知
网络限制细粒度的沙箱出入站网络访问控制

典型应用场景

AI 代码生成与验证

LLM代码生成管道中,将Daytona作为安全的代码执行沙箱:LLM生成代码 → 沙箱中执行并运行测试 → 返回执行结果给LLM进行自我修正 → 输出验证通过的代码。这个闭环完全在隔离的沙箱环境中完成,对宿主系统零风险。

多租户代码执行平台

构建面向多用户的在线代码执行服务(如Jupyter替代方案、在线编程竞赛平台、数据分析工作台)时,利用Daytona的快速启动和严格资源隔离特性,每个用户获得独立的计算环境,资源使用互不影响。

自动化智能体任务

在复杂的多步骤智能体任务中(如数据分析流水线、代码重构智能体、DevOps自动化),利用Daytona快照功能保存中间状态,允许任务在中断后从检查点恢复,避免从头重新执行耗时的初始化步骤。

安全沙箱化插件执行

在插件化架构的AI产品中(如编程助手、数据科学工具),用户安装和运行的第三方插件或工具在Daytona沙箱中执行,天然隔离于主应用进程,防止恶意插件对系统造成影响。

与同类项目的对比

以下对比基于三个项目的公开源码与官方文档,围绕定位、安全模型、SDK 支持、部署方式、网络控制、AI 集成等核心维度展开。

OpenSandbox(阿里巴巴)

OpenSandbox协议标准化为核心设计理念,通过 OpenAPI 规范定义沙箱生命周期接口(sandbox-lifecycle.yml)和执行接口(execd-api.yaml),将沙箱能力抽象为统一的API层。同一套接口可接入 DockerKubernetes/BatchSandbox 不同运行时,以及 gVisorKata-Containers(支持 QEMUFirecrackerCLH)等多种安全运行时,适合需要在多种AI框架和运行环境之间灵活切换的团队。

其内置的 Egress 边车组件基于 FQDN 白名单 + nftables 实现出站流量拦截,Ingress 网关支持基于HeaderURI 的路由,网络策略开箱即用。官方 MCP Serveropensandbox-mcp)使 Claude CodeCursor 等工具可直接通过 MCP 协议操作沙箱。项目已进入 CNCF Landscape,是三者中唯一具备沙箱协议标准化愿景的项目。

Daytona(daytonaio)

Daytona 定位为面向AI生成代码的弹性基础设施,强调快速启动(< 90ms)、状态持久化与平台完整性。每个沙箱是一个以 OCI/Docker 标准容器为基础的隔离执行单元,拥有独立分配的 vCPURAM、磁盘和网络栈。架构分为三个平面:接口层(CLIDashboardSDKREST API),控制面(NestJS API 负责编排、Snapshot ManagerSSH GatewayProxy)和计算面(Runner 节点 + 沙箱内 Daemon 代理)。

底层实现上,Runner 直接调用 Docker SDK 创建容器(--privileged 特权模式),并通过宿主机 iptables 规则对每个容器的 IP 单独设置出入站限制,实现比 Docker 原生网络隔离更细粒度的管控。< 90ms 冷启动依赖预热池(Warm Pool——提前维持一批待命容器,请求到来时直接分配。Daytona 目前仅支持 Docker 运行时,没有 gVisor/Kata 等内核级安全运行时,也无 Kubernetes 适配器,计算节点选择由内置的7维加权调度器管理。

面向开发者的功能极为完整:DashboardWeb UI)、Web TerminalSSHVNCVPN、预览 URLLSP 支持、Computer UseGit 操作、日志流等。Snapshots 功能支持将容器状态序列化为 OCI 镜像,后续沙箱可直接从快照启动,为跨会话的 Agent 工作流提供持久化保障。多语言 SDK 覆盖 PythonTypeScriptRubyGoJava 共五种语言。已推出托管云服务(app.daytona.io),同时支持自托管(Docker Compose)和混合部署(托管控制面 + 自有计算节点)。

OpenShell(NVIDIA)

OpenShell 是三者中安全机制最为深度的项目,定位为自主 AI Agent 的安全隐私运行时。核心思路是"纵深防御":在Linux内核层面叠加四层隔离——Landlock LSM(文件系统访问控制)、Seccomp BPF(系统调用过滤)、网络命名空间(隔离出站流量,经 HTTP CONNECT 代理中转)和 OPA/Rego 策略引擎(基于进程身份 + 目标 FQDN + HTTP Method/Path 的七层决策)。

网络侧还引入了 Privacy Router(推理路由器),能够透明拦截对AI Inference API的请求,剥离调用方凭据并注入后端凭据,避免API Key泄露至沙箱文件系统。策略以声明式 YAML 描述,静态字段(文件系统/进程)在创建时锁定,动态字段(网络/推理路由)支持热更新(openshell policy set),无需重启沙箱。内置对 Claude CodeOpenCodeCodexGitHub Copilot CLI 的原生支持,凭据通过 Provider 机制注入为环境变量(从不写入磁盘)。基础设施以 K3s(轻量级 Kubernetes)内嵌于单一 Docker 容器中运行,支持 GPU 直通(--gpu,实验性)。当前为 Alpha 阶段,主打单机开发者场景,企业级多租户部署在路线图中。

三维对比速查表

维度OpenSandbox(阿里巴巴)Daytona(daytonaio)OpenShell(NVIDIA)
项目定位协议标准化的AI沙箱平台AI代码执行弹性基础设施自主Agent安全隐私运行时
开源协议Apache 2.0Apache 2.0 / AGPL-3.0Apache 2.0
核心语言Python(服务端)+ 多语言 SDKGoCLI/Runner)+ TypeScriptAPI)+ 多语言 SDKRust(核心)+ Python SDK
多语言 SDKPython·Java/Kotlin·TypeScript·C#/.NET·GoPython·TypeScript·Ruby·Go·JavaPython(主要),CLI 为主入口
沙箱隔离机制gVisor/KataQEMU/Firecracker/CLH)/runc(可选)OCI/Docker 容器(--privileged)+ iptables 双重网络隔离;无 gVisor/Kata 硬化运行时Landlock LSM + Seccomp BPF + 网络命名空间 + OPA 策略引擎(四层纵深防御)
容器运行时Docker / containerd(经 Kubernetes CRI);安全运行时(gVisor/Kata)均为 OCI兼容 shimDocker EngineRunnerDinD 模式运行,内部依赖 Docker 守护进程;无裸 containerd CRI 接入)containerdK3s 默认容器运行时;沙箱以 K8s Pod 运行于内嵌 K3s 集群中)
网络出口控制Egress 边车:FQDN 白名单 + nftablesnetwork_block_all 全封断 / network_allow_list CIDR 白名单 + iptables 细粒度规则OPA/Rego 七层策略 + 热更新;Privacy Router 推理路由
AI 推理隐私保护无内置机制无内置机制有(Privacy Router:剥离来源凭据,注入后端凭据)
凭据管理无内置机制无内置机制Provider 机制(环境变量注入,从不落盘)
MCP 集成官方 MCP Serveropensandbox-mcp官方 MCP Server
GPU 支持--gpu 直通(实验性)
状态快照Snapshots(OCI 镜像快照,跨会话持久化)
部署方式Docker / KubernetesDocker Compose(自托管)/ 托管云 / 混合部署K3s-in-Docker(单容器)/ 远程主机
人工操作界面CLIosbDashboard·Web Terminal·SSH·VNC·VPN·预览 URLTUI(类 k9s)·SSH
协议标准化OpenAPI 规范(sandbox-lifecycle.yml + execd-api.yaml);CNCF Landscape自有 REST API(无统一沙箱协议规范)gRPCproto/sandbox.proto);无通用标准
大规模调度Kubernetes 原生(BatchSandbox/agent-sandboxRegion + 多 Runner 节点水平扩展Alpha 阶段,单机为主;企业级多租户待支持
调度器Kubernetes 原生调度器(kube-scheduler)—— K8s 运行时模式;Docker 模式无集中调度自研 7 维加权调度器(按 CPU/内存/磁盘/已分配资源等评分,选最优 Runner 节点;无 Kubernetes 依赖)K3s 内嵌 kube-schedulerAlpha 阶段为单节点,多节点调度尚未支持
成熟度生产可用,CNCF Landscape生产可用,已有托管云Alpha,主打开发者个人场景
适用场景AI框架集成、代码沙箱标准化、大规模 K8s 批量任务AI Coding Agent 平台、持久化 Agent 工作流、组织级管控单机 Coding Agent 安全运行、AI 推理隐私保护

如何选择

  • 若需要将沙箱能力统一接入多个 AI 框架,或需要大规模 Kubernetes 批量沙箱调度,OpenSandbox 的协议标准化设计和原生 K8s 支持是最优选。
  • 若需要构建一个面向组织的 AI Coding Agent 平台,需要完整的用户管理、持久化快照、Dashboard、多区域部署和丰富的人工交互界面(VNC/SSH/VPN),Daytona 提供了最完整的平台工程体验。
  • 若是开发者个人使用 Claude Code/Codex 等 Agent,关注凭据安全、推理隐私和网络访问控制,希望用声明式 YAML 策略精细限制 Agent 的文件/网络行为,OpenShell 提供了目前最深度的安全纵深防御机制,但需接受其 Alpha 阶段的稳定性现状。

总结

Daytona以沙箱为核心,构建了一套专为AI智能体时代设计的安全弹性代码执行基础设施。它解决了AI生成代码在生产环境中安全执行的核心难题,通过不超过90ms的冷启动速度、严格的资源与网络隔离、有状态快照机制以及丰富的多语言SDK,为智能体工作流提供了坚实的执行底座。

无论是构建代码生成验证管道、多租户执行平台,还是需要有状态复现的复杂智能体任务,Daytona都提供了从单机本地部署到云端全托管的灵活选择,是AI应用开发者值得深入了解和应用的基础设施工具。