NVIDIA GPUs sur Kubernetes
Ajouter un GPU à Kubernetes m'a permis de jouer avec Jellyfin et LLaMA sur un serveur Kubernetes qui se trouve sur un ordinateur à la maison mais les étapes sont reproduisible dans le cloud.
Je couvrirais les étapes d'installation et de configuration suivantes:
Kubernetes
Container Runtime
Software
GPU
Pour l'utilisation du GPU sur nos POD, le containeur devra inclure les les logiciels/drivers pour l'utilisation de CUDA.
Comment Kubernetes sait quel POD à besoin de GPUs?
Dans Kubernetes, les pods necessitant des GPU sont identifié par les demandes ressources et les limites dans la coniguration de pod
Ressources étendue
Ressources étendue: Les GPU ne sont pas reconnus nativement par Kubernetes mais sont considéré comme des "ressources étendues" necessitant donc une configuration spéciale pour leur utilisation.
Runtime Class
Runtime Class: Pour utiliser des ressources spécifiquement comme les GPU NVIDIA, Kubernetes peut etre configuré pour utiliser une classe d'éxecution spécifique ('runtimeClassName'). Cela permet d'utiliser le runtime de conteneur NVIDIA qui est optimisé pour les GPU.
spec:
runtimeClassName: nvidia # Utiliser le runtime de conteneur NVIDIADemandes et limites de ressources
Demandes et limites de ressources: La spécification du pod (spec) utilise des demandes et des limites de ressources pour déclarer explicitement qu'un certain nombre de GPU sont nécessaires. Pour les GPU NVIVIA cela est généralement défini comme nvidia.com/gpu
containers:
- name: mon-conteneur-gpu
image: mon-image-gpu
resources:
limits:
nvidia.com/gpu: 1 # Demande 1 GPUNodeSelector
Cet attribut aide à planifier les pods sur les noeuds qui ont les GPU requis. Il garanti que le pod s'exécute sur un nœud capable de répondre aux exigences de GPU
nodeSelector:
kubernetes.io/hostname: nom-du-noeud-gpu # Remplacez par le nom de noeud appropriéTolérance
Il est également courant de voir NoSchedule dans la configuration. Il s'agit d'empecher l'eceution de charges de travail qui n'ont pas explicitement besoin de GPU. (Taints and toleration docs)
spec:
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoScheduleNVIDIA GPU Operator
Les fonctionnalités des GPU NVIDIA sont géré automatiquement par le NVIDIA GPU Operator, cela facilite grandement l'utilisation des cartes graphiques GPU dans un environnement Kubernetes.
NVIDIA GPU Operator : L'opérateur s'occupe automatiquement de plusieurs tâches complexes :
Installation des pilotes : Il peut installer tout seul les logiciels nécessaires pour que les GPU fonctionnent correctement sur les ordinateurs (node).
Configuration du système : Il configure le système pour que les conteneurs puissent utiliser efficacement les GPU.
Étiquetage des nœuds : Il ajoute des labels sur les nodes pour indiquer quels nœuds ont des GPU et combien.
NVIDIA device Plugin : C'est une composante qui:
Détecte les GPU : il detecte automatiquement le nombre de GPU disponible sur chaque node et informe Kubernetes de savoir combien de GPU sont libres ou utilisés.
Surveille la santé des GPU : Il suit l'état de fonctionnement des GPU pour s'assurer que tout fonctionne bien.
Exécution de conteneurs avec GPU : Il permet de lancer des applications qui nécessitent des GPU pour fonctionner plus rapidement, par exemple pour traiter des images ou des calculs complexes.
Planification et exécution : Le cluster Kubernetes a programmé des taches sur les nodes pour être prêts à utiliser les GPU et a donné les instructions nécessaires pour utiliser ces ressources GPU de manière optimale.
Configuration NVIDIA sur Kubernetes
Vérifier la présence de la carte GPU
Utiliser lspci pour faire apparaitre les informations PCI sur votre système et ainsi vérifier la présence de votre carte GPU.
# list all PCI devices with the text NVIDIA
sudo lspci | grep NVIDIAVous devriez voir:
sudo lspci | grep NVIDIA
01:00.0 VGA compatible controller: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] (rev a1)
01:00.1 Audio device: NVIDIA Corporation TU102 High Definition Audio Controller (rev a1)
01:00.2 USB controller: NVIDIA Corporation TU102 USB 3.1 Host Controller (rev a1)
01:00.3 Serial bus controller: NVIDIA Corporation TU102 USB Type-C UCSI Controller (rev a1)Vérification des drivers GPU NVIDIA
Utiliser la recherche sur le site de téléchargement des drivers NVIDIA pour trouver le dernier recommandé pour votre carte.
Par exemple pour ma 2080TI
Version
550.78
Release Date
2024.4.25
Operating System
Linux 64-bit
Language
English (US)
File Size
292.67 MB
Ce qui veut dire que l'on doit prendre la version 550+
Installation des drivers GPU
Il existe plusieurs methode pour installer les drivers sur mon serveur Ubuntu 24.04 LTS:
Officiel Ubuntu NVIDIA drivers via
ubuntu-drivers install(lien)Officiel NVIDIA driver via
.run file(lien)Non officiel version driver NVIDIA via
ppa:graphics-drivers/ppa(lien)
Dans mon cas pour notre installation nous utiliserons l'option (ppa)
Ajouter le repo PPA et installer la version de driver trouvé sur le site officiel.
# add ppa:graphics-driver repo to apt
sudo add-apt-repository ppa:graphics-drivers/ppa --yes
# update apt content list
sudo apt update
# install driver
sudo apt install nvidia-driver-550Tester la version du driver installé avec la commande nvidia-smi
# get the driver version
nvidia-smi --query-gpu=driver_version --format=csv,noheaderDans mon cas j'ai comme retour 550.78
Pour voir la liste des packages installé utilisé dpkg -l avec "nvidia" ou "550"
dpkg -l | grep nvidia
# or
dpkg -l | grep 535Vérifier les modules kernel installé en utilisant lsmod qui permet de lister ce qui se trouve dans /proc/modules
# Show the status of driver modules in the Linux Kernel
lsmod | grep nvidiaSi tout semble bon vous devriez avoir:
# lsmod | grep nvidia
nvidia_uvm 4931584 12
nvidia_drm 122880 0
nvidia_modeset 1355776 1 nvidia_drm
nvidia 54239232 41 nvidia_uvm,nvidia_modeset
i2c_nvidia_gpu 12288 0
i2c_ccgx_ucsi 12288 1 i2c_nvidia_gpu
video 73728 1 nvidia_modesetVérifiez le fichier de version du pilote du kernel:
cat /proc/driver/nvidia/version# cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module 550.78 Sun Apr 14 06:35:45 UTC 2024
GCC version: gcc version 13.2.0 (Ubuntu 13.2.0-23ubuntu4)Vérifiez le fichier de périphérique NVIDIA trouvé:
# any device files (I/O sys calls)
ls /dev/ | grep 'nvidia[0-9]\+'Votre serveur maintenant a bien un GPU NVIDIA d'installé et fonctionnel si le retour de la commande est:
# ls /dev/ | grep 'nvidia[0-9]\+'
nvidia0TIPS
Pour éviter un changement ou une mise à jour non planifié, nous devons appliquer un hold sur les packages
# any package with nvidia in the name should be held
dpkg-query -W --showformat='${Package} ${Status}\n' | \
grep -v deinstall | \
awk '{ print $1 }' | \
grep -E 'nvidia.*-[0-9]+$' | \
xargs -r -L 1 sudo apt-mark holdCe qui donne:
#...
libnvidia-cfg1-550 passé en figé (« hold »).
libnvidia-common-550 passé en figé (« hold »).
libnvidia-compute-550 passé en figé (« hold »).
libnvidia-decode-550 passé en figé (« hold »).
libnvidia-encode-550 passé en figé (« hold »).
libnvidia-extra-550 passé en figé (« hold »).
libnvidia-fbc1-550 passé en figé (« hold »).
libnvidia-gl-550 passé en figé (« hold »).
nvidia-compute-utils-550 passé en figé (« hold »).
nvidia-dkms-550 passé en figé (« hold »).
nvidia-driver-550 passé en figé (« hold »).
nvidia-kernel-common-550 passé en figé (« hold »).
nvidia-kernel-source-550 passé en figé (« hold »).
nvidia-utils-550 passé en figé (« hold »).Avant une mise à jour planifié, il faut penser à retirer le tag hold sur les packages en faisant
sudo apt-mark unhold [package_name]Installation du Container Toolkit NVIDIA
Vous pouvez trouver le guide d'installation officiel de NVIDIA
# add nvidia-container-toolkit repo to apt sources
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
# update apt content
sudo apt update
# install container toolkit
sudo apt install -y nvidia-container-toolkit
Mon environnement Kubernetes étant sur containerd, nous avons besoin de mettre à jour la configuration runtime classes.
Toujours depuis le guide NVIDIA sur la configuration
# options: --dry-run
sudo nvidia-ctk runtime configure --runtime=containerdValider en vérifiant que nvidia runtime existe bien dans la config
sudo cat /etc/containerd/config.toml | grep "containerd.runtimes.nvidia."le résultat doit être:
# sudo cat /etc/containerd/config.toml | grep "containerd.runtimes.nvidia."
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options]Installation de NVIDIA GPU Operator
Nous devons maintenant installer le NVIDIA GPU Operator avec helm.
Vous pouvez installer helm en suivant le guide officiel
Ajouter le repo helm et faire un update:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \
&& helm repo updateDéployer NVIDIA GPU Operator sur votre serveur, par défaut il installe NVIDIA Container Toolkit et NVIDIA drivers comme des container sur le node. Les valeurs sont misent à false car nous venons de le faire.
helm install --wait gpu-operator \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--set driver.enabled=false \
--set toolkit.enabled=falseVérifier le déploiement des pods:
# ensure nothing on kubernetes is wonky
kubectl get pods -n gpu-operator | grep -i nvidiafini vous devriez avoir:
kubectl get pods -n gpu-operator | grep -i nvidia
nvidia-cuda-validator-nfpqp 0/1 Completed 0
nvidia-dcgm-exporter-9jb4j 1/1 Running 0
nvidia-device-plugin-daemonset-ljk4c 2/2 Running 0
nvidia-operator-validator-wzc5l 1/1 Running 0Valider l'installation avec cette comande:
kubectl -n gpu-operator logs deployment/gpu-operator | grep GPUvous devez avoir comme resultat Number of nodes with GPU label","NodeCount":1 ou 1 est le nombre de node avec une GPU
S'il donne comme resulat 0 il y a une erreur, vous pouvez debugger avec la comande:
kubectl get events -n gpu-operator --sort-by='.lastTimestamp'Pour finir, mettez en place un pod sur votre cluster pour verifier que votre integration NVIDIA fonctionne:
# EXPORT NODE NAME!
export NODE_NAME=$(kubectl get nodes -l nvidia.com/gpu.present=true -o custom-columns=NAME:.metadata.name --no-headers | head -n 1
)
cat <<EOF | kubectl create -f -
apiVersion: batch/v1
kind: Job
metadata:
name: test-job-gpu
spec:
template:
spec:
runtimeClassName: nvidia
containers:
- name: nvidia-test
image: nvidia/cuda:12.0.0-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
kubernetes.io/hostname: ${NODE_NAME}
restartPolicy: Never
EOF
regarder les logs:
kubectl logs job/test-job-gpuvous devez avoir ce résultat:

Félicitation 🎉🎉 vous avez un GPU de configuré sur une cluster Kubernetes.
Liens utiles
Site sur lequel je me suis basé
Mis à jour
