Aller au contenu

Blog ·

Choisir une plage de VMID pour un hébergeur

Un VMID est une identité, pas un compteur. Ce que décide la plage choisie : ce que la plateforme crée, ce qu’elle lit, et ce qui arrive quand elle est pleine.

Par Provibr

Toute installation Proxmox vous fait commencer à 100 et compter vers le haut. Cela fonctionne très bien jusqu’au jour où la machine cesse d’être la vôtre seule : jusqu’à ce qu’un panneau de gestion y crée des invités, qu’un collègue en crée à la main, qu’une bibliothèque de modèles apparaisse, et qu’une tâche de sauvegarde restaure quelque chose à trois heures du matin.

À ce moment, le VMID cesse d’être un compteur et devient une identité, et la plage que vous confiez à votre automatisation cesse d’être une commodité pour devenir une frontière. Elle mérite un choix délibéré, car deux des trois choses qu’une plage décide restent invisibles jusqu’à ce qu’elles tournent mal.

Ce que Proxmox autorise réellement

L’espace complet est plus large que la plupart des gens ne le supposent :

Valeur
VMID le plus bas accepté par Proxmox100
VMID le plus haut accepté par Proxmox999999999
Usage manuel habituelde 100 à quelques centaines

Neuf chiffres. Ce n’est pas une invitation à tous les utiliser, mais cela veut dire que l’inquiétude habituelle, « vais-je en manquer », n’est pas la bonne. Vous épuiserez une plage mal choisie bien avant d’épuiser les numéros.

Ces deux bornes sont les seules que l’hyperviseur impose. Tout le reste, c’est-à-dire la partie qui compte, relève d’une décision qui vous appartient.

Une plage est une frontière de permission avant d’être un allocateur

Voici la partie facile à manquer. Quand on dit à une plateforme « vous allouez de 5000 à 8999 », on lui dit deux choses à la fois :

  1. Ce qu’elle peut créer. Les nouveaux invités reçoivent un numéro pris dans cette fenêtre et nulle part ailleurs.
  2. Ce qui ne lui appartient pas. Tout ce qui se trouve hors de cette fenêtre a été fait par quelqu’un d’autre, et la plateforme n’a rien à y faire.

La seconde mérite d’être écrite au mur. Quand nous avons construit l’intégration Proxmox, la plage de vmid des réglages d’intégration est décrite dans le code exactement ainsi : la plateforme n’alloue qu’à l’intérieur de [vmidRangeStart, vmidRangeEnd], de sorte qu’une intégration ne peut, par construction, atteindre une VM en dehors. Qui garde ses VM de production hors de la plage les garde hors de portée.

Ce cadrage change la façon de choisir les numéros. Vous ne choisissez pas l’endroit où votre automatisation commence à compter. Vous tracez une ligne autour des machines que vous acceptez de laisser supprimer par un programme.

La lecture est une question à part, et elle mord plus tard

La création est la moitié évidente. La lecture est celle qui nous a surpris.

Notre agent interroge le cluster une fois par tour avec un seul GET /cluster/resources?type=vm, qui ne touche aucun invité. Mais pour chaque invité en cours d’exécution dans cette réponse, il effectuait ensuite deux appels supplémentaires vers l’agent invité QEMU, network-get-interfaces et get-fsinfo, afin de connaître les adresses et l’occupation disque. Cette liste sortait directement de la requête au cluster, sans aucun filtre.

Sur un hyperviseur de test qui fait aussi tourner des charges de production, cette liste contenait les machines de production. Ces lectures sont inoffensives au sens où rien n’est écrit. Elles ne le sont pas au sens qui compte, car « lecture seule » ne répond pas à la question pourquoi votre agent parle-t-il à l’agent invité d’une machine qui ne vous appartient pas.

La correction, c’est que la même plage borne désormais les lectures. Si vous construisez cela vous-même, la leçon se généralise : une frontière qui ne couvre que l’écriture est une demi-frontière, et la moitié lecture est celle dont personne ne remarque l’absence.

Où doit vivre la plage

Nous avons dû trancher une fois, et le raisonnement mérite d’être posé, car la réponse évidente est fausse.

La réponse évidente consiste à placer la plage à côté des identifiants, dans le paquet que la plateforme pousse vers l’agent au moment où l’intégration est créée. C’est un seul message, il arrive avec tout le reste, terminé.

Cela échoue au redémarrage. Les identifiants sont poussés une seule fois ; après un redémarrage, l’agent reconstruit ses intégrations depuis son coffre local, sans aucune poussée. Une frontière livrée par ce chemin disparaît discrètement au premier redémarrage du processus, et une frontière qui cesse silencieusement de s’appliquer est pire qu’aucune frontière, car personne ne va la chercher.

La plage voyage donc dans son propre message, envoyé à chaque poignée de main de session, et portant l’état complet. Deux chemins de livraison, une seule source de vérité. Il existe aussi une variable d’environnement sur l’hôte comme repli, et l’ordre entre les deux est délibéré :

SourceQuand elle l’emporte
Le réglage de la plateformeChaque fois qu’elle en a envoyé un
Variable d’environnement de l’hôteUniquement quand la plateforme n’a rien dit
Aucune limiteQuand ni la plateforme ni l’hôte n’ont parlé

L’ordre tentant est l’inverse, au motif qu’une ceinture attachée sur l’hôte serait plus solide. Il produit un état que personne ne voit : un administrateur qui a jadis posé une variable conserve en silence une frontière qui ne correspond plus à ce qu’affiche le panneau, et un client qui élargit la plage dans l’interface ne comprend pas pourquoi rien n’a changé.

