SysadminNews

Multikernel fait tourner plusieurs noyaux Linux nus

Sur cette page
  1. Ce que cela fait
  2. Les chiffres, et ce qu'ils mesurent
  3. Là où cela devient réellement intéressant
  4. Ce que ce n'est pas encore
  5. Sources et pour aller plus loin

Multikernel Technologies publie mklinux v7.0-mk2, première version publique d'un arbre Linux capable de faire tourner plusieurs noyaux indépendants sur une seule machine physique sans hyperviseur. Un noyau hôte possède un ensemble de processeurs, de mémoire et de périphériques PCI, le découpe en tranches, et démarre un noyau distinct dans chaque tranche au moyen de kexec. Chaque noyau engendré s'exécute ensuite nativement sur ses propres cœurs et sa propre mémoire physique. Rien n'est émulé et rien n'est intercepté, ce qui explique les mesures : un changement de contexte entre deux processus tombe à 1,37 microseconde contre 3,42 sous KVM sur le même matériel.

The short answer

Multikernel Technologies publie mklinux v7.0-mk2, un arbre fondé sur Linux 7.0 qui démarre plusieurs noyaux indépendants sur une seule machine physique sans hyperviseur. Un noyau hôte possède un ensemble de processeurs, de mémoire et de périphériques PCI, le partitionne, et démarre un noyau dans chaque partition via kexec_file_load, le suivi passant par /sys/fs/multikernel/. Chaque noyau engendré tourne nativement sur ses cœurs et sa mémoire physique. Sur un Intel Xeon Gold 5418Y, lmbench mesure un changement de contexte à 1,37 microseconde contre 3,42 sous KVM, une latence de tube à 3,24 contre 7,06 et une latence de socket Unix à 4,81 contre 7,48, pour environ 19 watts supplémentaires.

v7.0-mk2premier arbre multikernel Linux public
1,37 uschangement de contexte, contre 3,42 sous KVM
x86_64seule architecture prise en charge au lancement
Carte réponse : multikernel Linux v7.0-mk2 démarre plusieurs noyaux indépendants sur une machine sans hyperviseur, chacun disposant de processeurs, de mémoire et de périphériques PCI dédiés, avec un changement de contexte à 1,37 microseconde contre 3,42 sous KVM.
Ni hyperviseur ni conteneur. Un second noyau, démarré sur de vrais cœurs. PNG

Il existe d'ordinaire deux réponses pour faire tourner des charges isolées sur une même machine. Les machines virtuelles offrent des noyaux séparés au prix d'une couche d'arbitrage. Les conteneurs suppriment cette couche au prix d'un noyau partagé. Multikernel Linux propose une troisième réponse, assez inhabituelle pour mériter d'être comprise : des noyaux séparés, aucune couche d'arbitrage, et un matériel réparti entre eux dès le démarrage.

Ce que cela fait

Un noyau hôte possède un ensemble de processeurs, de mémoire et de périphériques PCI. Vous y découpez une tranche et vous y démarrez un second noyau au moyen de kexec_file_load(). Le noyau engendré se lève sur ses propres cœurs, dans sa propre mémoire physique, et pilote les périphériques qui lui sont assignés. Les instances sont suivies par des recouvrements d'arbre de périphériques sous /sys/fs/multikernel/.

La formule employée par les développeurs est que rien n'est émulé et rien n'est intercepté, et que seul est partagé ce que vous choisissez de partager. C'est une description précise plutôt qu'un argument commercial. Il n'y a pas de chemin de sortie de machine virtuelle car il n'y a rien vers quoi sortir. Il n'y a pas de tables de pages de second niveau car le noyau utilise directement de la mémoire physique réelle. Il n'y a pas d'émulation de périphériques car les périphériques sont simplement remis.

Le premier arbre public, mklinux v7.0-mk2, repose sur Linux 7.0 et les sources se trouvent sur github.com/multikernel/linux. Cong Wang l'a annoncé sur la liste de diffusion du noyau, et la presse spécialisée l'a repris entre le 25 août et la fin du mois.

