全栈应用服务器

  • 全栈应用服务器 > SDK 下载 > Go SDK 概览 > 沙箱管理

    沙箱管理

    最近更新时间: 2026-03-05 19:04:47

    沙箱管理

    本文档介绍如何使用 Go SDK 进行沙箱实例的创建、连接、列出、生命周期管理等操作。

    前置条件:请先完成客户端初始化

    创建沙箱

    基本创建

    使用 Create 方法创建沙箱,沙箱创建后需要轮询等待就绪。

    timeout := int32(300) // 超时时间(秒)
    sb, err := c.Create(ctx, sandbox.CreateParams{
    	TemplateID: "base",
    	Timeout:    &timeout,
    })
    if err != nil {
    	log.Fatalf("创建沙箱失败: %v", err)
    }
    defer sb.Kill(ctx)
    
    fmt.Printf("沙箱 ID: %s\n", sb.ID())
    

    创建并等待就绪

    推荐使用 CreateAndWait,它会自动轮询直到沙箱进入 running 状态。

    timeout := int32(120)
    sb, info, err := c.CreateAndWait(ctx, sandbox.CreateParams{
    	TemplateID: "base",
    	Timeout:    &timeout,
    }, sandbox.WithPollInterval(2*time.Second))
    if err != nil {
    	log.Fatalf("创建沙箱失败: %v", err)
    }
    defer sb.Kill(ctx)
    
    fmt.Printf("沙箱已就绪: %s (CPU: %d 核, 内存: %d MB)\n", sb.ID(), info.CPUCount, info.MemoryMB)
    

    创建参数

    CreateParams 支持以下参数:

    参数 类型 必填 说明
    TemplateID string 模板 ID
    Timeout *int32 超时时间(秒),默认 300 秒
    AutoPause *bool 超时后是否自动暂停
    AllowInternetAccess *bool 是否允许访问互联网
    Secure *bool 安全通信模式
    EnvVars *map[string]string 环境变量
    Metadata *Metadata 自定义元数据(key-value)
    Network *NetworkConfig 网络配置

    带元数据和网络配置创建

    timeout := int32(120)
    meta := sandbox.Metadata{"userId": "123", "env": "dev"}
    allowPublic := true
    network := sandbox.NetworkConfig{
    	AllowPublicTraffic: &allowPublic,
    }
    
    sb, info, err := c.CreateAndWait(ctx, sandbox.CreateParams{
    	TemplateID: "base",
    	Timeout:    &timeout,
    	Metadata:   &meta,
    	Network:    &network,
    }, sandbox.WithPollInterval(2*time.Second))
    

    网络配置

    NetworkConfig 支持以下参数:

    参数 类型 说明
    AllowOut *[]string 允许的出站流量 CIDR 列表
    AllowPublicTraffic *bool 是否允许公共流量访问沙箱 URL
    DenyOut *[]string 拒绝的出站流量 CIDR 列表
    MaskRequestHost *string 沙箱请求的 host 掩码

    连接到已有沙箱

    使用 Connect 重新连接到活动的沙箱实例,也可以恢复已暂停的沙箱。

    sb, err := c.Connect(ctx, "sandbox-id", sandbox.ConnectParams{
    	Timeout: 300, // 值类型 int32,非指针
    })
    if err != nil {
    	log.Fatalf("连接沙箱失败: %v", err)
    }
    
    fmt.Printf("已连接到沙箱: %s (模板: %s)\n", sb.ID(), sb.TemplateID())
    

    注意: ConnectParams.Timeoutint32 值类型(非指针),与 CreateParams.Timeout*int32 指针类型)不同。

    连接后可以正常使用沙箱的所有功能(命令执行、文件操作等)。

    列出沙箱

    列出所有沙箱

    sandboxes, err := c.List(ctx, nil)
    if err != nil {
    	log.Fatalf("列出沙箱失败: %v", err)
    }
    
    for _, sb := range sandboxes {
    	fmt.Printf("ID: %s, 模板: %s, 状态: %s\n", sb.SandboxID, sb.TemplateID, sb.State)
    }
    

    按状态过滤

    states := []sandbox.SandboxState{sandbox.StateRunning}
    sandboxes, err := c.List(ctx, &sandbox.ListParams{
    	State: &states,
    })
    

    支持的状态:

    • sandbox.StateRunning - 运行中
    • sandbox.StatePaused - 已暂停

    按元数据过滤

    metadata := "userId=123&env=dev"
    sandboxes, err := c.List(ctx, &sandbox.ListParams{
    	Metadata: &metadata,
    })
    

    分页查询

    limit := int32(10)
    sandboxes, err := c.List(ctx, &sandbox.ListParams{
    	Limit: &limit,
    })
    

    使用 NextToken 翻页:

    // 首次查询
    limit := int32(10)
    first, err := c.List(ctx, &sandbox.ListParams{Limit: &limit})
    
    // 获取下一页(从上次响应中获取 NextToken)
    nextToken := "..." // 从上一次查询获取
    next, err := c.List(ctx, &sandbox.ListParams{
    	Limit:     &limit,
    	NextToken: &nextToken,
    })
    

    列表项字段

    ListedSandbox 包含以下字段:

    字段 类型 说明
    SandboxID string 沙箱 ID
    TemplateID string 模板 ID
    ClientID string 客户端 ID
    Alias *string 别名
    State SandboxState 状态
    CPUCount int32 CPU 核数
    MemoryMB int32 内存大小(MB)
    DiskSizeMB int32 磁盘大小(MB)
    StartedAt time.Time 启动时间
    EndAt time.Time 过期时间
    Metadata *Metadata 自定义元数据

    获取沙箱信息

    info, err := sb.GetInfo(ctx)
    if err != nil {
    	log.Fatalf("获取信息失败: %v", err)
    }
    
    fmt.Printf("状态: %s, CPU: %d, 内存: %d MB\n", info.State, info.CPUCount, info.MemoryMB)
    fmt.Printf("开始时间: %s, 结束时间: %s\n", info.StartedAt, info.EndAt)
    

    检查运行状态

    IsRunning 通过探测沙箱内部 envd agent 的 /health 端点检查沙箱是否可用。与 GetInfo(查询控制面状态)不同,此方法直接验证沙箱内部 agent 是否可达。

    running, err := sb.IsRunning(ctx)
    if err != nil {
    	log.Fatalf("检查状态失败: %v", err)
    }
    fmt.Printf("沙箱是否运行中: %v\n", running)
    
    • 返回 true:沙箱运行中且 envd agent 已就绪
    • 返回 false:沙箱不可达(已暂停、已终止等)

    更新超时时间

    新的超时时间从当前时刻开始计算,最小值为 1 秒。

    if err := sb.SetTimeout(ctx, 10*time.Minute); err != nil {
    	log.Fatalf("更新超时失败: %v", err)
    }
    

    延长存活时间

    duration := 300 // 延长 300 秒
    if err := sb.Refresh(ctx, sandbox.RefreshParams{
    	Duration: &duration,
    }); err != nil {
    	log.Fatalf("延长存活时间失败: %v", err)
    }
    

    暂停和恢复

    沙箱暂停后会保留文件系统和内存状态,可以通过 Connect 恢复。

    暂停沙箱

    if err := sb.Pause(ctx); err != nil {
    	log.Fatalf("暂停失败: %v", err)
    }
    
    // 确认状态
    info, _ := sb.GetInfo(ctx)
    fmt.Printf("当前状态: %s\n", info.State) // paused
    

    恢复沙箱

    resumed, err := c.Connect(ctx, sb.ID(), sandbox.ConnectParams{
    	Timeout: 120,
    })
    if err != nil {
    	log.Fatalf("恢复失败: %v", err)
    }
    
    // 等待恢复就绪
    readyInfo, err := resumed.WaitForReady(ctx, sandbox.WithPollInterval(2*time.Second))
    if err != nil {
    	log.Fatalf("等待就绪失败: %v", err)
    }
    fmt.Printf("沙箱已恢复: %s (状态: %s)\n", resumed.ID(), readyInfo.State)
    

    终止沙箱

    Kill 会立即终止沙箱,无论剩余超时时间如何。

    if err := sb.Kill(ctx); err != nil {
    	log.Fatalf("终止沙箱失败: %v", err)
    }
    

    网络访问

    使用 GetHost 获取外部访问沙箱指定端口的域名。

    host := sb.GetHost(8080)
    fmt.Printf("端口 8080 访问地址: %s\n", host)
    // 输出格式: 8080-{sandboxID}.{domain}
    

    指标和日志

    获取资源指标

    metrics, err := sb.GetMetrics(ctx, nil)
    if err != nil {
    	log.Fatalf("获取指标失败: %v", err)
    }
    for _, m := range metrics {
    	fmt.Printf("CPU: %d 核 (%.1f%%), 内存: %d/%d, 磁盘: %d/%d\n",
    		m.CPUCount, m.CPUUsedPct, m.MemUsed, m.MemTotal, m.DiskUsed, m.DiskTotal)
    }
    

    可以指定时间范围:

    start := time.Now().Add(-1 * time.Hour).Unix()
    end := time.Now().Unix()
    metrics, err := sb.GetMetrics(ctx, &sandbox.GetMetricsParams{
    	Start: &start,
    	End:   &end,
    })
    

    获取日志

    logs, err := sb.GetLogs(ctx, nil)
    if err != nil {
    	log.Fatalf("获取日志失败: %v", err)
    }
    for _, l := range logs.Logs {
    	fmt.Printf("[%s] %s\n", l.Timestamp, l.Line)
    }
    
    // 结构化日志
    for _, e := range logs.LogEntries {
    	fmt.Printf("[%s] [%s] %s\n", e.Timestamp, e.Level, e.Message)
    }
    

    可以指定查询参数:

    start := time.Now().Add(-30 * time.Minute).UnixMilli()
    limit := int32(100)
    logs, err := sb.GetLogs(ctx, &sandbox.GetLogsParams{
    	Start: &start,
    	Limit: &limit,
    })
    

    批量获取指标

    ids := []string{"sandbox-id-1", "sandbox-id-2"}
    metrics, err := c.GetSandboxesMetrics(ctx, &sandbox.GetSandboxesMetricsParams{
    	SandboxIds: ids,
    })
    if err != nil {
    	log.Fatalf("获取批量指标失败: %v", err)
    }
    for id, m := range metrics.Sandboxes {
    	fmt.Printf("沙箱 %s: CPU %.1f%%\n", id, m.CPUUsedPct)
    }
    
    以上内容是否对您有帮助?