deploy/k8s/ 是一套 kustomize overlay,覆盖命名空间、配置、密钥、RBAC、Deployment、
Service、Ingress 和两个 PVC。
它会创建什么
apply 之前先把镜像指向你的仓库:
deploy/k8s/kustomization.yaml
真正要紧的是那个存储卷
TUNEPLANE_STORAGE_ROOT 指定的那个路径上——
它往 runs/<user>/<exp>/<run_id>/work 里放作业目录、测量磁盘压力、执行回收。
训练 Pod 挂载同一个 claim,所以控制台写的路径就是作业打开的路径。
容量按「权重缓存 + 数据集缓存 + 所有 run 目录」估。2Ti 是一个起点而不是建议值;
光是权重缓存,每个基座模型就是几十 GB。
推荐配置
deploy/k8s/configmap.yaml
TUNEPLANE_INGEST_URL 用的是集群内服务名
TUNEPLANE_INGEST_URL 用的是集群内服务名
训练 Pod 往它回传。用外部 ingress 地址会先出集群再绕回来;服务 DNS 名不会。
绝不能填
127.0.0.1——那是 worker 自己的回环。TUNEPLANE_KUBERAY_RAY_VERSION 必须和训练镜像一致
TUNEPLANE_KUBERAY_RAY_VERSION 必须和训练镜像一致
不一致的症状是「集群起来了但 worker 注册不上」,而唯一的线索是一行很容易淹没在启动输出里的版本警告。
TUNEPLANE_K8S_SHM_SIZE,因为容器默认只有 64MB
TUNEPLANE_K8S_SHM_SIZE,因为容器默认只有 64MB
Ray 的 object store 就在
/dev/shm 里。用默认值的话,稍大一点的 batch 立刻 OOM。
它由内存支撑,所以它加上内存上限不能超过物理内存。TUNEPLANE_KUBERAY_PRERUNNING_DEADLINE_S 给卡住的作业一个上限
TUNEPLANE_KUBERAY_PRERUNNING_DEADLINE_S 给卡住的作业一个上限
没有它,拉不到的镜像或者没有节点满足的 nodeSelector 会让作业无限期 Pending,同时一直占着队列位置。
密钥
secret.example.yaml 只是用来说明结构。上生产前请换成真实来源——
kubectl create secret、Sealed Secrets 或 External Secrets Operator——
并把它从 kustomization.yaml 里移除。
至少要有:TUNEPLANE_WEB_JWT_SECRET、TUNEPLANE_DB_URL、TUNEPLANE_REDIS_URL、
TUNEPLANE_S3_SECRET_KEY、TUNEPLANE_SECRET_ENC_KEY,以及 OIDC 的 client secret。
副本数
API 和 worker 必须共享 PostgreSQL、Redis 6.2 或更高版本、固定的 JWT 密钥和存储。 Helm 中启用worker.enabled=true 后,会关闭 API 内的后台循环,并创建一个可扩容的
worker Deployment。每个 worker 都运行全部协调循环(调度、状态对账、看门狗),
各循环通过 leader lease 保证同一时刻只有一个副本执行,其余副本热备;每增加一个
worker 也会增加消费能力。设置 worker.replicas=3 即为三个 worker。
Kustomize 只需 worker.yaml,不再有单独的 controller。
TUNEPLANE_WORKER_CONCURRENCY 控制每个进程的在途任务数(默认 4)。
TUNEPLANE_WORKER_IO_CONCURRENCY 控制整个 worker 池的导入和 Volume 测量并发上限
(默认 4),所有副本应设置相同值。仅增加副本不会提高存储并发预算,调整时还应计入
数据库连接数和存储带宽。
对象存储必须支持条件写入,浏览器上传的 CORS 配置还需允许 If-None-Match 请求头。
API、消费者、SDK 和网页应一起升级:Volume 文件上传后
必须完成发布才能被读取。托管 Volume 使用不可变代次读取,不兼容旧的可变数据目录。