feat: CDI-based NVIDIA GPU passthrough into gVisor actor containers#502
feat: CDI-based NVIDIA GPU passthrough into gVisor actor containers#502eliranw wants to merge 3 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
b510ec9 to
2693528
Compare
|
eliranw is there a way to do this without introducing all the new vendored components? (21k lines of code is too much!) |
|
It seems like we decided to commit vendor packages in this repo. I think it’s best to use the cdi package instead of reimplementing it. As far as I understand, the main downside of committing the vendor folder (instead of gitignoring it) is having a large diff. Do you have a different solution? To make it easier to review, I moved the vendor changes into a separate commit. I noticed many other PRs do the same thing - does this approach make sense to you? |
2693528 to
9cf40a5
Compare
|
eliranw it's not whether the vendor-ed stuff is a separate commit or not. just that we should avoid adding stuff if not really required. see for example - main...dims:substrate:gpu-nocdi |
|
thanks for working on this I'd also like to keep imported deps minimal. I started looking at uVM without privileged and we may have a bigger problem there ... ideally I don't want to require a plugin on the host but we need permission to talk to KVM. I may have an answer to that wrinkle but broadly speaking I'm also hoping that even if not implemented yet we can figure out how we'll extend this to uVM later, as I'm also working on closing the existing gap (durable directory support) at higher priority ... |
934e43d to
f896c76
Compare
When a WorkerPool template requests nvidia.com/gpu, mount the host NVIDIA container toolkit (/usr/local/nvidia/toolkit, read-only) into the worker pod so ateom-gvisor can run nvidia-ctk and the runtime CDI hooks. Non-GPU pools are byte-for-byte unchanged. Signed-off-by: Eliran Wolff <eliranw@nvidia.com>
On worker pods that have a GPU, detect /dev/nvidia0 at actor create and restore, require the cluster in CDI mode (fail fast on a legacy /proc/driver/nvidia overmount), generate a per-pod CDI spec once via nvidia-ctk (--format=json), and merge its device nodes, mounts, hooks, and env into each actor's OCI config.json before runsc create. runsc's --nvproxy auto-enables from the injected device nodes. Non-GPU actors are untouched. The CDI spec is applied with a small in-tree parser (encoding/json) instead of vendoring the container-device-interface library, keeping the dependency footprint minimal. Co-authored-by: Davanum Srinivas <davanum@gmail.com> Signed-off-by: Eliran Wolff <eliranw@nvidia.com>
Add a "GPU worker pools" section to the API guide covering the nvidia.com/gpu request that drives passthrough, what atecontroller and ateom-gvisor do automatically, the CDI-mode requirement, and the gVisor-only scope. Link it from the README and note GPU injection in the ateom-gvisor entry. Signed-off-by: Eliran Wolff <eliranw@nvidia.com>
f896c76 to
5320561
Compare
|
Thanks Davanum Srinivas (@dims) and Benjamin Elder (@BenTheElder). Dropped the vendored CDI as you both suggested and re-tested on a GPU node. I’ve also gated the whole thing to gVisor-only for now so the NVIDIA toolkit mount only lands on gVisor pools, meaning a micro-VM pool that requests a GPU won’t pick up the nvidia toolkit. On uVM - I'll start looking into that |
Summary
Adds CDI-based NVIDIA GPU passthrough into gVisor actor containers, activated only on worker pods that have a GPU. Non-GPU actors are unchanged.
When a WorkerPool template requests
nvidia.com/gpu:atecontrollermounts the host NVIDIA toolkit (/usr/local/nvidia/toolkit, read-only) into the worker pod.ateom-gvisor, at actor create/restore, detects/dev/nvidia0, enforces the ateom worker's GPU was passed using CDI Mode , generates a per-pod CDI spec once vianvidia-ctk(underreapLock), and injects it into each actor's OCIconfig.jsonvia the CDI library beforerunsc create.runsc's--nvproxyauto-enables from the injected device nodes.Why these choices
/var/run/cdi): NVML in the worker pod sees only the GPU the device-plugin assigned, so the spec is correctly scoped per assigned GPU on multi-GPU / multi-worker nodes — no "which device is mine" resolution.nvidia-ctkfrom the mounted toolkit (not vendornvcdi): the toolkit mount is needed anyway for the runtimenvidia-cdi-hookbinary, so this avoids the whole NVIDIA-toolkit Go dependency. Only the CDI library (tags.cncf.io/container-device-interface) is vendored, for the inject step./proc/driver/nvidiaovermount trips the kernel'smount_too_revealing()when runsc runsupdate-ldcachedeprivileged in the gofer; CDI mode never creates that overmount.Guarantees
maybeInjectGPUreturnsnilbefore any side effect when/dev/nvidia0is absent.Non-goals (out of scope, per design)
Non-privileged worker pods; rootless runsc; legacy-mode support; per-actor GPU API; MIG/vGPU/GDS; DRA
Testing
gpuPresent,enforceCDIMode(legacy/missing-toolkit/ok),generateCDISpec(fakenvidia-ctk),injectGPUIntoBundle(fixture CDI + OCI spec),maybeInjectGPUno-op. All green;GOOS=linuxand native builds clean.Live validation
nvml-mock, CDI mode): ran the full substrate flow — GPU WorkerPool → worker pod carriesnvidia.com/gpu+ the read-only/usr/local/nvidia/toolkitmount;ateom-gvisordetects/dev/nvidia0, passes the CDI-mode check, generates the per-pod CDI spec, injects it, andrunsc createsucceeds. A non-GPU control actor starts cleanly. (On the driverless mock,runsc startstops at nvproxy, as expected.)runsc --nvproxy,nvidia-smiruns inside the gVisor sandbox (sees the A10G) and a CUDA kernel (vectorAdd) executes and returnsTest PASSED— real GPU compute through nvproxy.This PR was AI assisted. I tested it on kind, and on real A10G hardware, and reviewed the changes. The CDI-apply approach was contributed by Davanum Srinivas (@dims) (co-authored).