/ kubernetes / README-ZH.md
README-ZH.md
1 # OpenSandbox Kubernetes 控制器 2 3 [English](README.md) | [中文](README-ZH.md) 4 5 OpenSandbox Kubernetes 控制器,通过自定义资源管理沙箱环境。它在 Kubernetes 集群中提供**自动化沙箱生命周期管理**、**资源池化以实现快速供应**、**批处理沙箱创建**和**可选的任务编排**功能。 6 7 ## 关键特性 8 9 - **灵活的沙箱创建**:在池化和非池化沙箱创建模式之间选择 10 - **批处理和单个交付**:支持单个沙箱(用于真实用户交互)和批处理沙箱交付(用于高吞吐量智能体强化学习场景) 11 - **可选任务调度**:集成任务编排,支持可选的分片任务模板以实现异构任务分发和定制化沙箱交付(例如,进程注入) 12 - **资源池化**:维护预热的资源池以实现快速沙箱供应 13 - **全面监控**:实时跟踪沙箱和任务状态 14 15 ## 功能特性 16 17 ### 批处理沙箱管理 18 BatchSandbox 自定义资源允许您创建和管理多个相同的沙箱环境。主要功能包括: 19 - **灵活的创建模式**:支持池化(使用资源池)和非池化沙箱创建 20 - **单个和批处理交付**:根据需要创建单个沙箱(replicas=1)或批处理沙箱(replicas=N) 21 - **可扩展的副本管理**:通过副本配置轻松控制沙箱实例数量 22 - **自动过期**:设置 TTL(生存时间)以自动清理过期沙箱 23 - **可选任务调度**:内置任务执行引擎,支持可选任务模板 24 - **详细状态报告**:关于副本、分配和任务状态的综合指标 25 26 ### 资源池化 27 Pool 自定义资源维护一个预热的计算资源池,以实现快速沙箱供应: 28 - 可配置的缓冲区大小(最小和最大)以平衡资源可用性和成本 29 - 池容量限制以控制总体资源消耗 30 - 基于需求的自动资源分配和释放 31 - 实时状态监控,显示总数、已分配和可用资源 32 33 ### Pod 驱逐 34 Pool 支持优雅的 Pod 驱逐,适用于节点维护或资源回收等场景: 35 36 **工作原理:** 37 - 用户通过给 Pod 打上 `pool.opensandbox.io/evict` 标签请求驱逐 38 - 控制器会跳过已分配给 BatchSandbox 的 Pod(保护使用中的工作负载) 39 - 空闲 Pod 将被删除,触发池补充容量 40 - 标记驱逐的 Pod 不会被分配给新的 BatchSandbox 41 42 **自定义驱逐行为:** 43 您可以通过以下方式实现自定义驱逐策略: 44 1. 在 Pool 上设置 `pool.opensandbox.io/eviction-handler` 标签选择您的处理器 45 2. 实现 `EvictionHandler` 接口,包含 `NeedsEviction()` 和 `Evict()` 方法 46 3. 在工厂函数中注册您的处理器 47 48 ### 任务编排 49 集成的任务管理系统,在沙箱内执行自定义工作负载: 50 - **可选执行**:任务调度完全可选 - 可以在不带任务的情况下创建沙箱 51 - **基于进程的任务**:支持在沙箱环境中执行基于进程的任务 52 - **异构任务分发**:使用 shardTaskPatches 为批处理中的每个沙箱定制单独的任务 53 54 ### 高级调度 55 智能资源管理功能: 56 - 最小和最大缓冲区设置,以确保资源可用性同时控制成本 57 - 池范围的容量限制,防止资源耗尽 58 - 基于需求的自动扩展 59 60 ## 运行时 API 支持说明 61 62 - Kubernetes 运行时当前**不支持** `pause` / `resume` 生命周期 API。 63 - 对 Kubernetes 运行时调用这两个 API 会返回 `501 Not Implemented`。 64 - OpenSandbox 的 pause/resume 语义是保留容器进程内存态后再恢复;当前 Kubernetes provider 主要覆盖 create/get/list/delete/renew 流程。 65 66 67 ## 与 [kubernates-sigs/agent-sandbox](kubernates-sigs/agent-sandbox) 的关系 68 69 BatchSandbox 并非重复实现 Agent-Sandbox 的基础功能,而是作为其补充,提供了额外的增强能力: 70 71 1. **批量 Sandbox 语义**:在强化学习(RL)训练等场景下,显著提升 Sandbox 的交付吞吐量 72 2. **Task 调度能力**:通过 Task 调度实现差异化 Sandbox 交付,例如在交付 Sandbox 之前向容器内注入自定义进程 73 74 因此,您可以根据具体应用场景选择合适的项目作为 Sandbox 底层运行时。 75 76 ### 性能测试 77 78 BatchSandbox 与 Sig Agent-Sandbox 在吞吐量方面的性能对比测试。 79 80 **测试环境** 81 82 **Controller 组件配置** 83 - 资源规格:request: 12C32G, limit: 16C64G 84 - 并发配置: 85 - **Sig Agent-Sandbox**:共 3 个 controller(sandbox、sandboxclaim、sandboxwarmppool),代码中未提供并发度配置,默认值为 1 86 - **BatchSandbox**:共 2 个 controller,batchsandbox controller 并发度为 32,pool controller 并发度为 1 87 88 **Pool 配置** 89 - 镜像:busybox:latest 90 - 资源规格:0.1C256MB 91 92 > **补充说明**:虽然 BatchSandbox 的 batchsandbox-controller 并发度为 32,但测试用例中仅创建了一个 BatchSandbox 对象,实际等价于并发度为 1。因此在并发度方面,BatchSandbox 与 SIG Agent-Sandbox 保持一致。 93 94 **性能对比结果** 95 96 在都使用资源池的情况下,交付 100 个 Sandbox 的总耗时对比: 97 98 | 测试场景 | 总耗时 (秒) | 99 |---------|------------| 100 | SIG Agent-Sandbox (创建并发=1) | 76.35 | 101 | SIG Agent-Sandbox (创建并发=10) | 23.17 | 102 | SIG Agent-Sandbox (创建并发=50) | 33.85 | 103 | BatchSandbox | 0.92 | 104 105 **原因分析** 106 107 核心差异:Sig Agent-Sandbox 和 BatchSandbox 批量交付 N 个 Sandbox 的时间复杂度分别为 O(N) 和 O(1)。 108 109 **Sig Agent-Sandbox 原理** 110 - 每个 Sandbox 的交付流程需要执行以下写操作(写操作总数与 Sandbox 规模成正比): 111 1. 创建一个 SandboxClaim 112 2. 创建一个 Sandbox 113 3. 更新 Pod 一次(从资源池中接管 Pod) 114 4. 更新 Sandbox Status 一次 115 5. 更新 SandboxClaim Status 一次 116 117 **BatchSandbox 原理** 118 - 每批 Sandbox 的交付流程需要执行以下写操作(写操作总数与 Sandbox 规模无关): 119 1. 创建一个 BatchSandbox 120 2. 更新 BatchSandbox annotation 一次(写入批分配结果) 121 3. 更新 BatchSandbox status 一次 122 123 ## 入门指南 124 125  126 127 ### 先决条件 128 - go 版本 v1.24.0+ 129 - docker 版本 17.03+ 130 - kubectl 版本 v1.11.3+ 131 - 访问 Kubernetes v1.21.1+ 集群 132 133 如果您没有 Kubernetes 集群的访问权限,可以使用 [kind](https://kind.sigs.k8s.io/) 创建一个本地 Kubernetes 集群进行测试。Kind 在 Docker 容器中运行 Kubernetes 节点,使得设置本地开发环境变得容易。 134 135 安装 kind: 136 - 从[发布页面](https://github.com/kubernetes-sigs/kind/releases)下载适用于您操作系统的发布二进制文件并将其移动到 `$PATH` 中 137 - 或使用包管理器: 138 - macOS (Homebrew):`brew install kind` 139 - Windows (winget):`winget install Kubernetes.kind` 140 141 安装 kind 后,使用以下命令创建集群: 142 ```sh 143 kind create cluster 144 ``` 145 146 此命令默认创建单节点集群。要与其交互,请使用生成的 kubeconfig 运行 `kubectl`。 147 148 **Kind 用户的重要说明**:如果您使用的是 kind 集群,在使用 `make docker-build` 构建镜像后,需要将控制器和任务执行器镜像加载到 kind 节点中。这是因为 kind 在 Docker 容器中运行 Kubernetes 节点,无法直接访问本地 Docker 守护进程中的镜像。 149 150 使用以下命令将镜像加载到 kind 集群中: 151 ```sh 152 kind load docker-image <controller-image-name>:<tag> 153 kind load docker-image <task-executor-image-name>:<tag> 154 ``` 155 156 例如,如果您使用 `make docker-build CONTROLLER_IMG=my-controller:latest` 构建镜像,则使用以下命令加载: 157 ```sh 158 kind load docker-image my-controller:latest 159 ``` 160 161 完成后使用以下命令删除集群: 162 ```sh 163 kind delete cluster 164 ``` 165 166 有关使用 kind 的更多详细说明,请参阅[官方 kind 文档](https://kind.sigs.k8s.io/docs/user/quick-start/)。 167 168 ### 部署 169 170 此项目需要两个独立的镜像 - 一个用于控制器,另一个用于任务执行器组件。 171 172 #### 方式 1:使用 Helm 部署(推荐) 173 174 **从 GitHub Release 安装:** 175 176 您可以直接从 GitHub Releases 安装 OpenSandbox Controller。查看 [Releases 页面](https://github.com/alibaba/OpenSandbox/releases?q=helm%2Fopensandbox-controller&expanded=true) 了解所有可用版本。 177 178 ```sh 179 # 将 <version> 替换为所需版本(例如:0.1.0) 180 helm install opensandbox-controller \ 181 https://github.com/alibaba/OpenSandbox/releases/download/helm/opensandbox-controller/<version>/opensandbox-controller-<version>.tgz \ 182 --namespace opensandbox-system \ 183 --create-namespace 184 ``` 185 186 具体版本示例: 187 ```sh 188 helm install opensandbox-controller \ 189 https://github.com/alibaba/OpenSandbox/releases/download/helm/opensandbox-controller/0.1.0/opensandbox-controller-0.1.0.tgz \ 190 --namespace opensandbox-system \ 191 --create-namespace 192 ``` 193 194 您也可以先下载 chart 然后再安装: 195 ```sh 196 # 下载 chart 197 wget https://github.com/alibaba/OpenSandbox/releases/download/helm/opensandbox-controller/<version>/opensandbox-controller-<version>.tgz 198 199 # 从本地文件安装 200 helm install opensandbox-controller ./opensandbox-controller-<version>.tgz \ 201 --namespace opensandbox-system \ 202 --create-namespace 203 ``` 204 205 **自定义安装:** 206 207 使用 `--set` 参数自定义配置: 208 209 ```sh 210 # 示例:自定义资源限制 211 helm install opensandbox-controller \ 212 https://github.com/alibaba/OpenSandbox/releases/download/helm/opensandbox-controller/0.1.0/opensandbox-controller-0.1.0.tgz \ 213 --namespace opensandbox-system \ 214 --create-namespace \ 215 --set controller.replicaCount=2 \ 216 --set controller.resources.limits.cpu=1000m \ 217 --set controller.resources.limits.memory=512Mi 218 219 # 示例:自定义日志级别 220 helm install opensandbox-controller \ 221 https://github.com/alibaba/OpenSandbox/releases/download/helm/opensandbox-controller/0.1.0/opensandbox-controller-0.1.0.tgz \ 222 --namespace opensandbox-system \ 223 --create-namespace \ 224 --set controller.logLevel=debug 225 ``` 226 227 或使用 values 文件进行复杂配置: 228 229 ```sh 230 # 创建自定义 values 文件 231 cat > custom-values.yaml <<EOF 232 controller: 233 replicaCount: 2 234 resources: 235 limits: 236 cpu: 1000m 237 memory: 512Mi 238 requests: 239 cpu: 100m 240 memory: 128Mi 241 logLevel: debug 242 EOF 243 244 # 使用自定义 values 安装 245 helm install opensandbox-controller \ 246 https://github.com/alibaba/OpenSandbox/releases/download/helm/opensandbox-controller/0.1.0/opensandbox-controller-0.1.0.tgz \ 247 --namespace opensandbox-system \ 248 --create-namespace \ 249 -f custom-values.yaml 250 ``` 251 252 **从源码安装(用于开发):** 253 254 如果您正在进行开发或需要自定义 chart: 255 256 1. **构建和推送您的镜像:** 257 ```sh 258 # 构建和推送控制器镜像 259 make docker-build docker-push CONTROLLER_IMG=<some-registry>/opensandbox-controller:tag 260 261 # 构建和推送任务执行器镜像 262 make docker-build-task-executor docker-push-task-executor TASK_EXECUTOR_IMG=<some-registry>/opensandbox-task-executor:tag 263 ``` 264 265 2. **使用 Helm 安装:** 266 ```sh 267 helm install opensandbox-controller ./charts/opensandbox-controller \ 268 --set controller.image.repository=<some-registry>/opensandbox-controller \ 269 --set controller.image.tag=<tag> \ 270 --namespace opensandbox-system \ 271 --create-namespace 272 ``` 273 274 **验证安装:** 275 276 检查控制器是否运行: 277 ```sh 278 kubectl get pods -n opensandbox-system 279 kubectl get deployment -n opensandbox-system 280 281 # 查看日志 282 kubectl logs -n opensandbox-system -l control-plane=controller-manager -f 283 ``` 284 285 **升级:** 286 287 ```sh 288 # 升级到新版本 289 helm upgrade opensandbox-controller \ 290 https://github.com/alibaba/OpenSandbox/releases/download/helm/opensandbox-controller/<new-version>/opensandbox-controller-<new-version>.tgz \ 291 --namespace opensandbox-system 292 ``` 293 294 **卸载:** 295 296 ```sh 297 helm uninstall opensandbox-controller -n opensandbox-system 298 ``` 299 300 有关更多配置选项和高级用法,请参阅 [Helm Chart README](charts/opensandbox-controller/README.md)。 301 302 #### 方式 2:使用 Kustomize 部署 303 304 1. **构建和推送您的镜像:** 305 ```sh 306 # 构建和推送控制器镜像 307 make docker-build docker-push CONTROLLER_IMG=<some-registry>/opensandbox-controller:tag 308 309 # 构建和推送任务执行器镜像 310 make docker-build-task-executor docker-push-task-executor TASK_EXECUTOR_IMG=<some-registry>/opensandbox-task-executor:tag 311 ``` 312 313 **注意:** 这些镜像应该发布在您指定的个人注册表中。需要能够从工作环境中拉取镜像。如果上述命令不起作用,请确保您对注册表具有适当的权限。 314 315 2. **将 CRD 安装到集群中:** 316 ```sh 317 make install 318 ``` 319 320 3. **将管理器部署到集群:** 321 ```sh 322 make deploy CONTROLLER_IMG=<some-registry>/opensandbox-controller:tag TASK_EXECUTOR_IMG=<some-registry>/opensandbox-task-executor:tag 323 ``` 324 325 **注意**:您可能需要授予自己集群管理员权限或以管理员身份登录以确保您在运行命令之前具有集群管理员权限。 326 327 **Kind 用户的重要说明**:如果您使用的是 kind 集群,需要在构建镜像后将两个镜像都加载到 kind 节点中: 328 ```sh 329 kind load docker-image <controller-image-name>:<tag> 330 kind load docker-image <task-executor-image-name>:<tag> 331 ``` 332 333 ### 创建 BatchSandbox 和 Pool 资源 334 335 #### 基础示例 336 创建一个简单的非池化沙箱,不带任务调度: 337 338 ```yaml 339 apiVersion: sandbox.opensandbox.io/v1alpha1 340 kind: BatchSandbox 341 metadata: 342 name: basic-batch-sandbox 343 spec: 344 replicas: 2 345 template: 346 spec: 347 containers: 348 - name: sandbox-container 349 image: nginx:latest 350 ports: 351 - containerPort: 80 352 ``` 353 354 应用批处理沙箱配置: 355 ```sh 356 kubectl apply -f basic-batch-sandbox.yaml 357 ``` 358 359 检查批处理沙箱状态: 360 ```sh 361 kubectl get batchsandbox basic-batch-sandbox -o wide 362 ``` 363 364 示例输出: 365 ```sh 366 NAME DESIRED TOTAL ALLOCATED READY EXPIRE AGE 367 basic-batch-sandbox 2 2 2 2 <none> 5m 368 ``` 369 370 状态字段说明: 371 - **DESIRED**:请求的沙箱数量 372 - **TOTAL**:创建的沙箱总数 373 - **ALLOCATED**:成功分配的沙箱数量 374 - **READY**:准备使用的沙箱数量 375 - **EXPIRE**:过期时间(未设置时为空) 376 - **AGE**:资源创建以来的时间 377 378 沙箱准备好后,您可以在注解中找到端点信息: 379 ```sh 380 kubectl get batchsandbox basic-batch-sandbox -o jsonpath='{.metadata.annotations.sandbox\.opensandbox\.io/endpoints}' 381 ``` 382 383 这将显示交付沙箱的 IP 地址。 384 385 #### 高级示例 386 387 ##### 不带任务的池化沙箱 388 首先,创建一个资源池: 389 390 ```yaml 391 apiVersion: sandbox.opensandbox.io/v1alpha1 392 kind: Pool 393 metadata: 394 name: example-pool 395 spec: 396 template: 397 spec: 398 containers: 399 - name: sandbox-container 400 image: nginx:latest 401 ports: 402 - containerPort: 80 403 capacitySpec: 404 bufferMax: 10 405 bufferMin: 2 406 poolMax: 20 407 poolMin: 5 408 ``` 409 410 应用资源池配置: 411 ```sh 412 kubectl apply -f pool-example.yaml 413 ``` 414 415 **可选:配置扩容速率控制** - 添加 `scaleStrategy` 限制扩容节奏: 416 ```yaml 417 scaleStrategy: 418 maxUnavailable: "20%" # 或绝对数量如 5 419 ``` 420 421 该配置控制扩容过程中允许不可用的 Pod 数量。例如,当 `poolMax=50` 且 `maxUnavailable=20%` 时,每次最多扩容 10 个 Pod。 422 423 使用资源池创建一批沙箱: 424 425 ```yaml 426 apiVersion: sandbox.opensandbox.io/v1alpha1 427 kind: BatchSandbox 428 metadata: 429 name: pooled-batch-sandbox 430 spec: 431 replicas: 3 432 poolRef: example-pool 433 ``` 434 435 应用批处理沙箱配置: 436 ```sh 437 kubectl apply -f pooled-batch-sandbox.yaml 438 ``` 439 440 ##### 带异构任务的池化沙箱 441 创建一批带有基于进程的异构任务的沙箱。为了使任务执行正常工作,任务执行器必须作为 sidecar 容器部署在资源池模板中,并与沙箱容器共享进程命名空间: 442 443 首先,创建一个带有任务执行器 sidecar 的资源池: 444 445 ```yaml 446 apiVersion: sandbox.opensandbox.io/v1alpha1 447 kind: Pool 448 metadata: 449 name: task-example-pool 450 spec: 451 template: 452 spec: 453 shareProcessNamespace: true 454 containers: 455 - name: sandbox-container 456 image: ubuntu:latest 457 command: ["sleep", "3600"] 458 - name: task-executor 459 image: <task-executor-image>:<tag> 460 securityContext: 461 capabilities: 462 add: ["SYS_PTRACE"] 463 capacitySpec: 464 bufferMax: 10 465 bufferMin: 2 466 poolMax: 20 467 poolMin: 5 468 ``` 469 470 使用我们刚刚创建的资源池创建一批带有基于进程的异构任务的沙箱: 471 472 ```yaml 473 apiVersion: sandbox.opensandbox.io/v1alpha1 474 kind: BatchSandbox 475 metadata: 476 name: task-batch-sandbox 477 spec: 478 replicas: 2 479 poolRef: task-example-pool 480 taskTemplate: 481 spec: 482 process: 483 command: ["echo", "Default task"] 484 shardTaskPatches: 485 - spec: 486 process: 487 command: ["echo", "Custom task for sandbox 1"] 488 - spec: 489 process: 490 command: ["echo", "Custom task for sandbox 2"] 491 args: ["with", "additional", "arguments"] 492 ``` 493 494 应用批处理沙箱配置: 495 ```sh 496 kubectl apply -f task-batch-sandbox.yaml 497 ``` 498 499 检查带任务的批处理沙箱状态: 500 ```sh 501 kubectl get batchsandbox task-batch-sandbox -o wide 502 ``` 503 504 示例输出: 505 ```sh 506 NAME DESIRED TOTAL ALLOCATED READY TASK_RUNNING TASK_SUCCEED TASK_FAILED TASK_UNKNOWN EXPIRE AGE 507 task-batch-sandbox 2 2 2 2 0 2 0 0 <none> 5m 508 ``` 509 510 任务状态字段说明: 511 - **TASK_RUNNING**:当前正在执行的任务数 512 - **TASK_SUCCEED**:成功完成的任务数 513 - **TASK_FAILED**:失败的任务数 514 - **TASK_UNKNOWN**:状态未知的任务数 515 516 当您删除带有运行任务的 BatchSandbox 时,控制器将首先停止所有任务,然后删除 BatchSandbox 资源。一旦所有任务都成功终止,BatchSandbox 将被完全删除,沙箱将返回到资源池中以供重用。 517 518 删除 BatchSandbox: 519 ```sh 520 kubectl delete batchsandbox task-batch-sandbox 521 ``` 522 523 您可以通过观察 BatchSandbox 状态来监控删除过程: 524 ```sh 525 kubectl get batchsandbox task-batch-sandbox -w 526 ``` 527 528 ### 监控资源 529 检查资源池和批处理沙箱的状态: 530 ```sh 531 # 查看资源池状态 532 kubectl get pools 533 534 # 查看批处理沙箱状态 535 kubectl get batchsandboxes 536 537 # 获取特定资源的详细信息 538 kubectl describe pool example-pool 539 kubectl describe batchsandbox example-batch-sandbox 540 ``` 541 542 ## 项目结构 543 544 ``` 545 ├── api/ 546 │ └── v1alpha1/ # 自定义资源定义(BatchSandbox, Pool) 547 ├── cmd/ 548 │ ├── controller/ # 主控制器管理器入口点 549 │ └── task-executor/ # 任务执行器二进制文件 550 ├── config/ 551 │ ├── crd/ # 自定义资源定义清单 552 │ ├── default/ # 控制器部署的默认配置 553 │ ├── manager/ # 控制器管理器配置 554 │ ├── rbac/ # 基于角色的访问控制清单 555 │ └── samples/ # 资源的示例 YAML 清单 556 ├── hack/ # 开发脚本和工具 557 ├── images/ # 文档图片 558 ├── internal/ 559 │ ├── controller/ # 核心控制器实现 560 │ ├── scheduler/ # 资源分配和调度逻辑 561 │ ├── task-executor/ # 任务执行引擎内部实现 562 │ └── utils/ # 实用函数和助手 563 ├── pkg/ 564 │ └── task-executor/ # 共享的任务执行器包 565 └── test/ # 测试套件 566 ``` 567 568 ## 贡献 569 欢迎为 OpenSandbox Kubernetes 控制器项目做出贡献。请随时提交问题、功能请求和拉取请求。 570 571 **注意:** 运行 `make help` 以获取所有潜在 `make` 目标的更多信息 572 573 更多信息请参见 [Kubebuilder 文档](https://book.kubebuilder.io/introduction.html) 574 575 ## 许可证 576 此项目在 Apache 2.0 许可证下开源。 577 578 您可以将 OpenSandbox 用于个人或商业项目,只要遵守许可证条款即可。