Reload vGPU licensing config without restarting the driver#881
Draft
abrarshivani wants to merge 1 commit into
Draft
Reload vGPU licensing config without restarting the driver#881abrarshivani wants to merge 1 commit into
abrarshivani wants to merge 1 commit into
Conversation
nvidia-gridd reads /etc/nvidia/gridd.conf and the NLS client configuration
token once, when it starts, and it offers no reload signal. When the Secret
behind driver.licensingConfig is rotated (ExternalSecrets/Vault), running
driver pods keep using the stale license material until someone runs a
kubectl rollout restart, which unloads the kernel module and evicts every GPU
workload on the node.
Restarting nvidia-gridd on its own is enough, and it is safe: a vGPU license
is a lease with a 20 minute grace period before any performance degradation,
so a bounce taking a couple of seconds is invisible to running CUDA
workloads. nvidia-gridd is always stopped with SIGTERM so the lease is
returned to the license server rather than leaked until it expires.
Refactor the startup copy into reusable helpers and add a background watcher,
started only for DRIVER_TYPE=vgpu, that:
- prefers the new /drivers/licensing-config directory mount that the
operator projects without subPath (so kubelet propagates updates in
place) and falls back to the legacy /drivers/gridd.conf and
/drivers/ClientConfigToken subPath mounts, which keeps the change inert
against an older operator,
- polls on VGPU_LICENSE_RELOAD_INTERVAL (default 30s) and compares file
content, not mtimes, since kubelet's atomic '..data' relink makes
timestamps unreliable and content comparison stops a bad config from
looping,
- applies a random jitter before acting, because kubelet propagates to
every node in the same short window and unjittered restarts would hit
the license server as one synchronized burst,
- backs up the current /etc/nvidia copies, installs the new ones and
restarts nvidia-gridd, verifying the pid is alive afterwards; if it did
not come back, the previous known good configuration is restored and
nvidia-gridd is restarted with that,
- never exits on failure, since failing the pod would evict every GPU
workload on the node over a typo in a secret.
_shutdown() stops and reaps the watcher before _unload_driver touches
nvidia-gridd. The watcher's signal handler only records the request, so an
in-flight restart always runs to completion first and the two can never
manipulate nvidia-gridd concurrently.
Set VGPU_LICENSE_AUTO_RELOAD=false to opt out. Both knobs reach the container
through the operator's existing driver.env passthrough.
Refs NVIDIA/gpu-operator#2279
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the Secret referenced by
driver.licensingConfigis updated — an NLS token rotated by ExternalSecrets/Vault, say — running driver pods never see the new files. Recovering the new license today requires akubectl rollout restartofnvidia-driver-daemonset, which unloads the kernel module and evicts every GPU workload on the node.Reported as NVIDIA/gpu-operator#2279.
There are three independent freeze points. The operator's
subPathmounts are one (addressed in the companion PR below). This PR addresses the other: the entrypoint copies/drivers/*into/etc/nvidiaonce at startup, andnvidia-griddreads those files only at process start.nvidia-griddhas no reload signal — the process must be restarted.Approach
Watch the licensing configuration and bounce only
nvidia-gridd, leaving the kernel module and running workloads untouched.This is safe because a vGPU license is a lease, not a presence check. There is a 20-minute grace period before any performance degradation begins, and compute is throttled rather than disabled after that. A restart taking a couple of seconds is invisible to running workloads. Full capability is restored immediately on re-acquisition.
SIGTERM, never SIGKILL. A clean SIGTERM returns the lease to the license server. An abrupt kill matches NVIDIA's documented "abrupt shutdown may not release the license" failure mode, which would leak the seat while the new
nvidia-griddacquires another — cluster-wide, that double-counts a seat on every node at once.What this does
Adds a background watcher, started from the vGPU branch of
_start_daemons(_load_driverin the precompiled variants):/drivers/licensing-config/directory mount, falls back per-file to the existingsubPathpaths. With an older operator the directory is simply absent, the watcher observes no change, and this is completely inert...data, which makes timestamps an unreliable signal. Comparing content also makes a broken configuration non-looping: a config that does not change again is not applied again.nvidia-gridddoes not come back (a malformedgridd.conf, for example), the previous config is restored andnvidia-griddrestarted with it. Failures are logged loudly and never propagated: exiting would fail the pod, unload the module and evict every GPU workload — a wildly disproportionate response to a typo in a secret.Applied to the 8 entrypoints that carry the vGPU gridd block. The helper block is byte-identical across all 8 (verified by hash); the only per-file difference is the
VGPU_GRIDD_LD_LIBRARY_PATHline, which already differed. OpenShift needs no extra file —Makefile:261-262mapsbuild-vgpuguest-rhcos%toSUBDIR = rhel9.Configuration
Both reach the container through the operator's existing
driver.envpassthrough, so no operator change is needed for them:VGPU_LICENSE_AUTO_RELOADtrueVGPU_LICENSE_RELOAD_INTERVAL30Notes for reviewers
No new runtime dependencies. Content is read with the bash
$(< file)builtin that these entrypoints already use for pid files, rather thansha256sum/md5sum(coreutils) orcmp(diffutils), none of which is guaranteed across ubuntu, UBI, and the CUDA UBI images the precompiled variants build from.Startup digest ordering. The digest is recorded before the initial copy, not after. Recording it after would make the watcher treat an update landing between the copy and the snapshot as already-applied, silently dropping a rotation. Failing this way round costs at most one spurious restart.
Shutdown ordering.
_stop_vgpu_license_watcherruns first in_shutdownand blocks until the watcher has exited, so the watcher can never be relaunchingnvidia-griddwhile_unload_driveris stopping it. The watcher's trap handler only sets a flag and never exits, and bash runs traps between commands, so an in-flight restart always completes first.Testing
bash -nclean on all 8.shellcheck— no new findings on any of the 8 versus baseline.nvidia-griddand/driversexercises 15 scenarios against all 8 entrypoints: legacy fallback, directory precedence, partial directory, content-vs-mtime, rotation, no-restart-when-unchanged, broken-config rollback, no retry loop, recovery, watcher reaping, both env knobs, non-NLS,set -esafety, invalid interval, and the shutdown race.Not tested: anything requiring a real vGPU driver, a real
nvidia-gridd, a real kubelet..datarelink, or the actual base images. This needs verification on a cluster with vGPU hardware and a live NLS server before merge — hence draft.Unrelated pre-existing bug found
All three
*/precompiled/nvidia-driverfiles call_start_vgpu_topology_daemonbut never define it (0 definitions, versus 1 in the non-precompiled files). Underset -euthat would abort the vGPU path in precompiled images today. Untouched here as out of scope, but it suggests the vGPU path in those three is not exercised upstream. Worth a separate issue.Companion PR
This is one half of a two-repo change and does nothing on its own. The operator half adds the
/drivers/licensing-config/directory mount: NVIDIA/gpu-operator#2677Neither ordering breaks anything — this PR is inert without the operator change, and the operator change is ignored by images without this one.