SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor

Peut-on installer Proxmox sur un VPS ?

La plupart des hébergeurs masquent le flag vmx. Vérifiez-le avec kvm-ok en une minute et repérez les erreurs exactes avant de lancer KVM ou Proxmox.

La réponse courte

La virtualisation imbriquée consiste à exécuter un hyperviseur dans une machine virtuelle : votre VPS est déjà un invité, et vous voulez qu’il héberge ses propres invités. Elle ne fonctionne que si l’hyperviseur de votre fournisseur expose délibérément les extensions de virtualisation du processeur à votre instance. Vérifiez /proc/cpuinfo pour rechercher l’indicateur vmx (Intel) ou svm (AMD). Si aucun des deux n’apparaît, aucune configuration effectuée dans le VPS ne pourra résoudre le problème.

Commençons par clarifier un point : Docker n’a besoin de rien de tout cela. Les conteneurs partagent le kernel de votre VPS et n’utilisent jamais /dev/kvm. Si votre objectif réel est d’exécuter plusieurs services dans des conteneurs sur votre serveur, vous disposez déjà de tout ce qu’il faut. La virtualisation imbriquée devient utile si vous avez besoin d’un second kernel, d’un lab Proxmox, d’un invité Windows, de microVM Firecracker, d’un émulateur Android, d’un environnement de test Kubernetes composé de véritables machines virtuelles ou de runners CI qui démarrent des images de machines virtuelles.

Ce qui est réellement imbriqué

Trois couches :

  • L0, l’hyperviseur du fournisseur, directement sur le matériel. Vous n’y avez pas accès.
  • L1, votre VPS. Pour L0, il s’agit simplement d’un invité.
  • L2, la VM que vous voulez exécuter dans votre VPS.

La virtualisation matérielle repose sur VT-x (l’indicateur vmx) et EPT sur Intel, ainsi que sur AMD-V / SVM (svm) et RVI/NPT sur AMD. Un hyperviseur utilise ces instructions pour passer en mode invité et permettre au CPU de parcourir deux tables de pages simultanément.

Aucune de ces technologies n’a été conçue pour être réentrante. L’imbrication est donc émulée : lorsque L1 exécute une instruction VMX telle que VMLAUNCH ou VMRESUME, l’exécution remonte vers L0, qui gère les structures shadow de L2 pour le compte de L1. Sur les CPU prenant en charge le VMCS shadowing, les instructions VMREAD et VMWRITE de L1 peuvent être traitées sans exit. Cela réduit une grande partie de ces transitions, mais pas toutes. KVM gère bien ce mécanisme, mais c’est L0 qui doit effectuer ce travail supplémentaire à chaque exit. Le fournisseur doit donc l’activer explicitement.

Lorsque L0 utilise KVM, deux conditions doivent être remplies pour qu’une L2 bénéficie de l’accélération :

  1. Le module KVM de L0 doit être chargé avec nested=1.
  2. L0 doit fournir à votre VPS un modèle de CPU qui expose cet indicateur : <cpu mode='host-passthrough'/> dans libvirt, cpu: host dans Proxmox et -cpu host avec QEMU brut. Un modèle générique émulé (qemu64, kvm64) masque vmx, même si l’imbrication est activée globalement.

Les autres hyperviseurs disposent de leur propre option. Hyper-V, par exemple, émule les extensions de virtualisation pour un hyperviseur imbriqué à l’intérieur de ses VM, mais uniquement dans les VM où l’imbrication a été activée individuellement.

Vérifier votre VPS en une minute

# 1. Are you in a VM, and under what?
systemd-detect-virt          # kvm, vmware, xen, microsoft, or "none" on metal

# 2. Does the CPU expose the extensions to you?
grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u
lscpu | grep -i -E 'virtual|hypervisor'

# 3. The definitive check
sudo apt update && sudo apt install -y cpu-checker
kvm-ok

# 4. The device node the whole stack depends on
ls -l /dev/kvm

Une instance opérationnelle affiche vmx ou svm, kvm-ok indique KVM acceleration can be used et /dev/kvm existe avec le mode root:kvm 660. Si le flag est présent, mais pas le device node, chargez le module manuellement et consultez le journal du noyau :