Un petit détail au mode de défaillance considérable : une valeur illisible est traitée comme « personne », et non comme « tout le monde ». Celui qui demande une frontière et fait une faute de frappe n’obtient plus aucune lecture, plus une ligne de journal qui dit pourquoi. Le coût est cosmétique : une adresse et un chiffre d’occupation disque manquants dans le panneau. L’autre solution, se rabattre sur « tout est autorisé », est l’échec classique des listes d’autorisation : elle échoue ouverte, en silence, précisément dans le cas où quelqu’un essayait d’être prudent.

Les modèles vont hors de la plage. Toujours.

Ceci est une règle et non une préférence, et c’est l’erreur qui se dévore elle-même.

Un allocateur distribue des numéros pris dans la plage. Placez un modèle dans la plage et un jour l’allocateur l’atteint, une nouvelle commande est créée sur ce numéro, et le modèle devient la VM d’un client. La commande suivante clone alors une machine qui n’est plus un modèle. Le validateur refuse donc un VMID de modèle Proxmox qui tombe à l’intérieur de la plage de l’intégration, et l’allocateur considère en outre chaque modèle lié comme pris, au cas où quelqu’un aurait élargi la plage après en avoir lié un.

Hors de la plage, un modèle peut vivre n’importe où. La plage borne ce que la plateforme crée, pas l’endroit où le matériau source a le droit de se trouver.

Ne jamais réutiliser un numéro, même quand la machine a disparu

L’allocateur distribue le plus petit VMID libre de la plage, et « libre » est plus strict qu’on ne l’imagine : tout VMID que l’intégration a un jour distribué compte comme pris, y compris ceux qui appartenaient à des serveurs supprimés.

Cela paraît du gaspillage pendant environ cinq secondes, jusqu’à ce que l’on considère ce qu’impliquerait la réutilisation. Un événement d’état tardif de l’ancienne VM atterrit sur la nouvelle ligne. L’historique d’audit de deux serveurs différents se confond en une seule chronologie. Quelqu’un restaure la sauvegarde d’hier sur un numéro qui appartient désormais à un autre client.

Fait intéressant, nous faisons le choix inverse pour les adresses IP dans le même produit, et pour une bonne raison : une adresse est une adresse, et ne jamais en réutiliser une épuiserait définitivement un /24 après 254 machines. Un VMID est le nom de l’histoire d’une machine. Les plages ne coûtent rien ; la confusion, si.

Il existe une troisième catégorie de « pris » qui n’apparaît qu’à partir du moment où plusieurs choses créent des machines. Une restauration encore en cours a réclamé son VMID cible mais n’a pas encore de ligne de serveur : une seconde restauration lancée dans la même minute recevrait sinon le même numéro « libre ». Tout ce qui réserve un VMID avant que la ligne existe doit être compté.

Ce qui arrive quand la plage est pleine

Deux réponses, et les deux doivent exister.

La réponse aimable est arithmétique : l’allocateur parcourt la plage, ne trouve rien de libre, et renvoie un échec précis qui nomme le début et la fin de la plage. Le client lit « cette plage est pleine, de 5000 à 8999 » plutôt qu’une erreur d’hyperviseur quatre couches plus bas.

La réponse réelle est la base de données. La contrainte d’unicité sur (intégration, identifiant externe) est l’arbitre : deux commandes passées au même instant peuvent voir le même plus petit numéro libre, et exactement une insertion survit. Le perdant réessaie, jusqu’à un petit nombre fixe de tentatives. Vérifier d’abord et insérer ensuite ouvre précisément la course que la contrainte referme : la contrainte est le mécanisme, et le message aimable une courtoisie posée par-dessus.

Notez ce que nous n’utilisons pas : Proxmox possède un point de terminaison qui donne le prochain identifiant libre, et c’est le mauvais outil ici. Il répond à « quel numéro est libre sur ce cluster », ce qui est une autre question que « quel numéro est libre et à l’intérieur de la fenêtre qui m’appartient ». Demandez à l’hyperviseur et il finira par vous tendre un numéro hors de votre propre frontière.

Donc, en pratique

  • Commencez haut et laissez les petits numéros tranquilles. De 100 à quelques centaines, c’est là que vivent les machines faites à la main sur toute installation Proxmox, y compris la vôtre dans trois ans, quand vous aurez oublié cette décision.
  • Choisissez une plage à la forme évidente. De 5000 à 8999 se lit comme « à nous » d’un coup d’œil dans l’interface web. Une plage de 4000 numéros, c’est quatre mille machines sur une seule intégration.
  • Placez les modèles en dehors, dans leur propre bloc, loin de là.
  • Écrivez la plage là où la plateforme peut la voir, et pas seulement dans un fichier de configuration de l’hôte, et assurez-vous qu’elle est renvoyée plutôt qu’envoyée une seule fois.
  • Vérifiez que les lectures sont bornées elles aussi, pas seulement les créations et les suppressions.

Le numéro lui-même n’a guère d’importance. Ce qui compte, c’est que la frontière soit une seule chose, visible à un seul endroit, appliquée aux lectures comme aux écritures, et qu’elle échoue fermée quand elle ne peut pas être lue.

Ce texte vient de la construction de l’intégration Proxmox pour Provibr, où l’agent tourne à l’intérieur du réseau du client et ne se connecte que vers l’extérieur.

Commencez avec un hôte et un agent

Créez un compte, installez l’agent avec une seule commande et connectez votre premier hôte Proxmox. La période d’essai dure 14 jours et ne demande aucune coordonnée de paiement.