deploy/k8s/ 是一套 kustomize overlay,覆盖命名空间、配置、密钥、RBAC、Deployment、
Service、Ingress 和两个 PVC。
它会创建什么
apply 之前先把镜像指向你的仓库:
deploy/k8s/kustomization.yaml
真正要紧的是那个存储卷
FORGE_STORAGE_ROOT 指定的那个路径上——
它往 runs/<user>/<exp>/<run_id>/work 里放作业目录、测量磁盘压力、执行回收。
训练 Pod 挂载同一个 claim,所以控制台写的路径就是作业打开的路径。
容量按「权重缓存 + 数据集缓存 + 所有 run 目录」估。2Ti 是一个起点而不是建议值;
光是权重缓存,每个基座模型就是几十 GB。
推荐配置
deploy/k8s/configmap.yaml
FORGE_INGEST_URL 用的是集群内服务名
FORGE_INGEST_URL 用的是集群内服务名
训练 Pod 往它回传。用外部 ingress 地址会先出集群再绕回来;服务 DNS 名不会。
绝不能填
127.0.0.1——那是 worker 自己的回环。FORGE_KUBERAY_RAY_VERSION 必须和训练镜像一致
FORGE_KUBERAY_RAY_VERSION 必须和训练镜像一致
不一致的症状是「集群起来了但 worker 注册不上」,而唯一的线索是一行很容易淹没在启动输出里的版本警告。
FORGE_K8S_SHM_SIZE,因为容器默认只有 64MB
FORGE_K8S_SHM_SIZE,因为容器默认只有 64MB
Ray 的 object store 就在
/dev/shm 里。用默认值的话,稍大一点的 batch 立刻 OOM。
它由内存支撑,所以它加上内存上限不能超过物理内存。FORGE_KUBERAY_PRERUNNING_DEADLINE_S 给卡住的作业一个上限
FORGE_KUBERAY_PRERUNNING_DEADLINE_S 给卡住的作业一个上限
没有它,拉不到的镜像或者没有节点满足的 nodeSelector 会让作业无限期 Pending,同时一直占着队列位置。
密钥
secret.example.yaml 只是用来说明结构。上生产前请换成真实来源——
kubectl create secret、Sealed Secrets 或 External Secrets Operator——
并把它从 kustomization.yaml 里移除。
至少要有:FORGE_WEB_JWT_SECRET、FORGE_DB_URL、FORGE_REDIS_URL、
FORGE_S3_SECRET_KEY、FORGE_SECRET_ENC_KEY,以及 OIDC 的 client secret。
副本数
清单里是单副本,这是安全的默认值。往上扩之前:FORGE_DB_URL必须指向 Postgres。SQLite 是单写的FORGE_WEB_JWT_SECRET必须固定,否则副本之间互相拒绝对方签的 tokenFORGE_REDIS_URL必须配置,否则后台角色会整个停掉而不是跨副本不安全地跑—— 存储记账、诊断、看门狗和每日日报全都不再运行- 把后台角色放进它自己的 Pod。设
FORGE_INPROCESS_WORKERS=0,再应用 worker Deployment——kustomize 路径下是worker.yaml,Helm 下是worker.enabled=true。诊断与日报的 tick 会调 LLM 并一次占住事件循环好几秒; 拆出去之后它们不再抬高 API 尾延迟,控制台副本也变成无状态的。副本数保持 1 是对的:每个角色都经 Redis 选主,第二个副本只会空转