Intro
Kubernetes device plugins enable pods to access specialized hardware such as GPUs, FPGAs, and NICs. However, misconfigurations can lead to failed pod scheduling, resource deadlocks, or even node crashes. This practical guide targets developers, DevOps consultants, and technical startup teams that need to configure device plugins safely and resolve issues quickly.
We will walk through a structured approach: first, take a complete version and environment inventory; then apply safe configuration changes; next, verify and diagnose problems; and finally, handle failure modes with recovery procedures. Each section includes concrete commands, expected outputs, and real-world examples. By following this operational safety framework—observe before changing, limit blast radius, avoid hardcoded secrets, verify results, and document rollback paths—you will reduce risk and downtime.
Version and Environment Inventory
Before changing any configuration, you must understand your Kubernetes cluster and the device plugin ecosystem. Capturing exact versions, deployment topology, and prerequisites prevents avoidable mistakes. Start with read-only observations, record timestamps, and protect credentials.
Step 1: Collect Cluster and Node Information
Run the following commands to snapshot the current state:
kubectl version --short
kubectl get nodes -o wide
kubectl get pods -n kube-system -l component=kubelet -o wide
Expected output looks like:
Client Version: v1.27.3
Server Version: v1.27.3
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node-1 Ready control-plane 10d v1.27.3 10.0.0.10 <none> Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.7.2
node-2 Ready <none> 10d v1.27.3 10.0.0.11 <none> Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.7.2
Key checks:
- Kubernetes version: Device plugin API
v1beta1was deprecated in 1.20 and removed in 1.25; onlyv1is supported in modern clusters. Confirm the plugin is built against the correct API. - Node OS/kernel: Some plugins require specific kernel modules or drivers (e.g., NVIDIA driver for GPU).
- Container runtime: Plugins interact with the runtime through the kubelet's device plugin registration mechanism; mismatch can cause registration failures.
Step 2: Inspect Existing Device Plugin Deployments
List all pods in kube-system and filter for device plugin names:
kubectl get pods -n kube-system | grep -E 'device-plugin|nvidia|intel|amd|fpga|nic'
Example output:
nvidia-device-plugin-daemonset-6xz7m 1/1 Running 0 3d
If none appear, check the DaemonSet:
kubectl get ds -n kube-system | grep -i device
Expected output might show:
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
nvidia-device-plugin 2 2 2 2 2 <none> 3d
Use kubectl describe ds <name> -n kube-system to view the pod template, resource requests, and tolerations.
Step 3: Verify Node Allocatable Resources and Device Counts
Check if the plugin has advertised devices to kubelet:
kubectl describe node <node-name> | grep -A 10 'Allocatable'
Look for extended resources like nvidia.com/gpu: 2 or amd.com/gpu: 1. If absent, the plugin is not healthy or not registered.
Step 4: Review Plugin Logs for Startup Errors
kubectl logs <plugin-pod-name> -n kube-system --tail=50
Watch for messages like:
I0628 10:00:00.123456 1 main.go:120] Starting FS watcher.
I0628 10:00:00.234567 1 main.go:130] Starting OS watcher.
E0628 10:00:00.345678 1 main.go:140] Failed to initialize NVML: could not load NVML library.
The last line indicates a missing driver—a common mistake.
Safe Configuration Path
When you need to change the device plugin configuration, adopt a step-by-step approach that minimizes risk. Apply one change at a time, validate in a test environment if possible, and always have a rollback plan.
Principle: Least Privilege and Minimal Change
A frequent mistake is rolling out a plugin update to all nodes without testing. Instead:
- Choose a single node or a non-production node pool.
- Label it for testing:
kubectl label node node-1 test-device-plugin=true. - Adjust the DaemonSet's node selector temporarily using a patch or a separate manifest.
Example patch to target only nodes with label test-device-plugin=true:
spec:
template:
spec:
nodeSelector:
test-device-plugin: "true"
Apply with:
kubectl patch ds nvidia-device-plugin -n kube-system --patch '{"spec":{"template":{"spec":{"nodeSelector":{"test-device-plugin":"true"}}}}}'
Wait for rollout and check pod status:
kubectl rollout status ds/nvidia-device-plugin -n kube-system
Expected output:
daemon set "nvidia-device-plugin" successfully rolled out
If successful, gradually expand the label to other nodes.
Placeholders Instead of Secrets
Never put credentials directly in the plugin configuration. Use Kubernetes Secrets and reference them via environment variables or mounted volumes. For example, if a plugin needs a license key, create a Secret:
kubectl create secret generic device-plugin-license --from-literal=license-key='abc123' -n kube-system
Then in the DaemonSet manifest:
env:
- name: LICENSE_KEY
valueFrom:
secretKeyRef:
name: device-plugin-license
key: license-key
Avoid hardcoding the key in the container spec; it appears in kubectl describe and logs.
Example: Updating the NVIDIA Device Plugin Version Safely
Suppose you need to upgrade from version v0.12.2 to v0.14.0. Steps:
- Save the current manifest:
kubectl get ds nvidia-device-plugin -n kube-system -o yaml > nvidia-device-plugin-v0.12.2-backup.yaml
- Apply the new manifest with the new image, but only to the test node (using the label selector).
- Monitor logs and node resource status:
kubectl logs -n kube-system -l name=nvidia-device-plugin-ds --tail=20
kubectl describe node node-1 | grep nvidia.com/gpu
- If the new version fails, rollback by reapplying the backup manifest.
- Once satisfied, remove the node selector to deploy cluster-wide.
Verification and Diagnostics
After configuration changes, verify that the plugin is healthy and devices are available. Diagnosing issues early saves hours of troubleshooting.
Verification Commands
1. Check DaemonSet Status
kubectl get ds -n kube-system | grep nvidia
Expected: DESIRED equals READY and AVAILABLE.
2. Confirm Pod Health
kubectl get pods -n kube-system -l name=nvidia-device-plugin-ds -o wide
Look for Running and Ready 1/1.
If a pod is not ready, use kubectl describe pod <pod-name> -n kube-system to view events. Look for FailedScheduling, CrashLoopBackOff, or FailedMount.
3. Validate Device Registration on Node
kubectl get node node-1 -o json | jq '.status.allocatable'
If nvidia.com/gpu appears with a value greater than 0, the plugin is advertising devices.
4. Test Pod Scheduling with GPU Request
Create a test pod that requests a GPU:
apiVersion: v1
kind: Pod
metadata:
name: gpu-test-pod
spec:
restartPolicy: Never
containers:
- name: cuda-vector-add
image: k8s.gcr.io/cuda-vector-add:v0.1
resources:
limits:
nvidia.com/gpu: 1
Apply and check status:
kubectl apply -f gpu-test-pod.yaml
kubectl get pod gpu-test-pod
If it remains Pending, inspect events:
kubectl describe pod gpu-test-pod
Look for error messages like Insufficient nvidia.com/gpu (no devices available) or Failed to allocate (plugin issue).
Diagnostics for Common Issues
Issue 1: Pod Pending with "Insufficient nvidia.com/gpu"
- Cause: Node does not have GPUs or plugin not running.
- Diagnose:
kubectl get ds -n kube-system,kubectl logs -n kube-system <plugin-pod>. - Fix: Ensure plugin DaemonSet is running on the node and driver is installed.
Issue 2: Plugin Pod CrashLoopBackOff
- Cause: Missing library, permission error, or incompatible API.
- Logs might show:
Fatal: failed to start device plugin: rpc error: code = Unimplemented desc = unknown service v1beta1.DevicePlugin(if using old API on new kubelet). - Fix: Use a plugin version compatible with your Kubernetes version, or update
--device-plugin-version(if supported).
Issue 3: Device Not Visible in Allocatable
- Cause: Plugin not registering due to socket path issue.
- The plugin typically creates a Unix socket at
/var/lib/kubelet/device-plugins/; ensure the DaemonSet mounts that directory withhostPath. - Check pod spec for volume mounts:
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
Failure Modes and Recovery
Even with careful planning, failures happen. Knowing common failure modes and having a recovery plan reduces mean time to recovery (MTTR).
Failure Mode 1: Plugin Upgrade Breaks Device Discovery
Scenario: You updated the plugin from v1 to v2, but v2 requires a different driver version, causing the plugin to crash on startup.
Recovery:
- Immediately rollback the DaemonSet to the previous version:
kubectl rollout undo ds/nvidia-device-plugin -n kube-system
Or apply the backup manifest.
- Verify that pods return to Running and devices reappear:
kubectl get pods -n kube-system -l name=nvidia-device-plugin-ds
kubectl describe node node-1 | grep nvidia.com/gpu
Failure Mode 2: Misconfigured Resource Limits Cause Scheduling Deadlock
Scenario: You set the plugin to advertise a higher number of devices than physically present by editing the --device-count flag. Pods are scheduled but fail when starting.
Recovery:
- Correct the flag in the DaemonSet spec and roll out:
kubectl edit ds nvidia-device-plugin -n kube-system
# change --device-count=N to actual number
- Delete the stuck pods or let them be evicted; they will be rescheduled with correct counts.
Failure Mode 3: Node Cordon and Drain for Plugin Maintenance
Scenario: You need to update the host driver (e.g., NVIDIA driver) and must drain the node.
Steps:
- Cordon the node:
kubectl cordon node-1
- Drain pods (but not daemonsets by default; include
--ignore-daemonsets):
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
- Perform maintenance (driver update, reboot).
- Uncordon:
kubectl uncordon node-1
- Verify plugin pod restarts and devices register.
Important: Always have a recent backup of the DaemonSet manifest and know how to roll back.
Operations Checklist
Use this checklist before and after any device plugin configuration change. It encapsulates best practices to avoid common mistakes.
Pre-Change Checklist
| Item | Command / Check | Expected Result |
|---|---|---|
| 1. Confirm cluster version | kubectl version --short | Server >= 1.25 for v1 API only |
| 2. Confirm plugin version compatibility | Read plugin docs or kubectl describe ds <plugin> -n kube-system | Plugin version supports cluster version |
| 3. Check node resource status | kubectl describe node <node> | grep -A5 Allocatable | Extended resources visible if plugin working |
| 4. Backup current manifest | kubectl get ds <plugin> -n kube-system -o yaml > backup.yaml | Backup file created |
| 5. Label test node | kubectl label node <node> test-device-plugin=true | Label applied |
| 6. Ensure no hardcoded secrets | kubectl get ds <plugin> -n kube-system -o yaml | grep -i secret | Only references to Secret objects |
Post-Change Checklist
| Item | Command / Check | Expected Result |
|---|---|---|
| 1. DaemonSet rollout status | kubectl rollout status ds/<plugin> -n kube-system | "successfully rolled out" |
| 2. Pod health | kubectl get pods -n kube-system -l name=<plugin-label> | Running and Ready 1/1 |
| 3. Device registration | kubectl describe node <node> | grep <resource-name> | Extended resource count >0 |
| 4. Test pod scheduling | Apply test pod requesting device; check status | Pod becomes Running or completes |
| 5. Logs check | kubectl logs -n kube-system <plugin-pod> --tail=50 | No fatal errors |
| 6. Rollback procedure documented | Have kubectl rollout undo command ready | Able to revert quickly |
Example filled checklist for a fictional NVIDIA plugin update:
- Test node label:
node-1labeledtest-device-plugin=true. - Backup file:
nvidia-device-plugin-v0.12.2-backup.yamlsaved. - Post-change:
nvidia.com/gpushows2on node-1. - Rollback:
kubectl rollout undo ds/nvidia-device-plugin -n kube-systemverified.
Conclusion
Kubernetes device plugin configuration mistakes can be avoided with a disciplined approach. Always start by inventorying versions, environment, and current state. Make small, reversible changes with secrets properly handled. Verify thoroughly using the commands and expected outputs provided. When failures occur, rely on rollback procedures and documented recovery steps.
By adopting these practices, you reduce the risk of downtime and keep your GPU-accelerated workloads running smoothly. Begin by implementing the version inventory and safe configuration path in your next plugin update, and expand from there. Remember: a reliable technical workflow makes failure visible, protects sensitive values, limits changes to the intended resource, and defines recovery before an incident forces the decision.