An init container that always restarts runs beside the main containers
and every later init container, so its GPUs add to theirs. Counting it
as an ordinary init container booked fewer units than the pod holds,
which let the binder overbook a node and undercounted raw quota keys.
Gt and Lt tolerations no longer count as tolerating a taint: where
their feature gate is off the scheduler ignores them, and skipping a
node is safer than binding to one no pod can land on.
The webhook contract now states that every refusal check, template
budgets and entitlement included, runs before anything is written.
Fixes: 5d90af051b ("feat(gpu): add the shared GPU placement and budget model")
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
The binder re-checks what admission checked, and cozystack-api shows
the remaining budget a later order is checked against; computing these
in three places would let them disagree. The model is pure, so each
caller builds a snapshot from its own cache.
GPU budgets cap the whole subtree of the tenant that declares them,
walked over the namespace ancestry and independent of the tenant quota
pools. A raw GPU key blocks a class until the same tenant also declares
a GPU key, and then caps devices and raw-name pods together.
A node takes binds only when it is schedulable, Ready and carries no
NoSchedule or NoExecute taint the pod does not tolerate; the
node.kubernetes.io taints are left to the first two checks, and a
taint never counts as a cordon.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>