OpenSandbox Kubernetes 控制器
OpenSandbox Kubernetes 控制器,通过自定义资源管理沙箱环境。它在 Kubernetes 集群中提供自动化沙箱生命周期管理、资源池化以实现快速供应、批处理沙箱创建和可选的任务编排功能。
关键特性
- 灵活的沙箱创建:在池化和非池化沙箱创建模式之间选择
- 批处理和单个交付:支持单个沙箱(用于真实用户交互)和批处理沙箱交付(用于高吞吐量智能体强化学习场景)
- 可选任务调度:集成任务编排,支持可选的分片任务模板以实现异构任务分发和定制化沙箱交付(例如,进程注入)
- 资源池化:维护预热的资源池以实现快速沙箱供应
- 全面监控:实时跟踪沙箱和任务状态
功能特性
批处理沙箱管理
BatchSandbox 自定义资源允许您创建和管理多个相同的沙箱环境。主要功能包括:
- 灵活的创建模式:支持池化(使用资源池)和非池化沙箱创建
- 单个和批处理交付:根据需要创建单个沙箱(replicas=1)或批处理沙箱(replicas=N)
- 可扩展的副本管理:通过副本配置轻松控制沙箱实例数量
- 自动过期:设置 TTL(生存时间)以自动清理过期沙箱
- 可选任务调度:内置任务执行引擎,支持可选任务模板
- 详细状态报告:关于副本、分配和任务状态的综合指标
资源池化
Pool 自定义资源维护一个预热的计算资源池,以实现快速沙箱供应:
- 可配置的缓冲区大小(最小和最大)以平衡资源可用性和成本
- 池容量限制以控制总体资源消耗
- 基于需求的自动资源分配和释放
- 实时状态监控,显示总数、已分配和可用资源
任务编排
集成的任务管理系统,在沙箱内执行自定义工作负载:
- 可选执行:任务调度完全可选 - 可以在不带任务的情况下创建沙箱
- 基于进程的任务:支持在沙箱环境中执行基于进程的任务
- 异构任务分发:使用 shardTaskPatches 为批处理中的每个沙箱定制单独的任务
高级调度
智能资源管理功能:
- 最小和最大缓冲区设置,以确保资源可用性同时控制成本
- 池范围的容量限制,防止资源耗尽
- 基于需求的自动扩展
与 kubernates-sigs/agent-sandbox 的关系
BatchSandbox 并非重复实现 Agent-Sandbox 的基础功能,而是作为其补充,提供了额外的增强能力:
- 批量 Sandbox 语义:在强化学习(RL)训练等场景下,显著提升 Sandbox 的交付吞吐量
- Task 调度能力:通过 Task 调度实现差异化 Sandbox 交付,例如在交付 Sandbox 之前向容器内注入自定义进程
因此,您可以根据具体应用场景选择合适的项目作为 Sandbox 底层运行时。
性能测试
BatchSandbox 与 Sig Agent-Sandbox 在吞吐量方面的性能对比测试。
测试环境
Controller 组件配置
- 资源规格:request: 12C32G, limit: 16C64G
- 并发配置:
- Sig Agent-Sandbox:共 3 个 controller(sandbox、sandboxclaim、sandboxwarmppool),代码中未提供并发度配置,默认值为 1
- BatchSandbox:共 2 个 controller,batchsandbox controller 并发度为 32,pool controller 并发度为 1
Pool 配置
- 镜像:busybox:latest
- 资源规格:0.1C256MB
补充说明:虽然 BatchSandbox 的 batchsandbox-controller 并发度为 32,但测试用例中仅创建了一个 BatchSandbox 对象,实际等价于并发度为 1。因此在并发度方面,BatchSandbox 与 SIG Agent-Sandbox 保持一致。
性能对比结果
在都使用资源池的情况下,交付 100 个 Sandbox 的总耗时对比:
| 测试场景 | 总耗时 (秒) |
|---|---|
| SIG Agent-Sandbox (创建并发=1) | 76.35 |
| SIG Agent-Sandbox (创建并发=10) | 23.17 |
| SIG Agent-Sandbox (创建并发=50) | 33.85 |
| BatchSandbox | 0.92 |
原因分析
核心差异:Sig Agent-Sandbox 和 BatchSandbox 批量交付 N 个 Sandbox 的时间复杂度分别为 O(N) 和 O(1)。
Sig Agent-Sandbox 原理
- 每个 Sandbox 的交付流程需要执行以下写操作(写操作总数与 Sandbox 规模成正比):
- 创建一个 SandboxClaim
- 创建一个 Sandbox
- 更新 Pod 一次(从资源池中接管 Pod)
- 更新 Sandbox Status 一次
- 更新 SandboxClaim Status 一次
BatchSandbox 原理
- 每批 Sandbox 的交付流程需要执行以下写操作(写操作总数与 Sandbox 规模无关):
- 创建一个 BatchSandbox
- 更新 BatchSandbox annotation 一次(写入批分配结果)
- 更新 BatchSandbox status 一次
入门指南

