This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| wiki:ai:nvidia_gpu_operator_installation_and_upgrade [2026/07/20 12:01] – ssuresh | wiki:ai:nvidia_gpu_operator_installation_and_upgrade [2026/07/20 16:53] (current) – ssuresh | ||
|---|---|---|---|
| Line 198: | Line 198: | ||
| - | === Phase 5 — CUDA VectorAdd GPU test === | + | ===== Phase 5 — CUDA VectorAdd GPU test ===== |
| <code -> | <code -> | ||
| Line 224: | Line 224: | ||
| {{: | {{: | ||
| - | ==== Phase 6 — Upgrade the Operator==== | + | ===== Phase 6 — Upgrade the Operator |
| **Concept: ** | **Concept: ** | ||
| Line 353: | Line 353: | ||
| Once burning, nvidia-smi shows GPU-Util climbing toward 100%, memory in use, and gpu_burn listed in the Processes section — genuine GPU activity, i.e. a real ML workload stand-in. | Once burning, nvidia-smi shows GPU-Util climbing toward 100%, memory in use, and gpu_burn listed in the Processes section — genuine GPU activity, i.e. a real ML workload stand-in. | ||
| + | ==== B — Understand what an upgrade will do (before touching anything) ==== | ||
| + | **B1. Pre-upgrade check: what's using the GPU?** | ||
| + | |||
| + | <code -> | ||
| + | kubectl get pods -A -o wide | grep -i gpu | ||
| + | kubectl get pods | ||
| + | </ | ||
| + | |||
| + | Always know what will be disrupted before upgrading. | ||
| + | |||
| + | **B2. Inspect the Operator' | ||
| + | |||
| + | <code -> | ||
| + | kubectl get clusterpolicies -o yaml | grep -A 25 " | ||
| + | kubectl get node $NODE -o jsonpath=' | ||
| + | </ | ||
| + | |||
| + | **Pause / resume automatic driver upgrades cluster-wide: | ||
| + | |||
| + | <code -> | ||
| + | # Pause | ||
| + | kubectl patch clusterpolicies/ | ||
| + | -p ' | ||
| + | # Resume | ||
| + | kubectl patch clusterpolicies/ | ||
| + | -p ' | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | |||
| + | ==== C — Simulate the disruptive part of a driver upgrade ==== | ||
| + | |||
| + | **C1. Cordon the node (maintenance mode)** | ||
| + | |||
| + | <code -> | ||
| + | kubectl cordon $NODE | ||
| + | kubectl get node $NODE # STATUS: Ready, | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | {{: | ||
| + | |||
| + | **C2. Drain the node → watch the workload get evicted** | ||
| + | |||
| + | <code -> | ||
| + | kubectl drain $NODE --ignore-daemonsets --delete-emptydir-data --force | ||
| + | kubectl get pods # gpu-burn is gone (evicted) | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | |||
| + | ==== D — Do the actual upgrade & validate ==== | ||
| + | |||
| + | **D1. Uncordon first so the upgrade schedules cleanly** | ||
| + | |||
| + | <code -> | ||
| + | kubectl uncordon $NODE | ||
| + | kubectl get node $NODE # back to Ready | ||
| + | </ | ||
| + | |||
| + | **D2. Upgrade the GPU Operator** | ||
| + | |||
| + | <code -> | ||
| + | helm list -n gpu-operator | ||
| + | helm search repo nvidia/ | ||
| + | </ | ||
| + | |||
| + | If a newer version exists, run the corrected upgrade (Part I, Phase 6.3). If already newest, you performed a real upgrade earlier in the story — the observation below is the point. Watch which pods restart: | ||
| + | |||
| + | <code -> | ||
| + | kubectl get pods -n gpu-operator -w # Ctrl+C when settled | ||
| + | </ | ||
| + | |||
| + | **D3. Validate after upgrade** | ||
| + | |||
| + | <code -> | ||
| + | kubectl get pods -n gpu-operator | ||
| + | kubectl get nodes -o=jsonpath=' | ||
| + | kubectl apply -f cuda-vectoradd.yaml | ||
| + | sleep 25 | ||
| + | kubectl logs cuda-vectoradd | ||
| + | kubectl delete -f cuda-vectoradd.yaml | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | |||
| + | ==== E — Restore & learn the production lesson ==== | ||
| + | |||
| + | **E1. Restore the workload** | ||
| + | |||
| + | <code -> | ||
| + | kubectl apply -f gpu-burn.yaml | ||
| + | kubectl get pods | ||
| + | </ | ||
| + | |||
| + | **E2. Inference with replicas + PodDisruptionBudget (why production has many nodes)** | ||
| + | |||
| + | Free the GPU first so the inference pod can schedule: | ||
| + | |||
| + | <code -> | ||
| + | kubectl delete -f gpu-burn.yaml --ignore-not-found | ||
| + | </ | ||
| + | |||
| + | Deploy an " | ||
| + | |||
| + | <code -> | ||
| + | cat > inference.yaml <<' | ||
| + | apiVersion: apps/v1 | ||
| + | kind: Deployment | ||
| + | metadata: | ||
| + | name: inference | ||
| + | spec: | ||
| + | replicas: 2 | ||
| + | selector: | ||
| + | matchLabels: | ||
| + | template: | ||
| + | metadata: | ||
| + | labels: { app: inference } | ||
| + | spec: | ||
| + | containers: | ||
| + | - name: inference | ||
| + | image: nvcr.io/ | ||
| + | command: [" | ||
| + | resources: | ||
| + | limits: | ||
| + | nvidia.com/ | ||
| + | --- | ||
| + | apiVersion: policy/v1 | ||
| + | kind: PodDisruptionBudget | ||
| + | metadata: | ||
| + | name: inference-pdb | ||
| + | spec: | ||
| + | minAvailable: | ||
| + | selector: | ||
| + | matchLabels: | ||
| + | EOF | ||
| + | |||
| + | kubectl apply -f inference.yaml | ||
| + | kubectl get pods -l app=inference | ||
| + | </ | ||
| + | |||
| + | See the PDB protect the service — try to drain and watch it get blocked: | ||
| + | |||
| + | <code -> | ||
| + | kubectl drain $NODE --ignore-daemonsets --delete-emptydir-data | ||
| + | # Blocked: " | ||
| + | # Press Ctrl+C to stop the attempt | ||
| + | kubectl uncordon $NODE | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | |||
| + | |||
| + | ===== PART III — ROLLBACK PLAN ===== | ||
| + | |||
| + | **Before any upgrade — capture your safety net** | ||
| + | |||
| + | <code -> | ||
| + | helm list -n gpu-operator | ||
| + | helm get values < | ||
| + | helm history < | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | |||
| + | |||
| + | **Roll back the Operator release** | ||
| + | |||
| + | <code -> | ||
| + | helm history < | ||
| + | helm rollback < | ||
| + | # or a specific revision: | ||
| + | helm rollback < | ||
| + | helm rollback < | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | |||
| + | **Simulation cleanup** | ||
| + | |||
| + | <code -> | ||
| + | kubectl delete -f gpu-burn.yaml --ignore-not-found | ||
| + | kubectl delete -f inference.yaml --ignore-not-found | ||
| + | kubectl delete pdb inference-pdb --ignore-not-found | ||
| + | kubectl uncordon $NODE 2>/ | ||
| + | kubectl get pods | ||
| + | </ | ||
| + | |||
| + | {{: | ||
| + | |||
| + | **Cleanup (avoid a surprise bill!)** | ||
| + | |||
| + | * Pause between sessions: EC2 → Stop (compute stops billing; small EBS cost remains; public IP changes on restart unless you use an Elastic IP). | ||
| + | * Done for good: EC2 → Terminate (deletes instance + disk). | ||
| + | * Release any Elastic IP if you allocated one (billed even while unused). | ||