De VMware ESXi 6 à Proxmox 7.2 : passthrough GPU et USB vers une VM Docker

De VMware ESXi 6 à Proxmox 7.2 : passthrough GPU et USB vers une VM Docker

L'hyperviseur qui hébergeait ma VM Docker était resté sur VMware ESXi 6 pendant longtemps, notamment parce que le passthrough PCI y était possible mais peu confortable à maintenir. Après la migration vers Proxmox VE 7.2, le même besoin — exposer un GPU et un disque dur USB directement à une VM pour que les conteneurs Docker qu'elle héberge puissent s'en servir — fonctionne enfin sans contorsion. Voici la configuration mise en place.

1. Pourquoi ça coinçait sous ESXi 6

Sous VMware, le passthrough PCI (DirectPath I/O) fonctionne, mais plusieurs limites rendaient l'usage peu pratique dans un contexte homelab : la version gratuite d'ESXi restreint certaines fonctionnalités avancées de configuration matérielle, le support des groupes IOMMU dépend fortement de la carte mère et n'est pas toujours exposé proprement dans l'interface, et un périphérique passé en DirectPath I/O empêche la VM concernée de bénéficier de certaines fonctions de gestion (snapshots à chaud, vMotion — peu utile en mono-hôte, mais symptomatique de la rigidité du dispositif). Résultat : ça marchait, mais chaque redémarrage d'hôte ou changement de configuration matérielle était une source d'inquiétude.

2. Prérequis : activer l'IOMMU

Sur Proxmox, la première étape est identique quel que soit le périphérique à passer : activer la virtualisation d'E/S (Intel VT-d ou AMD-Vi) au niveau du BIOS, puis côté noyau.

  1. BIOS/UEFI : activer VT-d (Intel) ou AMD-Vi / IOMMU (AMD) dans les options de virtualisation.
  2. Paramètres de démarrage du noyau (/etc/kernel/cmdline en UEFI, ou /etc/default/grub en legacy) : ajouter intel_iommu=on iommu=pt (Intel) ou amd_iommu=on iommu=pt (AMD).
  3. Modules noyau (/etc/modules) : ajouter vfio, vfio_iommu_type1, vfio_pci, vfio_virqfd.
  4. Régénérer l'initramfs (update-initramfs -u -k all) puis redémarrer l'hôte.
terminal
# Vérifier que l'IOMMU est bien actif après redémarrage
$ dmesg | grep -e DMAR -e IOMMU

# Lister les groupes IOMMU et ce qu'ils contiennent
$ for d in /sys/kernel/iommu_groups/*/devices/*; do
    n=${d#*/iommu_groups/*}; n=${n%%/*}
    printf 'Groupe %s: ' "$n"; lspci -nns "${d##*/}"
  done
Groupes IOMMU non isolés : pour être passé en passthrough, un périphérique doit idéalement être seul (ou accompagné uniquement de matériel non critique) dans son groupe IOMMU. Si le GPU ou le contrôleur USB partage son groupe avec d'autres composants sensibles (contrôleur SATA du disque système, par exemple), le correctif de contournement (ACS override patch) existe mais affaiblit l'isolation de sécurité entre VMs — à réserver à un hôte mono-VM ou de confiance.

3. Passthrough du GPU

Une fois l'IOMMU actif, le GPU doit être détaché du pilote hôte pour être réservé à vfio-pci :

terminal
# Identifier l'ID fabricant:produit du GPU (ex. carte + audio HDMI associé)
$ lspci -nn | grep -i vga

# Réserver le périphérique à vfio-pci dès le démarrage
$ echo "options vfio-pci ids=XXXX:YYYY,XXXX:ZZZZ" > /etc/modprobe.d/vfio.conf
$ update-initramfs -u -k all && reboot

Dans l'interface Proxmox, sur la VM concernée : Hardware → Add → PCI Device, sélectionner le GPU (et sa fonction audio associée s'il y en a une), cocher All Functions, PCI-Express et ROM-Bar.

Piège classique (GPU grand public) : certains pilotes détectent la virtualisation et refusent de s'initialiser (erreur « Code 43 » côté invité Windows, comportement similaire possible côté Linux). Le contournement consiste à masquer la signature d'hyperviseur à la VM : ajouter args: -cpu host,kvm=off,hv_vendor_id=null,hidden=1 à la configuration de la VM via le shell (/etc/pve/qemu-server/<vmid>.conf), Proxmox n'exposant pas toujours cette option dans l'interface graphique.

4. Passthrough du disque dur USB

Pour un disque USB, deux approches existent. Le passthrough d'un périphérique USB unique (via l'onglet USB Device de la VM) est simple à mettre en place, mais peut se montrer instable sur de gros transferts ou après une mise en veille du contrôleur. Le passthrough du contrôleur USB PCI dans son ensemble est plus fiable pour un disque qui reste branché en permanence : la VM reçoit le contrôleur entier comme s'il lui appartenait, ce qui évite les micro-coupures de connexion que peut provoquer un simple mapping logiciel.

Si la carte mère expose un contrôleur USB dédié dans son propre groupe IOMMU (fréquent sur les ports USB arrière additionnels de certaines cartes de bureau ou stations), il se passe en PCI Device exactement comme le GPU : identification via lspci -nn | grep -i usb, réservation à vfio-pci, puis ajout dans Hardware → Add → PCI Device de la VM.

À vérifier avant de choisir une méthode : tous les contrôleurs USB d'une carte mère ne sont pas dans des groupes IOMMU distincts — plusieurs ports physiques partagent parfois le même contrôleur PCI que le chipset. Un petit tour par la commande de listing des groupes IOMMU (section 2) permet de savoir si le contrôleur qui héberge le port du disque est isolable proprement avant de s'engager dans cette voie.

5. Exploiter GPU et disque depuis Docker, à l'intérieur de la VM

Une fois les deux périphériques visibles côté VM (lspci et lsusb/lsblk à l'intérieur de l'invité les font apparaître comme du matériel natif), il reste à les rendre disponibles aux conteneurs :

  • GPU : installer le pilote correspondant dans la VM (pilote propriétaire NVIDIA ou pile ROCm/AMD selon le matériel), puis le nvidia-container-toolkit (ou équivalent) pour exposer le GPU à Docker. Un conteneur peut alors le solliciter via docker run --gpus all ... ou, en Compose, une section deploy.resources.reservations.devices.
  • Disque USB : une fois monté normalement dans la VM (mount /dev/sdX1 /mnt/disque-externe, idéalement via une entrée fstab avec UUID plutôt que chemin de périphérique), il se bind-mount dans les conteneurs concernés comme n'importe quel volume Docker classique.
Le passthrough n'est qu'une étape : c'est le pilote et l'outillage installés à l'intérieur de la VM qui déterminent si le périphérique est réellement exploitable par les conteneurs.

Conclusion

La combinaison Proxmox VE 7.2 + IOMMU + vfio-pci couvre proprement ce que je cherchais depuis longtemps sous ESXi 6 : un GPU et un disque USB réservés à une seule VM, stables d'un redémarrage à l'autre, et exploitables directement par les conteneurs Docker qui tournent dedans. La partie la plus délicate reste l'analyse des groupes IOMMU en amont — un peu de temps passé à cette étape évite ensuite le plus gros des mauvaises surprises. Si vous voulez être accompagné sur une migration d'hyperviseur ou une configuration de passthrough, n'hésitez pas à me contacter.

R
Raph — Chronoassistance25 ans d'expérience en informatique, cybersécurité et infrastructure.