Repository navigation
feat(kubernetes): default gpu-operator to an OS-provided driver on Talos - #3585
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: cozystack/cozystack/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review. 📝 WalkthroughWalkthroughGPU Operator defaults disable driver and toolkit management and configure validation of host-installed NVIDIA drivers. Device-plugin defaults use CDI annotations and UUID device IDs. Tests cover these settings, absent kernel-module ConfigMap paths, and environment-list overrides. ChangesTalos GPU Operator integration
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Feature Merge Risk: ⚪ Minimal · up to This change sets Talos GPU Operator defaults to use host-provided NVIDIA drivers and CDI. No blocking issue was found, and the author reports a successful hardware test. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change avoids competing driver installations, but GPU availability now depends on the host driver and CDI configuration being ready together. The available evidence does not establish a new privilege exposure or verify recovery from a partial rollout. Retained concerns
Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
End-to-end run done, on hardware, and it holds. Reporting it as promised rather than leaving the claim on unit tests alone. Setup: a fresh single-node tenant cluster, one node group with an L40S (
The last row matters because a Talos node whose extension services cannot start reboots at roughly 70 minutes of uptime while still reporting The L40S is the point: everything behind this configuration was previously only exercised on Blackwell (GB202). It works unchanged on Ada, so the set is not GPU-generation-specific. What this run does not establish, stated plainly:
Taking this out of draft on the strength of the above. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/system/gpu-operator/values.yaml (1)
37-48: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRemove the stale
NVreg_NvLinkDisable=1default.Lines 37-43 state that this parameter is no longer a default. However, Lines 47-48 still supply it when an operator sets
driver.enabled: trueandkernelModuleConfig.create: true.Leave
contentempty by default. Require an operator to set the parameter explicitly when it is required.Proposed fix
name: nvidia-kernel-module-params - content: | - NVreg_NvLinkDisable=1 + content: ""🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/system/gpu-operator/values.yaml` around lines 37 - 48, Update the kernelModuleConfig default in values.yaml so its content is empty instead of supplying NVreg_NvLinkDisable=1. Preserve the existing create and name settings, requiring operators to explicitly provide the parameter when enabling this configuration.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/apps/kubernetes/tests/gpu_operator_hami_test.yaml`:
- Around line 46-66: Add contains assertions in the gpu-operator test for
NVIDIA_DRIVER_ROOT, DEVICE_ID_STRATEGY set to uuid, and CDI_ANNOTATION_PREFIX
set to cdi.k8s.io/. Place them alongside the existing validator.driver and
devicePlugin environment assertions, preserving the exact expected paths and
values.
---
Outside diff comments:
In `@packages/system/gpu-operator/values.yaml`:
- Around line 37-48: Update the kernelModuleConfig default in values.yaml so its
content is empty instead of supplying NVreg_NvLinkDisable=1. Preserve the
existing create and name settings, requiring operators to explicitly provide the
parameter when enabling this configuration.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 9efeb3d5-ea76-4de7-b09e-3bc34d570290
📒 Files selected for processing (3)
packages/apps/kubernetes/templates/helmreleases/gpu-operator.yamlpackages/apps/kubernetes/tests/gpu_operator_hami_test.yamlpackages/system/gpu-operator/values.yaml
|
Two findings from the review: one taken, one I disagree with. Taken — the missing assertions. 48007bd pins Not taken — emptying That content is only read when an operator sets both There is also no contradiction to resolve. "No variant enables it any more" and "the content is right when it is enabled" are both true at once: The comment above it was updated in this PR to say precisely that nothing enables it by default and that it is kept for an operator who re-enables the driver container, who then also has to set |
48007bd to
61dce5d
Compare
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
mattia-eleuteri NOT LGTM. The values themselves look right to me, the blockers are in the text around them: one wrong field path that users will follow, and commit and comment wording that the contributing guide rules out.
Business context: tenant GPU pools run Talos workers with the NVIDIA driver from a system extension, and the gpu-operator addon default still assumed an operator-installed driver, so the validator looped and pods got the device without CUDA libraries.
Blockers
B1: nodeGroups.<name>.kernelModules does not exist
The comments and the release note send the reader to nodeGroups.<name>.kernelModules in packages/apps/kubernetes. That chart has no nodeGroups at the base of this PR or on current main: worker pools are the separate KubernetesNodes app in packages/apps/kubernetes-nodes. #3571 adds kernelModules as a top-level field of that app, not under nodeGroups. An operator who reads the release note to find where NVreg_NvLinkDisable=1 went looks for a key that is not there.
Places: templates/helmreleases/gpu-operator.yaml:14, tests/gpu_operator_hami_test.yaml:98, packages/system/gpu-operator/values.yaml:41, and the release-note block in the PR body. Fix: name the KubernetesNodes field (kernelModules on the pool) and its package.
B2: commit 61dce5d carries review-iteration wording
The body opens with "Review feedback on the addon default:". The contributing guide (Review Blockers, commit message) blocks review-iteration vocabulary, and with merge commits this body lands in main as is. The simplest fix is to squash it into d105bbe, since it only adds assertions for the same change. Otherwise drop the first sentence and keep the rest, which already says why.
B3: comments carry change history and issue labels
The same Review Blockers section rules out comments that log a change or have a ticket as their content. Examples:
gpu-operator.yaml:8: "This replaces the previous default, which assumed the Ubuntu shape..." andpackages/system/gpu-operator/values.yaml:37: "No variant enables it any more. Tenant Kubernetes clusters used to..." describe what the code was before. That belongs in the commit message, which already has it.gpu_operator_hami_test.yaml:44and:56: "gap 3" and "gap 4" mean something only to someone who has the issue open.gpu_operator_hami_test.yaml:23says "These three asserts are the whole contract", while that test has ten asserts.:67("The remaining three are just as load-bearing as the two above") reads as an answer to a review comment rather than a note for the next reader.
The template comment is also about 50 lines, longer than the values it describes. Keep the constraints that the values cannot show (why driver and toolkit are off on Talos, why the validator needs the host root, why CDI, the list-replace trap in mergeOverwrite) and drop the history and the production-validation claim.
Checked, no change needed
- The
packages/system/gpu-operatorchange is comment only, so the management cluster gpu-operator variants render the same as before. helm unittestontests/gpu_operator_hami_test.yamlpasses (8 tests). Flipping driver or toolkit back on, changing the validator symlink flag, changingNVIDIA_CTK_PATH, or enabling the device plugin under HAMi each fails a test.pre-commitandE2E Testsare green on 61dce5d.- On the
kernelModuleConfig.contentthread I agree with keepingNVreg_NvLinkDisable=1: it is inert withcreate: falseand correct when someone turns the driver container back on.
Non-blocking: with addons.hami.enabled this now also turns off driver and toolkit for HAMi tenants, and the PR says HAMi on Talos is not validated. An issue for the HAMi CDI wiring would give that a home.
Closes the gpu-operator half of cozystack#3563. Tenant clusters have run Talos workers since 1.6.0, where the NVIDIA driver comes from a system extension baked into the worker image rather than from the operator's driver container. The addon default still described the Ubuntu shape, so a GPU node group came up with the operator fighting the OS for the driver and no path at all for CUDA libraries to reach a tenant pod. Three things change, each fixing one silent failure: driver.enabled and toolkit.enabled go false. The driver container would load its own module and clash with the extension's; the toolkit container would rewrite /etc/containerd/config.toml, which Talos owns and which already registers the nvidia runtime with enable_cdi = true and cdi_spec_dirs = ['/run/cdi']. validator.driver.env points DRIVER_ROOT and NVIDIA_DRIVER_ROOT at / and disables /dev/char symlink creation. The driver validator otherwise looks for a driver container install, finds none, never writes its sentinel, and leaves the device plugin blocked behind toolkit-validation — the loop on "Attempting to validate a driver container installation". devicePlugin.env selects cdi-annotations and points NVIDIA_CTK_PATH at the host's nvidia-ctk. Tenant pods carry no runtimeClassName and did not need one on Ubuntu, where the toolkit made nvidia the default containerd runtime; Talos does not, so CDI is the only route for the CUDA libraries. DEVICE_ID_STRATEGY, NVIDIA_DRIVER_ROOT and CDI_ANNOTATION_PREFIX are set and tested alongside it: CDI device names key on the UUID strategy, the plugin resolves the driver from NVIDIA_DRIVER_ROOT, and the annotation prefix has to be the one containerd reads, so a regression in any of them breaks device resolution on its own. The previous default fed NVreg_NvLinkDisable=1 to the driver container through the nvidia-kernel-module-params ConfigMap. With that container off the ConfigMap is mounted by nothing, so the default is removed. On Talos a module parameter belongs to the worker machine config, which the kernelModules field of the KubernetesNodes app (packages/apps/kubernetes-nodes, cozystack#3571) writes. The wrapper chart keeps the ConfigMap for an operator who re-enables the driver container. Every value here is the configuration validated on a production Talos GPU node group, minus the parts that only mattered while the driver container was in play. Not covered: HAMi. When addons.hami.enabled the operator's device plugin stays off and HAMi serves the GPUs, and HAMi's own plugin needs equivalent CDI wiring on Talos that this default does not attempt. Refs: cozystack#3563 Assisted-by: LLM Signed-off-by: Mattia Eleuteri <[email protected]>
61dce5d to
669fb24
Compare
|
Aleksei Sviridkin (@lexfrei) all three blockers are fixed in 669fb24, pushed as a single commit. B1. Every B2. I squashed 61dce5d into d105bbe. The CDI assertions it added are now justified in one paragraph of the single commit body, with no review wording. B3. The template comment is down from about 50 lines to 27. It keeps only the constraints: why driver and toolkit are off, why the validator is pointed at the host root, why CDI is the only route (and the pod-admission timing), and the list-replace trap in Nothing changed in behaviour. The rendered HelmRelease is byte-identical to 61dce5d with HAMi on and with HAMi off, and |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
mattia-eleuteri LGTM. The rendered HelmRelease is the same as on the head I reviewed, with HAMi on and off, and the text is fixed. One thing about order: the comment, the body and the release note point at the top-level kernelModules field of KubernetesNodes, which only #3571 adds. This should land after #3571, otherwise main documents a field that does not exist yet.
What this PR does
Closes the gpu-operator half of #3563 — gap 3 (the operator cannot validate a driver it did not install) and gap 4 (nothing routes CUDA libraries to a tenant pod).
Tenant clusters have run Talos workers since 1.6.0, where the NVIDIA driver comes from a system extension baked into the worker image rather than from the operator's driver container. The addon default still described the Ubuntu shape, so a GPU node group came up with the operator fighting the OS for the driver and no path at all for the CUDA libraries.
Three changes, each closing one silent failure:
driver.enabled: false,toolkit.enabled: false/etc/containerd/config.toml, which Talos owns and which already registers thenvidiaruntime withenable_cdi = trueandcdi_spec_dirs = ['/run/cdi']validator.driver.env:DRIVER_ROOT=/,NVIDIA_DRIVER_ROOT=/,DISABLE_DEV_CHAR_SYMLINK_CREATION=truetoolkit-validation— the loop onAttempting to validate a driver container installation(gap 3)devicePlugin.env:DEVICE_LIST_STRATEGY=cdi-annotations,NVIDIA_CTK_PATH=/usr/local/bin/nvidia-ctk, plusDEVICE_ID_STRATEGY,NVIDIA_DRIVER_ROOT,CDI_ANNOTATION_PREFIXruntimeClassNameand did not need one on Ubuntu, where the toolkit madenvidiathe default containerd runtime. Talos does not, so CDI is the only route: the pod gets the device and no CUDA libraries (gap 4)Every value is the configuration validated on a production Talos GPU node group, minus the parts that only mattered while the driver container was in play. No DaemonSet, no new image, no new package — the fix is values.
The removed default
The previous default fed
NVreg_NvLinkDisable=1to the driver container through thenvidia-kernel-module-paramsConfigMap. With that container off the ConfigMap is mounted by nothing, so this removes the default. On Talos the parameter belongs to the worker machine config, which thekernelModulesfield of the worker pool writes: that field is top-level in the KubernetesNodes app (packages/apps/kubernetes-nodes), added by #3571, and its automatic set for a pool holding annvidia.com/*GPU already loadsnvidiawithNVreg_NvLinkDisable=1. The wrapper chart keeps the ConfigMap feature for an operator who re-enables the driver container throughvaluesOverride. A test pins the absence so the dead default cannot come back and offer a second, inert source for the same setting.Relationship to #3571
Independent files, no conflict, but only useful together: this makes
driver.enabled: falsecorrect, and #3571 is what actually loads the modules the extension ships. Merged alone, this changes a GPU node group from "operator fights the OS" to "operator stays out of the way and the modules still are not loaded" — better, but not yet working. #3571 alone leaves the operator fighting for the driver. Either order is safe; both are needed for a GPU node group to work.What is verified, and what is not
Verified here: the rendered HelmRelease values, that
valuesOverridestill wins over each new key, and that the removed default is gone. The individual values are the ones running in production today, applied by hand throughaddons.gpuOperator.valuesOverride.Not verified here: this exact default exercised end-to-end as the chart's own output. That needs a Talos GPU node group whose modules load, which needs #3571 released. I would rather say so than imply a green e2e that does not exist — happy to hold this as draft until I have run a single-node L40S cluster against the chart default, and I will report the result on this PR either way.
Not covered
HAMi. When
addons.hami.enabledthe operator's device plugin stays off and HAMi serves the GPUs; HAMi's own plugin needs equivalent CDI wiring on Talos, which this default does not attempt. Flagging rather than guessing — the production cluster this was derived from runs HAMi disabled, so I have no validated configuration for that path. Worth its own issue if a maintainer confirms the shape.Also not in scope, and unchanged from the merge base:
talos.installerRepositoryandtalos.versionreach the worker machine config unvalidated (being tracked separately by Aleksei Sviridkin (@lexfrei)), and thenvidia-operator-validatorchain for the management cluster's own passthrough/vgpu variants, which never load the host driver at all.Screenshots
No UI changes.
Screenshots
Downstream repositories
Release note
Summary by CodeRabbit
Configuration
/dev/charsymlinks.Documentation
valuesOverridereplaces lists wholesale.