Les chiffres, et ce qu'ils mesurent

La version se compare à KVM avec lmbench sur un Intel Xeon Gold 5418Y.

Comparaison des latences lmbench sur un Intel Xeon Gold 5418Y : changement de contexte entre deux processus à 1,37 microseconde en multikernel contre 3,42 sous KVM, latence de tube 3,24 contre 7,06, latence de socket Unix 4,81 contre 7,48. Plus bas est meilleur.
Plus bas est meilleur. Ce sont les chemins où l'arbitrage de l'hyperviseur se voit le plus. PNG

Un changement de contexte entre deux processus mesure 1,37 microseconde, contre 3,42 microsecondes sous KVM. La latence de tube mesure 3,24 microsecondes contre 7,06. La latence de socket Unix mesure 4,81 microsecondes contre 7,48. Soit environ un facteur deux sur le changement de contexte et un peu plus sur les tubes.

Lisez ces résultats comme des microbancs, car c'en sont. lmbench isole délibérément les opérations où un hyperviseur doit intervenir, ce qui flatte une approche dont l'argument entier consiste à supprimer cette intervention. Une base de données ou un étage web passe l'essentiel de son temps dans du code qu'un hyperviseur ne touche jamais, et le gain y sera bien plus faible. Ce que ces chiffres établissent honnêtement, c'est l'ampleur du coût d'arbitrage lui-même, ce qui est utile précisément parce que la plupart d'entre nous en portons une hypothèse plutôt qu'une mesure.

Il existe un coût de l'autre côté du bilan, et le projet le publie : environ 19 watts supplémentaires, l'hôte maintenant ses processeurs pleinement occupés au lieu de les laisser au repos. Sur une machine isolée, c'est du bruit. À l'échelle d'une baie, c'est une ligne de facture, et c'est le genre de détail assez souvent omis dans ce type d'annonce pour que son inclusion mérite d'être signalée.

Là où cela devient réellement intéressant

Les usages décrits par les développeurs sont plus précis qu'une consolidation généraliste. Donner à un agent d'apprentissage automatique un accès direct à une carte graphique sans la faire transiter par un hyperviseur en est un. Remplacer un noyau sans arrêter la machine en est un autre, puisqu'un nouveau noyau peut être démarré dans une tranche et la charge déplacée. Partitionner les serveurs à très grand nombre de cœurs est le troisième, et c'est celui qui comptera le plus avec le temps : à mesure que le nombre de cœurs grimpe, traiter un socket comme un ensemble uniforme devient un choix par défaut moins évident qu'auparavant. Les conceptions hétérogènes, où les cœurs diffèrent réellement, vont dans le même sens.

L'argument d'isolation est d'ailleurs un argument de fiabilité et non de densité. Les conteneurs partagent un noyau, ce qui signifie qu'une contention de verrou ou une panique est partagée par tout ce qui tourne sur la machine. Des noyaux séparés n'ont pas cette propriété. C'est un avantage réel pour les charges où la panne que vous cherchez à éviter est justement celle d'un locataire fautif qui emporte la machine entière, et un mauvais compromis quand vous vouliez empiler quatre cents petits services sur un seul hôte.

Ce que ce n'est pas encore

Il s'agit d'une première version publique d'une bifurcation hors arbre principal. Elle ne gère que x86_64, même si les interfaces spécifiques à l'architecture ont été séparées pour rendre des portages ARM et RISC-V structurellement possibles plus tard. Son chemin vers le noyau principal est incertain et non planifié, et l'évaluation réaliste veut qu'une telle intégration reste lointaine.

Rien de tout cela ne la rend inintéressante. La direction dominante de la dernière décennie a consisté à ajouter des couches : hyperviseurs, puis conteneurs, puis orchestrateurs par-dessus les deux. Ceci va dans l'autre sens, et le fait avec un mécanisme qui existe déjà dans le noyau plutôt qu'avec un nouveau. Quiconque optimise la latence devrait lire ces mesures, et quiconque monte un laboratoire ce trimestre dispose d'une expérience peu coûteuse. Si vous pesez les solutions à l'étage au-dessus, notre article sur la migration quasi à chaud dans Incus 7.4 décrit ce que la pile classique fait du même problème, et la fenêtre de fusion de Linux 7.3-rc1 montre ce qui arrive en amont pendant que ceci reste à l'extérieur.

