@chamvi/sandbox-k8s

中文文档
0.8.0发布于 2026/11/09Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 2904

Kubernetes沙盒提供商为chamvi:每个工作空间一个硬化的吊舱.

中文使用文档
文档目录12 节
  1. 安装
  2. 使用量
  3. 非洲区域局
  4. 舱
  5. 图像
  6. 缓存
  7. 警卫
  8. 暂停和中止
  9. 垃圾收集
  10. 选项
  11. API 密码
  12. 许可证

@chamvi/sandbox-k8s

@chamvi/ sandbox-k8s (英语)

每个工作空间一个舱, 对于chamvi代理在Kubernetes.
根植于此软件包管理器的工作, 少数能力, 没有服务账户符号, 资源限制,
在重新启动后或在另一个复制品上再次通过标签找到.

npm version CI License


目录

安装

npm install @chamvi/sandbox-k8s @chamvi/sandbox @chamvi/core ai --save

仅限无害环境管理,节点.js >=26.0.0。 。 。 . @chamvi/core 财务报告和审定财务报表 @chamvi/sandbox 是同伴的依赖关系。 API 服务器通过 @kubernetes/client-node 页:1CoreV1Api 财务报告和审定财务报表 Exec 在一个WebSocket上。 它宣布 @types/node ^26 作为运行时间的依赖,所以一个关于更古老的节点类型的项目会得到一个嵌入式复制件;这与 skipLibCheck。 。 。 .

使用量

import type { KubeConfig } from '@kubernetes/client-node';
import type { ISandboxProvider } from '@chamvi/sandbox';
import { createKubernetesSandbox } from '@chamvi/sandbox-k8s';

export function createSandbox(kubeConfig: KubeConfig): ISandboxProvider {
    // one pod per workspace in this namespace; nothing is contacted before the first create()
    return createKubernetesSandbox({ namespace: 'agents', kubeConfig });
}

无 kubeConfig 提供者的电话 loadFromDefault(): chamvi运行于吊舱时的集群内服务账户,否则 KUBECONFIG 或者说 ~/.kube/config。将提供者传给 createWorkspaceManager({ provider }) 从 @chamvi/sandbox创建它与任何联系; create() 创建吊舱, 等待它运行( 每秒, 最多2分钟, 快速失效) ErrImagePull, (中文(简体) ), ImagePullBackOff, (中文(简体) ), InvalidImageName, (中文(简体) ), CreateContainerConfigError 财务报告和审定财务报表 CreateContainerError),然后检查出来.

非洲区域局

身份 chamvi 随需要运行, 只存在于沙盒名空间 :

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: chamvi-sandbox
  namespace: agents
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create", "get", "list", "delete"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["get", "create"]
  # only with persistence
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["create", "get", "list", "delete"]

方案安全: 默认情况下, pockes 以可写入的 root 文件系统和能力作为 root 运行 CHOWN, (中文(简体) ), DAC_OVERRIDE, (中文(简体) ), FOWNER, (中文(简体) ), FSETID, (中文(简体) ), SETUID, (中文(简体) ), SETGID 财务报告和审定财务报表 KILL安全级别 baseline 承认和 restricted 拒绝。 将沙盒命名空间相应标记:

kubectl label namespace agents pod-security.kubernetes.io/enforce=baseline

