Skip to main content
Fleet 是一组机器加上在它们上面跑活儿的后端,有名字。它是你建出来的一条记录,不是导出的一个 环境变量:一个 console 可以同时挂着好几个 Fleet,每个作业和每个部署都记下了它被准入到哪一个。 它取代了原先那个部署级的后端开关。原因见 ADR-0013FORGE_DEFAULT_FLEET_KIND 是它留下的东西,只在 console 还没有任何 Fleet 时用来种出第一个—— 首次启动读一次,别处不读。

一个 Fleet 记了什么

config 放的是同一种 kind 的两个 Fleet 之间会不一样的那些键——slurm 的 REST 地址、KubeRay 的 namespace。写了一个没有任何设置会读的键,会打一条 warning 而不是被无声忽略:拼错的覆盖项就是 一条运维以为生效、实际没生效的设置。
capability 是承诺,不是偏好。没有 serve 的 Fleet 不是「serve 得不好」的 Fleet——点名它的 部署会被拒。

建一个

Fleets → 新建 Fleet。选后端、选它用来做什么;数据投递方式默认跟随后端,可以改。也可以走 API:
仅管理员。注册机器是运维做的事;挑一个 Fleet 提交是用户做的事。 一个完全没有 Fleet 的 console 会在首次启动时按 FORGE_DEFAULT_FLEET_KIND 种下一个,所以 零配置部署根本不用调这个接口。

注册一台机器

只有 node Fleet 需要注册机器——kuberayslurm 的机器由集群管理器给,local 就是 console 自己这台。 在 Fleet 页面签出一个 join token——「添加机器」。它一次性、24 小时过期、只存哈希。页面会给出一行可以直接粘到 机器上的命令:
机器上已经装了这个包的话:
join token 就是全部授权。你需要的是这台机器的 root,而不是 console 上的账号——这也正是那一行 命令可以直接交给管这台机器的人的原因。聊天记录里的 token 在过期之前都要当成一把长期钥匙看。
返回的是节点的身份和一份长期凭证,写在 FORGE_NODE_STATE_DIR 下。**凭证只返回一次。**弄丢了就 只能再要一个 token、作为新节点重新加入——这是对的:一台丢了身份的机器,对一个要拿容器跟它对账的 控制面来说,就不是同一台机器了。 节点在 join 时上报自己的清单——卡名、卡数、驱动、容器运行时,以及看不看得见存储根。console 把卡名 映射到硬件系列。注册表不认识的卡会在 join 的输出里点出来,好让管理员补进去;在那之前,指定了系列 的作业不会落到这台机器上。

地址不是身份

节点的标识是 console 签发的 id,不是 host:port。搬了家的机器还是同一台机器。这带来的后果是, 两条记录合法地答在同一个地址上是可能的,所以「加入时已有另一个活着的节点答在这个地址」是一条警告 而不是拒绝——由 forgelet join 打出来,因为最常见的成因是一次重新加入留下了旧记录,于是 console 把一台机器的卡数了两遍。

存活判定

一个 last_seen_at,对三个阈值来读,因为判错的代价取决于这台机器是干什么的: 这是三种后果,不是三种状态。节点被判为 gone 用的是它所在 Fleet 各 capability 里最宽松的 那一个;更紧的规则按 capability 单独回答。「现在别往那儿发流量」和「根本别往那儿放东西」是两句 不同的话——否则一个声明了全部三项的 Fleet 会在静默 45 秒后连训练活儿都不接了。 被判为 gone 不会杀掉任何东西。节点失联不等于作业死亡:observe 对它上面的作业不返回信号,对账 跳过这一轮,机器回来后按真实容器状态收敛。 shared-mount 的节点上报说看不见存储根了,会被 cordon;挂载回来后自动解除。运维自己下的 cordon 永远不会被一次心跳解除——那一个是决定,而心跳是观察。

排空、cordon、移除

它们都不杀东西,这正是重点。cordoned 给还会回来的机器,draining 给要走的机器。 移除一个 active 的节点会被拒。它的身份正是让它的容器可对账的东西,所以先排空、让活儿跑完。 force=true 是给已经没了的机器用的;它会以「强制」记进审计日志,因为它留下的是一个再也没人能 对账的容器。 一个 Fleet 只有在既没有节点、也没有部署钉在上面时才能删。部署不会换 Fleet,所以把它脚下的 Fleet 删掉,会留下一行后端解析不到任何东西的记录:观察不了、停不掉,卡还占着。

怎么挑 Fleet

部署是那个例外,因为它的地址比这个决定活得更久、而且永远不搬,而 Fleet 记录上没有任何字段说得清 这些机器归哪个部门、什么数据可以碰它们。平台拒绝回答一个它答不了的问题。 放置在准入这一刻带着理由拒绝——capability、可见性、或者装不装得下。没有任何 Fleet 能容纳的作业, 会在提交者还盯着响应的时候就被告知,而不是几个小时后排到队首才发现。
「装不装得下」是一次检查,不是一次预留。到底拿到哪几张卡,权威仍然是分配器;这里挡的只是「这个 Fleet 从来就没有过的硬件」,免得它在队列里排到天荒地老。

可见性

project 的 Fleet 在项目之外不可见,点名它的作业会被拒为不存在而不是无权限——私有 Fleet 的 名字不该从一条错误信息里漏出去。