Sources et pour aller plus loin

Questions fréquentes

En quoi cela diffère-t-il d'une machine virtuelle ?

Une machine virtuelle exécute un noyau invité sur du matériel émulé ou paravirtualisé, l'hyperviseur arbitrant les accès. Cet arbitrage vous coûte le chemin de sortie de machine virtuelle, les tables de pages de second niveau et l'émulation de périphériques, et ce sont précisément ces coûts qui apparaissent sur les charges sensibles à la latence. Une instance multikernel n'en a aucun. Le noyau engendré démarre sur des cœurs réels et de la mémoire physique réelle via kexec_file_load, et pilote de vrais périphériques PCI qui lui sont assignés. Il n'y a pas d'interception vers une couche inférieure, car il n'y a pas de couche inférieure. La contrepartie est que vous obtenez du partitionnement, pas la migration, les instantanés et le surengagement qui justifient l'existence d'un hyperviseur.

En quoi cela diffère-t-il des conteneurs ?

Les conteneurs partagent un noyau. C'est leur avantage, car cela les rend peu coûteux à démarrer et denses à empiler, et c'est aussi leur limite : une contention de verrou, une pathologie d'ordonnanceur ou une panique du noyau sont partagées par tout ce qui tourne sur la machine. Les instances multikernel ne partagent aucun noyau. Chacune a son ordonnanceur, sa gestion mémoire et ses pilotes de périphériques, si bien qu'un défaut dans l'une ne se propage pas aux autres. Vous payez cette isolation en processeurs et en mémoire dédiés, ce qui donne un profil de densité très différent de celui des conteneurs.

Que montrent réellement les mesures publiées ?

La version se compare à KVM avec lmbench sur un Intel Xeon Gold 5418Y. Un changement de contexte entre deux processus mesure 1,37 microseconde contre 3,42 sous KVM. La latence de tube mesure 3,24 microsecondes contre 7,06. La latence de socket Unix mesure 4,81 microsecondes contre 7,48. Ce sont des microbancs portant sur les chemins où l'arbitrage de l'hyperviseur est le plus visible : ils représentent donc un cas favorable à l'approche plutôt qu'un résultat applicatif. Un coût énergétique est aussi mesuré, environ 19 watts supplémentaires, car l'hôte maintient ses processeurs pleinement occupés.

Peut-on l'utiliser en production ?

Non, et le projet ne le prétend pas. Il s'agit de la première version publique d'une bifurcation de noyau hors arbre principal, testée uniquement sur x86_64, dont l'intégration en amont est incertaine et non planifiée. Voyez-la comme quelque chose à monter en laboratoire et à mesurer sur votre propre charge, pas comme un choix de plateforme. La question intéressante qu'elle permet de trancher à peu de frais est de savoir si le surcoût d'hyperviseur que vous supposez payer correspond à celui que vous payez réellement, et cela vaut un après-midi même si l'arbre ne fusionne jamais.

Quel matériel et quels usages sont visés ?

x86_64 est la seule architecture officiellement prise en charge au lancement, même si les développeurs ont séparé les interfaces spécifiques à l'architecture pour permettre d'autres portages. Les usages décrits sont la consolidation de charges sur matériel nu sans taxe d'hyperviseur, l'accès direct d'un agent d'apprentissage automatique à une carte graphique, le remplacement d'un noyau sans arrêter la machine, et le partitionnement des serveurs à très grand nombre de cœurs qui deviennent ordinaires. Les conceptions hétérogènes sont aussi citées, où des cœurs différents pourraient raisonnablement exécuter des noyaux différents au lieu de feindre un ensemble uniforme.