sudo modprobe kvm_intel     # or kvm_amd
sudo dmesg | tail -n 20

Un fichier est cité en permanence et souvent mal interprété :

cat /sys/module/kvm_intel/parameters/nested   # Y or N

Dans votre VPS, il s’agit du paramètre de votre module KVM. Il indique si un guest L2 pourrait imbriquer un troisième niveau. Il ne dit rien sur l’activation du nesting par L0 pour votre VPS : /proc/cpuinfo et kvm-ok répondent à cette question. Le paramètre nested est celui que vous définissez sur une machine qui vous appartient entièrement :

echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intel

La suppression du module est refusée lorsqu’une VM est en cours d’exécution. Arrêtez donc d’abord les machines invitées. Si cette machine est un hôte Proxmox, l’activation de la virtualisation imbriquée dans Proxmox VE 9 décrit la même modification de modprobe.d, ainsi que le paramètre cpu: host par VM qui rend le flag visible dans une machine invitée.

Pourquoi la plupart des hébergeurs de VPS la désactivent

  • Migration à chaud. Vous attribuer vmx revient à exposer un modèle de CPU qui prend en charge ce flag. Une machine virtuelle qui dépend de ces fonctionnalités CPU ne peut pas être migrée de manière fiable vers une machine dont le CPU ne les prend pas en charge. Un hébergeur qui évacue des nœuds en migrant les clients renonce à cette possibilité dès qu’il active la virtualisation imbriquée.
  • Surface d’attaque. Les chemins VMX/SVM imbriqués comptent parmi les parties les plus complexes de la couche de virtualisation du kernel, avec un historique de CVE à l’avenant.
  • L0 n’est peut-être pas KVM. Si systemd-detect-virt affiche vmware, xen ou microsoft, les règles de virtualisation imbriquée sont celles de cette stack, et non celles de KVM.

Aucun flag sur votre instance ? Demandez au support (certains l’activent VM par VM), choisissez une offre qui documente la virtualisation imbriquée ou passez à une machine dédiée. La suite suppose que vous disposez de root sur une machine qui affiche ce flag.

Exécuter un invité L2 avec libvirt

sudo apt install -y qemu-system-x86 libvirt-daemon-system virtinst ovmf
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm "$USER"   # log out and back in

virt-install \
  --name guest1 \
  --memory 2048 \
  --vcpus 2 \
  --cpu host-passthrough \
  --disk path=/var/lib/libvirt/images/guest1.qcow2,size=20,format=qcow2,bus=virtio \
  --network network=default,model=virtio \
  --os-variant debian13 \
  --location https://deb.debian.org/debian/dists/trixie/main/installer-amd64/ \
  --graphics none \
  --console pty,target_type=serial \
  --extra-args 'console=ttyS0,115200n8'

Aucune session graphique n’est nécessaire. Une installation série prend un certain temps. Lancez-la donc dans un shell persistant : le même flux de travail tmux qui maintient les sessions Claude Code actives sur un VPS conserve une console virt-install attachée malgré une déconnexion SSH. Si --os-variant debian13 est rejeté, votre osinfo-db est antérieur à cette version. Exécutez osinfo-query os, puis choisissez un nom existant. --cpu host-passthrough transmet vmx à L2. Cette option est nécessaire uniquement si L2 doit à son tour exécuter de la virtualisation. Rendez l’invité sûr au démarrage avec virsh autostart guest1.

Le bus virtio du disque et de la carte réseau n’est pas un détail : les périphériques IDE et e1000 émulés provoquent bien plus souvent des sorties vers l’hyperviseur que les files virtio. Avec la virtualisation imbriquée, une sortie que L0 ne peut pas traiter seul est remontée à L1. Son traitement peut alors déclencher d’autres sorties dans L1.

Réseau : la partie que les tutoriels omettent

Votre VPS possède une seule IP publique et se trouve derrière une infrastructure qui filtre les adresses MAC inconnues. Deux conséquences en découlent.

