沙箱管理
本文档介绍如何使用 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.Timeout 是 int32 值类型(非指针),与 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)
}
文档反馈
(如有产品使用问题,请 提交工单)