Ressources MIG exposées par un nœud Kubernetes
Infrastructure

Présenter des GPU à Kubernetes : GPU Operator, device plugin et stratégies MIG

Ressources étendues, device plugin, ClusterPolicy — et le piège de la stratégie MIG « single » qui bloque tout dès qu'on utilise plusieurs profils sur le même nœud.

Les partitions MIG existent sur la carte. Encore faut-il que Kubernetes les voie, sache les attribuer, et refuse d'en donner deux fois la même. C'est le rôle du GPU Operator et du device plugin NVIDIA — avec un piège de configuration qui bloque net dès qu'on utilise plusieurs profils.

Pourquoi Kubernetes ne voit pas un GPU tout seul

Kubernetes sait compter les processeurs et la mémoire. Tout le reste — GPU, cartes réseau spécialisées — passe par le mécanisme des ressources étendues : un composant déclare au nœud « je fournis N unités de telle ressource », et l'ordonnanceur les distribue comme le reste.

Pour les GPU NVIDIA, ce composant est le device plugin. Il inventorie les GPU du nœud, les annonce sous le nom nvidia.com/gpu — ou sous des noms par profil quand MIG est actif — et se charge d'exposer le bon périphérique au conteneur qui l'obtient.

Le GPU Operator, lui, est la couche au-dessus : il déploie et maintient l'ensemble de la pile — pilote, runtime conteneur, device plugin, outils de supervision — et se pilote par un objet de configuration unique, la ClusterPolicy.

Les trois stratégies MIG, et celle qu'il vous faut

Le device plugin peut annoncer les partitions de trois façons :

  • none — MIG ignoré : le GPU est vu comme un tout ;
  • single — les partitions sont annoncées sous le nom générique nvidia.com/gpu, à condition qu'elles soient toutes identiques sur le nœud ;
  • mixed — chaque profil est annoncé sous son propre nom : nvidia.com/mig-3g.71gb, nvidia.com/mig-2g.35gb, etc.

La stratégie par défaut est single. Or une découpe hétérogène — un gros profil, un moyen, deux petits — est exactement ce qu'elle interdit. Le device plugin refuse alors de démarrer avec un message sans ambiguïté :

invalid MIG configuration: more than one MIG device type present on node

Le symptôme, côté exploitation, est déroutant : les partitions existent, nvidia-smi les affiche parfaitement, et Kubernetes n'expose aucune ressource GPU. Le premier réflexe est de lire les journaux du device plugin — l'erreur y est explicite.

Passer en mode mixed

Correction de la stratégie MIG et ressources exposées par le nœud

Un patch sur la ClusterPolicy, un redémarrage du device plugin, et le nœud annonce ses huit partitions sous trois noms distincts.

kubectl patch clusterpolicy cluster-policy --type=merge \
  -p '{"spec":{"mig":{"strategy":"mixed"}}}'

kubectl rollout restart daemonset/nvidia-device-plugin-daemonset -n gpu-operator

Une précision utile : si une configuration de device plugin avait été posée auparavant, elle peut entrer en conflit avec la nouvelle stratégie. Il faut alors la retirer explicitement de la ClusterPolicy avant de redémarrer — sans quoi le plugin repart sur l'ancien comportement sans le dire.

Le résultat se vérifie sur le nœud :

kubectl describe node <nœud> | grep -A6 Allocatable
  nvidia.com/gpu:            0
  nvidia.com/mig-1g.18gb:    4
  nvidia.com/mig-2g.35gb:    2
  nvidia.com/mig-3g.71gb:    2

Noter le nvidia.com/gpu: 0 : une fois MIG actif, le GPU entier n'est plus attribuable. C'est cohérent — il est découpé — mais cela signifie qu'un manifeste réclamant nvidia.com/gpu restera en attente indéfiniment.

Demander une partition dans un pod

resources:
  limits:
    nvidia.com/mig-3g.71gb: 1
  requests:
    nvidia.com/mig-3g.71gb: 1

Trois règles à connaître :

  • les ressources étendues ne se surchargent pas : une partition attribuée à un pod n'est plus disponible pour un autre. C'est l'ordonnanceur qui garantit l'exclusivité ;
  • on demande une seule partition par pod : un conteneur ne peut pas agréger deux instances MIG pour obtenir plus de mémoire ;
  • la valeur doit être identique en requests et en limits, faute de quoi le manifeste est refusé.

Si aucune partition du profil demandé n'est libre, le pod reste en Pending — et la commande kubectl describe pod l'indique explicitement. C'est un comportement sain : mieux vaut un pod en attente qu'un modèle qui démarre sur une partition déjà occupée.

Ce qui reste à faire côté exploitation

  • Nommer les partitions dans les manifestes, pas les cartes. Un service demande un profil, jamais un GPU précis : c'est ce qui permet de déplacer une charge sans réécrire son manifeste.
  • Surveiller l'occupation : combien de partitions de chaque profil sont utilisées, et par quoi. Sans cela, on découvre la saturation au moment d'un déploiement urgent.
  • Documenter la découpe comme une ressource d'infrastructure : c'est un plan d'adressage au même titre qu'un réseau.

La série « IA en interne »

Cinq articles, du choix d'architecture à la mise en service :

  1. Pourquoi internaliser l'exécution des modèles
  2. La H200 : anatomie d'un accélérateur
  3. Partitionner une H200 avec MIG
  4. Présenter des GPU à Kubernetes — vous y êtes
  5. Exécuter des modèles sur K3s avec vLLM

Ces articles s'appuient sur une plateforme réellement exploitée. Les éléments d'infrastructure — noms de machines, adresses internes, espaces de noms — ont été neutralisés ; les principes, commandes et manifestes, eux, sont ceux qui tournent.

Retour au blog