Le bridging de guests L2 sur le réseau public ne fonctionnera généralement pas. Placez br0 sur la carte réseau publique, attribuez sa propre adresse MAC au guest, et vous verrez les requêtes ARP sortir sans recevoir de réponse : le switch du fournisseur supprime les trames provenant d’une adresse MAC qui ne vous a jamais été attribuée. Si c’est le symptôme observé, cessez de déboguer le bridge : c’est le fonctionnement attendu.

Utilisez plutôt le réseau NAT. libvirt fournit default : virbr0, 192.168.122.0/24, des baux dnsmasq et une connectivité sortante immédiatement opérationnelle. Pour les connexions entrantes, terminez TLS sur L1 et utilisez un proxy vers le guest. Les chemins des certificats ci-dessous proviennent de l’émission d’un certificat Let’s Encrypt avec Certbot sur Nginx :

server {
    listen 443 ssl;
    server_name lab.example.com;

    ssl_certificate     /etc/letsencrypt/live/lab.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/lab.example.com/privkey.pem;

    location / {
        proxy_pass http://192.168.122.50:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Commencez par attribuer un bail statique au guest (virsh net-edit default), afin que l’adresse indiquée dans proxy_pass reste inchangée.

Les interfaces d’administration ne doivent pas être exposées sur Internet : VNC sur 5900 et l’interface web Proxmox sur 8006 doivent rester liées à loopback. Accédez-y via un tunnel SSH (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) ou au moyen d’un VPN WireGuard auto-hébergé vers le VPS, qui place toute la plage de guests 192.168.122.0/24 à un seul saut réseau privé. Limitez le firewall à sudo ufw allow 22,80,443/tcp, et à rien d’autre. Si les guests perdent leur connectivité sortante juste après l’activation d’ufw, la cause habituelle est DEFAULT_FORWARD_POLICY="DROP" dans /etc/default/ufw. Définissez-le sur ACCEPT, puis rechargez ufw.

Proxmox sur un VPS

Proxmox VE 9 repose sur Debian 13. Il s’installe donc sur un VPS Debian en ajoutant le dépôt pve-no-subscription et le paquet proxmox-ve. Reprenez les lignes du dépôt et du keyring dans la documentation officielle actuelle de Proxmox. Une URL copiée depuis un ancien article de blog peut bloquer l’installation. Avant de consacrer une soirée à la configuration réseau ci-dessous, il est préférable de déterminer si Proxmox a réellement sa place sur du matériel loué. La comparaison des coûts et des capacités entre un serveur Proxmox à domicile et un VPS loué répond à cette question en intégrant déjà les calculs liés à l’alimentation et au matériel.

Les paquets ne sont pas le point difficile. Proxmox attend que vmbr0 soit bridgé sur une carte réseau physique, ce qui mène directement à l’impasse du filtrage MAC décrite plus haut. Sur un VPS, la configuration qui fonctionne est un vmbr0 en NAT ou routé, sans port physique attaché, avec les guests sur une plage privée et des règles DNAT ou un reverse proxy sur l’hôte pour les services publics. Lorsque les services exposés sont des conteneurs plutôt que des VM, Traefik qui place plusieurs applications derrière un même fichier Docker Compose assure le même routage avec des certificats automatiques. Prenez d’abord un snapshot de /etc/network/interfaces : une mauvaise définition du bridge peut vous verrouiller hors d’une machine dont vous n’avez peut-être pas accès à la console.

Performances, en toute transparence

La virtualisation imbriquée est plus lente qu’une virtualisation à un seul niveau, et le mécanisme est ciblé plutôt que diffus : le coût concerne les sorties de mode et la traduction d’adresses, pas les instructions ordinaires. Lorsque EPT/NPT est disponible, L0 fusionne les tables de pages de L1 pour L2 et les siennes dans une seule table fantôme. En cas de succès dans le TLB, l’exécution se fait donc à la vitesse du matériel. Un échec dans le TLB coûte davantage : le matériel parcourt simultanément la table de pages du guest et la table fantôme, et chaque modification apportée par L1 à ses propres tables force une sortie de mode afin que L0 puisse resynchroniser la table fantôme. Les opérations qui quittent le mode guest sont coûteuses : E/S, interruptions de timer, MMIO et interruptions interprocesseur. En effet, une sortie de L2 est traitée par L0 et peut être renvoyée à L1, puis à L2. Les charges CPU qui utilisent un petit ensemble de travail restent proches des performances natives. Les grands ensembles de travail en mémoire subissent le coût des échecs dans le TLB. Les charges dominées par les appels système, les paquets réseau et les E/S disque ressentent davantage les différents niveaux de virtualisation.

En pratique, utilisez donc des périphériques virtio partout. Votre fichier qcow2 se trouve sur un disque que le fournisseur a déjà virtualisé. Deux niveaux de thin provisioning sont alors empilés, et cache=none sur le disque guest empêche les mêmes blocs de se retrouver simultanément dans deux page caches. Aucun chiffre de benchmark ici : mesurez votre propre charge sur votre propre instance.

Modes de défaillance et messages affichés

INFO: /dev/kvm does not exist / KVM acceleration can NOT be used depuis kvm-ok. Soit le module n’est pas chargé, soit le flag n’est pas exposé. Vérifiez d’abord /proc/cpuinfo.

kvm: disabled by bios dans dmesg. Sur une machine bare metal, activez l’option VT-x/SVM dans le firmware. Dans un VPS, cela signifie que L0 ne vous transmet pas les extensions. Aucune commande saisie dans le guest ne peut modifier ce comportement.

modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. Le CPU vu par votre kernel ne fournit pas vmx. Là encore, c’est une décision de L0.

Could not access KVM kernel module: Permission denied. Le problème vient des permissions, pas du matériel. ls -l /dev/kvm doit afficher le groupe kvm et le mode 660. Ajoutez-vous à ce groupe, puis ouvrez une nouvelle session de login. L’appartenance à un groupe ne s’applique pas à une session déjà ouverte.

kvm: Device or resource busy au démarrage de QEMU. Un autre module d’hyperviseur utilise le CPU. Exécutez lsmod, recherchez vboxdrv ou les modules VMware à côté de kvm_intel, puis déchargez le module dont vous ne voulez pas.

/var/run/libvirt/libvirt-sock: No such file or directory depuis virsh. Le daemon est arrêté : sudo systemctl enable --now libvirtd.

Proxmox : KVM virtualisation configured, but not available. Un guest utilise l’accélération KVM sur un host qui ne peut pas la fournir. Corrigez la virtualisation imbriquée, ou désactivez cette option et acceptez l’émulation.

Émulateur Android : x86_64 emulation currently requires hardware acceleration! /dev/kvm à nouveau, généralement à cause du groupe.

Aucune erreur, mais tout est extrêmement lent. Sans flag d’accélération, QEMU bascule sur TCG, son émulateur logiciel. Le fonctionnement est correct, mais lent : un boot mesuré en secondes prend alors plusieurs minutes. Passez explicitement -accel kvm afin que QEMU s’arrête avec une erreur au lieu de lancer discrètement l’émulation.

Un guest disparaît en cours d’exécution. Consultez dmesg pour rechercher Out of memory: Killed process ... qemu-system-x86_64. Un guest L2 est un processus sur L1, et l’OOM killer le traite comme n’importe quel autre processus. La RAM de L2 est prélevée sur l’allocation fixe de L1 ; elle ne peut pas emprunter de mémoire à l’host.

Exploitation : sauvegardes, mises à jour, limites

Sauvegardes. Copier le fichier qcow2 d'une machine virtuelle en cours d'exécution risque de produire une image incohérente, car l'invité continue d'écrire pendant votre lecture. Soit vous exécutez virsh shutdown guest1, vous attendez que virsh domstate guest1 indique shut off (la commande d'arrêt peut rendre la main alors que l'invité est encore en cours d'extinction), puis vous copiez ; soit vous effectuez un snapshot externe (virsh snapshot-create-as guest1 snap1 --disk-only --atomic) afin que les écritures soient redirigées vers une surcouche pendant que vous copiez la base devenue statique, puis vous fusionnez le tout avec virsh blockcommit guest1 vda --active --pivot. Exportez les copies hors du VPS ; un snapshot stocké sur le même disque ne protège contre rien du tout.

Mises à jour. apt full-upgrade installe les nouveaux modules kvm_intel/kvm_amd, mais le noyau en cours d'exécution conserve les anciens jusqu'au redémarrage. Gardez le noyau précédent installé et relancez kvm-ok après chaque changement de noyau : un hôte qui redémarre sans vmx reste ainsi à une entrée de boot près d'un retour à la normale.

Limites de montée en charge. Une seule adresse IP publique signifie que chaque service L2 accède au monde via un proxy ou une règle DNAT sur L1. La migration à chaud n'est pas possible. En cas de contention CPU, le chemin de sortie imbriqué est le premier à en subir les conséquences. Un hyperviseur avec plusieurs invités est une machine dont la RAM est déjà allouée ; les machines virtuelles imbriquées ne peuvent pas utiliser le surabonnement (overcommit) pour pallier une allocation fixe. Lorsqu'un environnement de test dépasse ces capacités, la solution n'est pas d'empiler davantage de couches d'imbrication ; il faut passer sur une machine dédiée où vous êtes L0 et où aucune de ces contraintes ne s'applique.

FAQ

Ai-je besoin de la virtualisation imbriquée pour exécuter Docker sur un VPS ?

Non. Les conteneurs partagent le kernel de votre VPS et n’ouvrent jamais /dev/kvm. Une instance standard, sans indicateur vmx ni svm, exécute correctement Docker et Docker Compose. La virtualisation imbriquée est utile uniquement lorsque vous voulez exécuter un second kernel : un environnement Proxmox, une machine virtuelle Windows, des microVM Firecracker, un émulateur Android ou des runners CI qui démarrent des images de machines virtuelles.

Comment vérifier si mon VPS prend en charge la virtualisation imbriquée ?

Exécutez grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u, puis kvm-ok depuis le paquet cpu-checker. Une instance compatible affiche vmx (Intel) ou svm (AMD). kvm-ok indique KVM acceleration can be used, et /dev/kvm existe avec le groupe kvm et le mode 660. Ignorez /sys/module/kvm_intel/parameters/nested pour cette vérification : ce fichier décrit votre propre module KVM, pas ce que l’hyperviseur du fournisseur vous a exposé.

Pourquoi la plupart des fournisseurs de VPS désactivent-ils la virtualisation imbriquée ?

Exposer vmx revient à fournir à la machine virtuelle un modèle de CPU qui porte cet indicateur. Une machine virtuelle qui dépend de ces fonctionnalités CPU ne peut pas être migrée à chaud vers une machine dont le CPU ne les prend pas en charge. Un fournisseur qui évacue des nœuds en déplaçant les clients doit donc renoncer à cette possibilité. Les chemins de code VMX/SVM imbriqués ont également un long historique de CVE. Certains hébergeurs l’activent encore par VM sur demande. D’autres documentent la virtualisation imbriquée comme une fonctionnalité de l’offre.

Ma machine virtuelle imbriquée n’a pas de réseau sur le bridge public. Quel est le problème ?

Le switch du fournisseur abandonne les trames provenant d’une adresse MAC qu’il ne vous a jamais attribuée. Une machine virtuelle L2 reliée à la carte réseau publique envoie donc des requêtes ARP sans recevoir de réponse. Arrêtez de diagnostiquer br0. Utilisez le réseau NAT default de libvirt (virbr0, 192.168.122.0/24), attribuez un bail statique à la machine virtuelle, puis publiez les services accessibles depuis Internet via un reverse proxy ou une règle DNAT sur le VPS lui-même.

Une machine virtuelle imbriquée est-elle beaucoup plus lente ?

Le coût se concentre sur les sorties de VM et la traduction d’adresses. Lorsque EPT/NPT est actif, les instructions et les accès au TLB de la couche L2 s’exécutent à la vitesse du matériel. En revanche, un défaut de TLB parcourt des tables de pages supplémentaires. Les E/S, les interruptions de timer, les accès MMIO et les IPI sont traités par L0 et peuvent être renvoyés via L1. Les charges limitées par le CPU, avec un petit jeu de travail, restent proches des performances natives. Les jeux de travail volumineux en mémoire et les charges intensives en appels système, en paquets réseau ou en accès disque subissent le coût de chaque couche. Utilisez partout des périphériques virtio et cache=none sur les disques invités, puis mesurez vos propres charges.