只在哪个地方 restricted 允许使用硬化模式, createKubernetesSandbox({ namespace, user: { uid: 1000, gid: 1000 }, readOnlyRoot: true }): 无根 runAsNonRoot 财务报告和审定财务报表 fsGroup,只读的根,没有能力(apt 然后失败; 工具链仍然安装到 /cache 以弥撒为主。 共享 cache.claimName 必须尊重 fsGroup (NFS风格的音量插件忽略了它)或作世界写作,否则被硬化的用户无法写入.

pods/exec 需要两个动词 : 客户端打开 exec WebSocket 用一个 GET, API 服务器授权为 get,而带有 WebSocket 升级授权更改的服务器则请求 create将沙盒命名空间除去Chamvi自己的,因此被吊舱从不与它的秘密共享命名空间.

舱

每个工作空间都是空的 chamvi-ws-<id> 一个集装箱 sandbox数字 :

设置数值
专辑restartPolicy: Never, (中文(简体) ), automountServiceAccountToken: false, (中文(简体) ), enableServiceLinks: false, (中文(简体) ), shareProcessNamespace: true (暂停容器是pid 1 并收获任何图像的孤儿过程, 也是一个没有init, 否则僵尸会填补 kubelet 的 pid 极限), activeDeadlineSeconds = 工作空间的寿命,以秒计(lifetimeSeconds),所以吊舱结束于 expiresAt 即使没有收藏, terminationGracePeriodSeconds: 5
Pod 担保runAsUser编号 :runAsGroup 从 user (默认 0 ),秒comp RuntimeDefault; 非根用户添加 runAsNonRoot 财务报告和审定财务报表 fsGroup
集装箱安全allowPrivilegeEscalation: false没有特权, readOnlyRootFilesystem 从 readOnlyRoot (默认不实),所有能力都下降,用于根 ROOT_CAPABILITIES 添加回来
命令command: ['sh', '-c', SLEEP_UNTIL_SCRIPT, 'sh', '<expiresAt in epoch seconds>'] (睡觉直到) expiresAt,因此一个预定后期停放的起落架),替换了图像的入站点(一个其入站点也是命令工作的出站点)
资源请求同等限制 : cpu, (中文(简体) ), memory, (中文(简体) ), ephemeral-storage 从 storage
/workspace空目录 sizeLimit 从 storage; 与 persistence (b) 工作空间的索赔 workspace(中文(简体) )
/tmp内存支持的空目录 tmpSize (默认 1 GiB, TMP_SIZE(中文(简体) )
/home/sandbox家庭(WORKSPACE_HOME: 节点磁盘上的一个空盘,计算在 ephemeral-storage; 与 persistence (b) 工作空间的索赔 home(中文(简体) )
/cachereadWrite Many 主张 cache.claimName,由每个工作区共享, 否则是空的
环境SANDBOX_ENV,缓存变量(CACHE_ENV和 env查姆维的舱里什么都没有
标签podLabels,则 app.kubernetes.io/managed-by=chamvi, (中文(简体) ), app.kubernetes.io/component=sandbox, (中文(简体) ), chamvi.dev/run=<runId>, (中文(简体) ), chamvi.dev/workspace=<id>, (中文(简体) ), chamvi.dev/deployment=<deployment>, (中文(简体) ), chamvi.dev/repo-key=<hash> (带有寄存器) (管理下的标签胜出; podLabels 命名一掷; a runId 没有标签值是一个 ValidationError,引擎运行代号为UUID)
说明chamvi.dev/created-at 财务报告和审定财务报表 chamvi.dev/expires-at (划时代), chamvi.dev/repo, (中文(简体) ), chamvi.dev/ref, (中文(简体) ), chamvi.dev/image

使用一个 pock 而不是 Job : exec 需要一个在创建时间已知的 pock 名称, 而 Job 的控制器, 重试和生成的名称 则不会添加任何 cock 光谱尚未执行的 .

limits.pids 库伯涅茨没有每波德字段: podPidsLimit 应用,所以设置在运行沙盒的节点上.

图像

默认图像是 ghcr.io/chamvi/sandbox-dev:trixie (单位:千美元)DEFAULT_SANDBOX_IMAGE: Debian, git, 为任何工具链构建工具, rigrep, jq and mise, 为 linux/amd64 财务报告和审定财务报表 linux/arm64 从 images/sandbox-dev; 标签 trixie (根据更改和每周重建)和 trixie-<short sha>。 。 。 . imagePullPolicy (提供者图像)默认为 'IfNotPresent'; 使用 'Always' 跟踪可变标记,或在生产中粘贴摘要(image: 'ghcr.io/chamvi/sandbox-dev@sha256:...') (中文(简体) ).

运行可能选择一个图像( Q)create_workspace({ image })),只有当管理者有许可列表时(allowImage,或 CHAMVI_SANDBOX_IMAGES 内 sandboxModule()(三); imagePullPolicy 适用于每一个图像, 提供者, 管理者 和一个运行要求。 图像需要 sh, (中文(简体) ), git 和一个 GNU timeout 这需要 -k数字 : create 一旦吊舱运行失败 就会探测 SandboxError 指定缺少的,在任何检出之前(并删除吊舱).

缓存

每个舱载 /cache 并获得缓存变量(CACHE_ENV数字 : XDG_CACHE_HOME, (中文(简体) ), npm_config_cache, (中文(简体) ), PIP_CACHE_DIR, (中文(简体) ), GOMODCACHE, (中文(简体) ), GOCACHE, (中文(简体) ), COMPOSER_CACHE_DIR; 包只下载, mise将工具链保存在Home). 无 cache 是一个空的 Dir (按其 ephemeral-storage)),所以安装工作,但每次开始冷. 与 cache: { claimName } 每个工作区都挂载相同的ReadWriteMany索赔(NFS, CephFS, EFS, Azure 文件),因此工作区共享权利要求的再利用相互的软件包下载(漏取,拆出或同时安装仍然可能再次取取;工具链停留每个工作区,在Home).

风险: 名称空间的每个运行和代理共享一个共享的主张. 一个被抓取的恶意包可以坐到另一个运行的缓存;npm验证完整性的散列,活页,Go的构建缓存等更少. 保持运行,这些运行不得在不同的要求上相互影响,或没有一项要求.

警卫

  • 不是网络边界. 没有网络政策,DNS就将工作空间舱传送到集群中的每一项服务,包括chamvi API及其数据库,以及云元数据。 选择由 app.kubernetes.io/component=sandbox (或你的电话) podLabels并且拒绝所有进取,除非工作需要(GitHub, npm 注册)、chamvi命名空间和 169.254.169.254 明确否认。 赫尔姆海图将运送这项政策.
  • 根在内部,不在节点上: 默认的根用户只持有软件包管理功能, 没有特权升级, seccomp RuntimeDefault,没有主机路径,也没有特权模式;被硬化的模式也会降低根.
  • 无全权证书:没有挂载服务账户令牌,没有注入服务链接,没有chamvi环境变量到达吊舱.
  • 即时注射:模型所运行的跟随其读取的. 缩小 allowRepo 在经理和设置 bash 背后的核准 必要时.

暂停和中止

每个命令运行为 timeout -k 5 <seconds> <argv>,表示整个进程组。 一个客户端警卫在超时后停止等15 s,并报告出口137 与产出至今. Kubernetes只在每个持有其输出的流程关闭后才发送一个执行官的退出状态,所以命令在stderr上报告其退出:一个退出时它开始的背景工作持有其输出(node server.js & echo started)在退出后使用自己的退出代码返回大约2 s,任务一直持续到被删除后. 中止( E)signal(中文(简体) ) 节点: 执行WebSocket关闭,命令运行到其 timeout 火灾或吊舱被删除。 每一次确定运行都会处理其工作空间(manager.attach(engine)) (中文(简体) ). 一个处理器删除了没有宽限期的吊舱.

Stdin只关闭在 v5.channel.k8s.io 执行协议(Kubernetes 1.30+) v4 它被写着,但从来没有关闭, 所以一个命令等待 Stdin EOF 挂起,直到它的超时. writeFile 不依赖它(head -c <bytes>) (中文(简体) ).

垃圾收集

find(runId, { deployment }) 通过标签列出运行的显示器并重建运行中运行的显示器的工作空间(一个显示器失败、完成或正在被删除的显示器已消失),所以运行在重启后或在另一个复制件上找到它的工作空间. collectGarbage({ deployment, isSettled }) 列出部署中带有所管理标签的显示器,并删除其过去的标签 chamvi.dev/expires-at 说明,处于阶段 Failed 或者说 Succeeded 并,与 isSettled,则已结算的运行(该流程的开放工作空间被先处理). 经理打来的 acquire 最多每10分钟一次.

持久性 (单位:千美元)persistence: { storageClassName?, size? }, (中文(简体) ), CHAMVI_SANDBOX_PERSISTENCE=true 与 sandboxModule(): create 提出ReadWriteOnce索赔 chamvi-ws-<id> (舱的标签和说明, size 默认 limits.storage, (中文(简体) ), storageClassName 默认星团),在起落架前,起落架在 /workspace 财务报告和审定财务报表 /home/sandbox与 isSuspendable 收藏删除一个运行中等待足够长并保留索赔的运行中吊舱; find 重建无运行状态的活体索赔的吊舱(从索赔中得出的图像和失效, env 财务报告和审定财务报表 limits 从提供者和经理, activeDeadlineSeconds 生命所剩无几 等待着 create 失败 SandboxError 当它没有开始。 撤销、终止和结清索赔也删去。 被停职:背景工作, /tmp,在两座山外写作,并写出一个空的Dir /cache一个节点本地存储类将重建的吊舱接入其节点. 无法移除的舱不能阻止通行:其他人去,一个去 SandboxError 与计数和第一个失败 投出在结尾.

选项

createKubernetesSandbox(options)数字 :

选项类型默认说明
namespacestring所需经费工作空间舱的命名空间
kubeConfigKubeConfigloadFromDefault()集群接入
imagestringDEFAULT_SANDBOX_IMAGE工作空间图像; 在生产中刻入摘要
imagePullPolicy'IfNotPresent' | 'Always''IfNotPresent'每个工作空间图像; 'Always' 可变标记
envRecord<string, string>无之后添加 SANDBOX_ENV 财务报告和审定财务报表 CACHE_ENV
user{ uid, gid }{ uid: 0, gid: 0 }舱的用户; 一个非源用户没有能力, runAsNonRoot 财务报告和审定财务报表 fsGroup
readOnlyRootbooleanfalse只读的根文件系统
cache{ claimName }无共享的ReadWriteMany索赔 /cache (每舱空出一个Dir)
persistence{ storageClassName?, size? }无每一工作空间的索赔 /workspace 和家,所以一个等待运行的吊舱可以中止;一个习惯 client 然后需要索赔方法
tmpSizestring'1Gi'内存大小 /tmp
limitsSandboxLimitsDEFAULT_LIMITScpu, (中文(简体) ), memory, (中文(简体) ), storage, (中文(简体) ), maxLifetimeMs (单位:千美元)pids:见上文)
podLabelsRecord<string, string>无额外标签, 例如, 用于网络政策; 可能不命名管理下的标签
startTimeoutMsnumber120_000多长时间 create 等待吊舱运行
pollMsnumber1_000等待时的状态民调间隔
clockIClocksystemClock民意调查 过期 执行警卫
clientIPodClientcreatePodClient()测试接合

配置错误抛出核心 InvalidAgentDefinitionError; API 和 pock 失败为 SandboxError编号.

API 密码

导出仁爱目的
createKubernetesSandbox函数这个 ISandboxProvider (单位:千美元)name: 'k8s'(中文(简体) )
createPodClient函数这个 IPodClient 结束 @kubernetes/client-node
CONTAINER_NAME常数'sandbox'
POD_NAME_PREFIX常数'chamvi-ws-'
START_TIMEOUT_MS, (中文(简体) ), POLL_MS常数120_000, (中文(简体) ), 1_000
FATAL_WAITING_REASONS常数集装箱等待原因 create 一次失败

类型 : KubernetesSandboxOptions, (中文(简体) ), KubernetesPersistence, (中文(简体) ), PodUser, (中文(简体) ), IPodClient, (中文(简体) ), PodExecInput, (中文(简体) ), CreatePodClientInput。 。 。 .

许可证

原载 Apache 许可证 2.0。 。 。 .

版本与发布记录

@chamvi/sandbox-k8s 共发布 15 个版本,首次发布于 2026/10/25;过去 12 个月发布了 15 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.8.0latest2026/11/09今天
0.7.32026/11/063 天前
0.7.22026/11/053 天前
0.7.12026/11/054 天前
0.7.02026/11/045 天前
0.6.12026/11/045 天前

关于 @chamvi/sandbox-k8s 的常见问题

@chamvi/sandbox-k8s 是什么?

Kubernetes沙盒提供商为chamvi:每个工作空间一个硬化的吊舱.

如何安装 @chamvi/sandbox-k8s?

在项目目录运行 npm install @chamvi/sandbox-k8s,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@chamvi/core(^0.8.0)、@chamvi/sandbox(^0.8.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@chamvi/sandbox-k8s 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@chamvi/sandbox-k8s 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@chamvi/sandbox-k8s 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=26.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@chamvi/sandbox-k8s 可以商用吗?

@chamvi/sandbox-k8s 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@chamvi/sandbox-k8s 的下载量有多少?

根据 npm 官方下载统计,@chamvi/sandbox-k8s 在 2026/10/10 – 2026/11/08 这 30 天内被下载 2,904 次,日均约 97 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@chamvi/sandbox-k8s 还在维护吗?

最新版本 0.8.0 发布于 2026/11/09(今天);至今共发布 15 个版本,其中过去 12 个月发布了 15 个;首次发布于 2026/10/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。