|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Set up single-node K3s with NVIDIA GPU scheduling on a Lambda Cloud instance. |
| 3 | +# Lambda Stack preinstalls the NVIDIA driver and Container Toolkit, so this |
| 4 | +# script only installs K3s, points containerd at the NVIDIA runtime, registers |
| 5 | +# the RuntimeClass, and deploys the device plugin. Run once on a fresh instance. |
| 6 | +set -euo pipefail |
| 7 | + |
| 8 | +echo "==> [1/4] Installing K3s (single node)" |
| 9 | +curl -sfL https://get.k3s.io | sh - |
| 10 | +# Make kubectl usable without sudo for the rest of the script. |
| 11 | +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml |
| 12 | +sudo chmod 644 /etc/rancher/k3s/k3s.yaml |
| 13 | +kubectl wait --for=condition=Ready node --all --timeout=120s |
| 14 | +echo " K3s ready." |
| 15 | + |
| 16 | +echo "==> [2/4] Configuring K3s containerd for the NVIDIA runtime" |
| 17 | +# K3s ships its own containerd. Recent K3s autodetects the NVIDIA runtime when |
| 18 | +# the Container Toolkit is present, generating an "nvidia" runtime in its |
| 19 | +# containerd config. Restart K3s so detection runs now that the toolkit is here. |
| 20 | +sudo systemctl restart k3s |
| 21 | +sleep 10 |
| 22 | +kubectl wait --for=condition=Ready node --all --timeout=120s |
| 23 | +# Verify the nvidia runtime was registered in K3s containerd config. |
| 24 | +if sudo grep -q 'nvidia' /var/lib/rancher/k3s/agent/etc/containerd/config.toml*; then |
| 25 | + echo " NVIDIA runtime detected in K3s containerd config." |
| 26 | +else |
| 27 | + echo " WARNING: nvidia runtime not found in containerd config; GPU pods may fail." |
| 28 | +fi |
| 29 | + |
| 30 | +echo "==> [3/4] Registering the nvidia RuntimeClass" |
| 31 | +kubectl apply -f - <<'RTC' |
| 32 | +apiVersion: node.k8s.io/v1 |
| 33 | +kind: RuntimeClass |
| 34 | +metadata: |
| 35 | + name: nvidia |
| 36 | +handler: nvidia |
| 37 | +RTC |
| 38 | +echo " RuntimeClass 'nvidia' applied." |
| 39 | + |
| 40 | +echo "==> [4/4] Deploying the NVIDIA device plugin" |
| 41 | +kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.17.1/deployments/static/nvidia-device-plugin.yml |
| 42 | +kubectl -n kube-system rollout status daemonset/nvidia-device-plugin-daemonset --timeout=120s |
| 43 | + |
| 44 | +echo "==> Verifying GPU is advertised to the scheduler" |
| 45 | +for i in $(seq 1 12); do |
| 46 | + gpu=$(kubectl get nodes -o jsonpath='{.items[0].status.allocatable.nvidia\.com/gpu}' 2>/dev/null || true) |
| 47 | + if [ -n "${gpu:-}" ] && [ "$gpu" != "0" ]; then |
| 48 | + echo " Node advertises nvidia.com/gpu=${gpu}. Cluster is GPU-ready." |
| 49 | + exit 0 |
| 50 | + fi |
| 51 | + echo " [$i] waiting for GPU to be advertised..." |
| 52 | + sleep 5 |
| 53 | +done |
| 54 | +echo " ERROR: no GPU advertised after 60s. Check device plugin logs:" |
| 55 | +echo " kubectl -n kube-system logs daemonset/nvidia-device-plugin-daemonset" |
| 56 | +exit 1 |
0 commit comments