先决条件
- go 版本 v1.24.0+
- docker 版本 17.03+
- kubectl 版本 v1.11.3+
- 访问 Kubernetes v1.22.4+ 集群
如果您没有 Kubernetes 集群的访问权限,可以使用 kind 创建一个本地 Kubernetes 集群进行测试。Kind 在 Docker 容器中运行 Kubernetes 节点,使得设置本地开发环境变得容易。
安装 kind:
- 从发布页面下载适用于您操作系统的发布二进制文件并将其移动到
$PATH中 - 或使用包管理器:
- macOS (Homebrew):
brew install kind - Windows (winget):
winget install Kubernetes.kind
- macOS (Homebrew):
安装 kind 后,使用以下命令创建集群:
kind create cluster此命令默认创建单节点集群。要与其交互,请使用生成的 kubeconfig 运行 kubectl。
Kind 用户的重要说明:如果您使用的是 kind 集群,在使用 make docker-build 构建镜像后,需要将控制器和任务执行器镜像加载到 kind 节点中。这是因为 kind 在 Docker 容器中运行 Kubernetes 节点,无法直接访问本地 Docker 守护进程中的镜像。
使用以下命令将镜像加载到 kind 集群中:
kind load docker-image <controller-image-name>:<tag>
kind load docker-image <task-executor-image-name>:<tag>例如,如果您使用 make docker-build IMG=my-controller:latest 构建镜像,则使用以下命令加载:
kind load docker-image my-controller:latest完成后使用以下命令删除集群:
kind delete cluster有关使用 kind 的更多详细说明,请参阅官方 kind 文档。
部署
此项目需要两个独立的镜像 - 一个用于控制器,另一个用于任务执行器组件。
构建和推送您的镜像:
sh# 构建和推送控制器镜像 make docker-build docker-push IMG=<some-registry>/opensandbox-controller:tag # 构建和推送任务执行器镜像 make docker-build-task-executor docker-push-task-executor TASK_EXECUTOR_IMG=<some-registry>/opensandbox-task-executor:tag注意: 这些镜像应该发布在您指定的个人注册表中。需要能够从工作环境中拉取镜像。如果上述命令不起作用,请确保您对注册表具有适当的权限。
将 CRD 安装到集群中:
shmake install将管理器部署到集群:
shmake deploy IMG=<some-registry>/opensandbox-controller:tag TASK_EXECUTOR_IMG=<some-registry>/opensandbox-task-executor:tag注意:您可能需要授予自己集群管理员权限或以管理员身份登录以确保您在运行命令之前具有集群管理员权限。
Kind 用户的重要说明:如果您使用的是 kind 集群,需要在构建镜像后将两个镜像都加载到 kind 节点中:
kind load docker-image <controller-image-name>:<tag>
kind load docker-image <task-executor-image-name>:<tag>创建 BatchSandbox 和 Pool 资源
基础示例
创建一个简单的非池化沙箱,不带任务调度:
apiVersion: sandbox.opensandbox.io/v1alpha1
kind: BatchSandbox
metadata:
name: basic-batch-sandbox
spec:
replicas: 2
template:
spec:
containers:
- name: sandbox-container
image: nginx:latest
ports:
- containerPort: 80应用批处理沙箱配置:
kubectl apply -f basic-batch-sandbox.yaml检查批处理沙箱状态:
kubectl get batchsandbox basic-batch-sandbox -o wide示例输出:
NAME DESIRED TOTAL ALLOCATED READY EXPIRE AGE
basic-batch-sandbox 2 2 2 2 <none> 5m状态字段说明:
- DESIRED:请求的沙箱数量
- TOTAL:创建的沙箱总数
- ALLOCATED:成功分配的沙箱数量
- READY:准备使用的沙箱数量
- EXPIRE:过期时间(未设置时为空)
- AGE:资源创建以来的时间
沙箱准备好后,您可以在注解中找到端点信息:
kubectl get batchsandbox basic-batch-sandbox -o jsonpath='{.metadata.annotations.sandbox\.opensandbox\.io/endpoints}'这将显示交付沙箱的 IP 地址。
高级示例
不带任务的池化沙箱
首先,创建一个资源池:
apiVersion: sandbox.opensandbox.io/v1alpha1
kind: Pool
metadata:
name: example-pool
spec:
template:
spec:
containers:
- name: sandbox-container
image: nginx:latest
ports:
- containerPort: 80
capacitySpec:
bufferMax: 10
bufferMin: 2
poolMax: 20
poolMin: 5应用资源池配置:
kubectl apply -f pool-example.yaml使用资源池创建一批沙箱:
apiVersion: sandbox.opensandbox.io/v1alpha1
kind: BatchSandbox
metadata:
name: pooled-batch-sandbox
spec:
replicas: 3
poolRef: example-pool应用批处理沙箱配置:
kubectl apply -f pooled-batch-sandbox.yaml带异构任务的池化沙箱
创建一批带有基于进程的异构任务的沙箱。为了使任务执行正常工作,任务执行器必须作为 sidecar 容器部署在资源池模板中,并与沙箱容器共享进程命名空间:
首先,创建一个带有任务执行器 sidecar 的资源池:
apiVersion: sandbox.opensandbox.io/v1alpha1
kind: Pool
metadata:
name: task-example-pool
spec:
template:
spec:
shareProcessNamespace: true
containers:
- name: sandbox-container
image: ubuntu:latest
command: ["sleep", "3600"]
- name: task-executor
image: <task-executor-image>:<tag>
securityContext:
capabilities:
add: ["SYS_PTRACE"]
capacitySpec:
bufferMax: 10
bufferMin: 2
poolMax: 20
poolMin: 5使用我们刚刚创建的资源池创建一批带有基于进程的异构任务的沙箱:
apiVersion: sandbox.opensandbox.io/v1alpha1
kind: BatchSandbox
metadata:
name: task-batch-sandbox
spec:
replicas: 2
poolRef: task-example-pool
taskTemplate:
spec:
process:
command: ["echo", "Default task"]
shardTaskPatches:
- spec:
process:
command: ["echo", "Custom task for sandbox 1"]
- spec:
process:
command: ["echo", "Custom task for sandbox 2"]
args: ["with", "additional", "arguments"]应用批处理沙箱配置:
kubectl apply -f task-batch-sandbox.yaml检查带任务的批处理沙箱状态:
kubectl get batchsandbox task-batch-sandbox -o wide示例输出:
NAME DESIRED TOTAL ALLOCATED READY TASK_RUNNING TASK_SUCCEED TASK_FAILED TASK_UNKNOWN EXPIRE AGE
task-batch-sandbox 2 2 2 2 0 2 0 0 <none> 5m任务状态字段说明:
- TASK_RUNNING:当前正在执行的任务数
- TASK_SUCCEED:成功完成的任务数
- TASK_FAILED:失败的任务数
- TASK_UNKNOWN:状态未知的任务数
当您删除带有运行任务的 BatchSandbox 时,控制器将首先停止所有任务,然后删除 BatchSandbox 资源。一旦所有任务都成功终止,BatchSandbox 将被完全删除,沙箱将返回到资源池中以供重用。
删除 BatchSandbox:
kubectl delete batchsandbox task-batch-sandbox您可以通过观察 BatchSandbox 状态来监控删除过程:
kubectl get batchsandbox task-batch-sandbox -w监控资源
检查资源池和批处理沙箱的状态:
# 查看资源池状态
kubectl get pools
# 查看批处理沙箱状态
kubectl get batchsandboxes
# 获取特定资源的详细信息
kubectl describe pool example-pool
kubectl describe batchsandbox example-batch-sandbox项目结构
├── api/
│ └── v1alpha1/ # 自定义资源定义(BatchSandbox, Pool)
├── cmd/
│ ├── controller/ # 主控制器管理器入口点
│ └── task-executor/ # 任务执行器二进制文件
├── config/
│ ├── crd/ # 自定义资源定义清单
│ ├── default/ # 控制器部署的默认配置
│ ├── manager/ # 控制器管理器配置
│ ├── rbac/ # 基于角色的访问控制清单
│ └── samples/ # 资源的示例 YAML 清单
├── hack/ # 开发脚本和工具
├── images/ # 文档图片
├── internal/
│ ├── controller/ # 核心控制器实现
│ ├── scheduler/ # 资源分配和调度逻辑
│ ├── task-executor/ # 任务执行引擎内部实现
│ └── utils/ # 实用函数和助手
├── pkg/
│ └── task-executor/ # 共享的任务执行器包
└── test/ # 测试套件贡献
欢迎为 OpenSandbox Kubernetes 控制器项目做出贡献。请随时提交问题、功能请求和拉取请求。
注意: 运行 make help 以获取所有潜在 make 目标的更多信息
更多信息请参见 Kubebuilder 文档
许可证
此项目在 Apache 2.0 许可证下开源。
您可以将 OpenSandbox 用于个人或商业项目,只要遵守许可证条款即可。
此页内容来自仓库源文件:
kubernetes/README-ZH.md