The GPU admission webhooks need a Service, a serving certificate and
webhook configurations, and the binder's metrics need a port a scrape
can reach. All of it renders only with GPU enabled, which the platform
sets where KubeVirt serves GPUs, so clusters without KubeVirt change
nothing.
The webhooks fail closed. The two mutating ones select only VMIs and
virt-launcher pods carrying the device-reference label, the pod webhook
also requiring the virt-launcher label, so of VMIs and pods a
controller outage blocks only the start of VMs with device references;
the GPUDevice webhook blocks new orders as well. The controller then
runs two replicas behind a PDB, since a single fail-closed replica
would block those starts on every rollout.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
A tenant references held devices and device templates on the VMI
template; something has to turn those references into GPUs on one node
before KubeVirt renders the launcher pod, and refuse a start that cannot
work instead of leaving a VMI Pending with no pod.
The GPUDevice webhook refuses an order that cannot be met now: an
unknown or deleted class, maxCount, the class's free units or one
node's, a budget of the tenant or an ancestor, or a vGPU class without
the entitlement.
The VMI webhook runs every refusal check before it writes anything, so
a dry run and a refused start leave no trace. It then creates the
template devices, attaches the whole set with optimistic concurrency so
two VMIs never take one device, and waits a bounded time for the
leader's binder to place the set on one node. The API server calls it
again after virt-api's mutator changes the VMI, so a recent answered
request for the same VMI is taken as its own and nothing is written
twice. It adds a gpus entry per GPU and never a resources key as
well, since the launcher pod would request the sum.
The pod webhook pins the launcher pod to the devices' node with a
required node affinity on the pod, because LiveUpdate rewrites the
VMI's affinity from the VM template.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
The binder, the admission webhooks, the tenant chart, the policies and
cozystack-api all have to agree on the same label, annotation,
finalizer and quota keys and on the settings ConfigMap the policies
take as a parameter, so they are defined once here.
The binder in the leader is the only writer of placement; webhooks
running in every replica record an attachment and a bind request in
the device status and wait for the binder's answer, so capacity and
budgets are decided in one serialized loop. Status is the carrier
because no tenant role can write it. The template-device mark carries
no VMI name, since a VMI name can exceed a label value.
Register and Setup exist as no-ops so the controller can be wired to
them before the webhooks and reconcilers land.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>