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.
- BIOS/UEFI : activer VT-d (Intel) ou AMD-Vi / IOMMU (AMD) dans les options de virtualisation.
- Paramètres de démarrage du noyau (
/etc/kernel/cmdlineen UEFI, ou/etc/default/gruben legacy) : ajouterintel_iommu=on iommu=pt(Intel) ouamd_iommu=on iommu=pt(AMD). - Modules noyau (
/etc/modules) : ajoutervfio,vfio_iommu_type1,vfio_pci,vfio_virqfd. - Régénérer l'initramfs (
update-initramfs -u -k all) puis redémarrer l'hôte.
# 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
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 :
# 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.
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.
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 viadocker run --gpus all ...ou, en Compose, une sectiondeploy.resources.reservations.devices. - Disque USB : une fois monté normalement dans la VM (
mount /dev/sdX1 /mnt/disque-externe, idéalement via une entréefstabavec 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.