Lab 02 — Kubernetes Device Plugin + Fractional GPU (Go)
Phase: 06 — GPU Scheduling | Difficulty: ⭐⭐⭐⭐☆ | Time: 4–6 hours Language: Go (stdlib) | Hardware: none — a model of the device-plugin contract + a mock kubelet
Concept primer:
../WARMUP.mdCh. 8.
Run
go test ./... # mock kubelet drives registration -> list -> allocate
go run . # prints a narrated end-to-end allocation walkthrough
0. The mission
Implement the Kubernetes device-plugin contract for a fake GPU — the real
mechanism by which a node advertises nvidia.com/gpu: 8 and a pod gets device
nodes injected. Then extend it to advertise fractional GPUs (time-sliced
replicas) and MIG profiles as distinct resources, so the
allocation ≠ isolation boundary (WARMUP Ch. 8) is concrete code, not a slogan.
We model the three plugin operations that matter (the real API is gRPC over a Unix socket; we keep the semantics and the data flow, in plain Go interfaces, so it runs anywhere with no proto toolchain):
| Operation | Real API | What it does |
|---|---|---|
| Register | Registration.Register | tell the kubelet the resource name |
ListAndWatch | streams Device[] | advertise healthy device IDs (→ node capacity) |
Allocate | AllocateResponse | return device nodes + mounts + env to inject |
1. What the walkthrough shows
mode=whole resource=nvidia.com/gpu advertised units=4 (4 physical GPUs)
allocate [GPU-0 GPU-1] -> env NVIDIA_VISIBLE_DEVICES=GPU-0,GPU-1
devices /dev/nvidia0 /dev/nvidia1
isolation: STRONG (dedicated physical devices)
mode=timeslice resource=nvidia.com/gpu advertised units=16 (4 GPUs x 4 replicas)
allocate [GPU-0::3] -> env NVIDIA_VISIBLE_DEVICES=GPU-0 (replica 3 shares GPU-0!)
isolation: NONE (replicas share memory + faults — WARMUP Ch. 4)
mode=mig resource=nvidia.com/mig-1g.10gb advertised units=28 (4 GPUs x 7 instances)
allocate [MIG-0-2] -> env NVIDIA_VISIBLE_DEVICES=MIG-GPU-0/2/0
isolation: STRONG (hardware-partitioned instance)
The same plugin API advertises all three — but the isolation each delivers is completely different. Time-slicing's "16 GPUs" are 4 physical devices wearing 4 hats each; the plugin happily allocates replica 3 of GPU-0 to a pod with no memory or fault isolation from replicas 0–2. That's the lesson the lab burns in: the device plugin allocates; it does not isolate.
2. Reading order
device.go— theDevice,Plugininterface, and the three modes (whole / timeslice / mig) that change only what gets advertised.plugin.go—ListAndWatch(build the advertised list) andAllocate(pick devices, build the injection response withNVIDIA_VISIBLE_DEVICES).kubelet_mock.go— the mock kubelet: registers the plugin, reads the device list, and requests an allocation, exactly as the real kubelet does.plugin_test.go— the contract tests.
3. Extensions
- MIG geometry: advertise mixed profiles (
1g.10gb,2g.20gb,3g.40gb) as separate resource names from the same physical GPUs, respecting that a GPU's instances are mutually exclusive (allocating a3gconsumes capacity the1gs would have used) — the real MIG accounting problem. - Health transitions: mark a device
Unhealthy(model an Xid error from Phase 04/10);ListAndWatchmust re-advertise and the kubelet must stop scheduling onto it. gpu-feature-discovery: emit node labels (nvidia.com/gpu.product=H100,nvidia.com/gpu.memory=80) so the scheduler can do affinity.- Preferred allocation: implement
GetPreferredAllocationto pick devices that share NVLink (topology — Phase 08) for multi-GPU requests.
4. Common pitfalls
- Conflating advertised units with isolation — the entire point. A test
asserts that two timeslice replicas of the same physical GPU resolve to the
same
NVIDIA_VISIBLE_DEVICESvalue (proof they share hardware). - Forgetting the env/mount injection — without it the container sees the resource accounted but can't actually reach the GPU (Phase 04 Ch. 9).
- Letting
Allocatehand out more replicas than the device has, or replicas of an unhealthy device.
5. What this lab proves about you
You can implement the exact integration point between Kubernetes and GPUs, and you can articulate — with running code — why "fractional GPU" means very different isolation guarantees depending on the mechanism. When a customer or a PM asks for "GPU sharing in k8s," you can design the honest answer (which resource, which isolation, which tier — Phase 12).