- Sandbox monoprocessus basé sur KVM
- Permet d’exécuter dans un sandbox des programmes Linux classiques ou des programmes utilisant une API spécifique
- Fournit des performances natives grâce à la virtualisation matérielle
- N’utilise qu’une partie de l’API KVM → base de code réduite et efficace
Conception de TinyKVM
- Prise en charge de l’exécution de programmes Linux ELF statiques
- La prise en charge des exécutables dynamiques sera ajoutée plus tard
- Peut aussi être étendu via une API afin de fournir un accès à un serveur HTTP externe ou à un cache
- Fonctionne actuellement sur AMD64 (x86_64), avec un portage vers AArch64 (ARM 64 bits) prévu
- Prise en charge des hugepages
- Il est possible de créer des hugepages pour les pages invitées
- L’hôte peut aussi utiliser des hugepages → amélioration des performances
- Exemple : avec des pages de 2 Mo, une hausse de 5 % des performances de compilation LLVM a été constatée
- Appels de fonction rapides
- Lors d’un appel de fonction depuis l’invité, le surcoût est de 2 μs
- Sans timer pendant l’exécution, le surcoût descend à 1,2 μs
- Prise en charge du débogage à distance
- Débogage à distance possible avec GDB
- Reprise normale du programme possible après le débogage
- Prise en charge du Copy-on-Write
- Fonction de fork intégrée → permet de réduire au minimum la duplication mémoire
- Exemple : lors de la duplication d’un modèle de 6 Go, seulement 260 Mo de mémoire sont nécessaires par instance
- Initialisation rapide de l’état
- L’état de l’invité peut être réinitialisé rapidement → sécurité renforcée
- Une réinitialisation à chaque requête réduit le risque d’exposition d’état
- Base de code simplifiée
- Environ 42 kLOC de l’API KVM sont utilisés
- La base de code propre à TinyKVM fait environ 9 kLOC → bien plus petite que les solutions concurrentes
- Exemple : Wasmtime 350 kLOC, FireCracker 165 kLOC
- Création statique des tables de pages
- Impossible de modifier les tables de pages à l’exécution → sécurité renforcée
- Vérification de l’intégrité des tables de pages effectuée
- Contexte de processus isolé
- L’invité KVM utilise un PCID/ASID distinct → plus résistant aux attaques par exécution spéculative comme Spectre
- Noyau renforcé pour la sécurité
- SMEP et SMAP activés
- Gestion possible des exceptions CPU en mode utilisateur
Gestion des appels système
- Connexion API avec l’hôte
- Les appels système sont effectués via les instructions SYSCALL/SYSRET ou OUT
- L’exécution d’un appel système provoque une sortie de VM → environ 1 μs
- Il est recommandé de limiter les petits appels et de concevoir une API avec de grosses unités d’entrée/sortie
Benchmarks
- Surcoût des appels VM
- Mesure de la tail latency lors de la réinitialisation de la VM
- Le surcoût est faible pour un simple appel sans réinitialisation
- Performances mémoire
- Les performances mémoire sont normales
- Exemple : dans un benchmark HTTP, 1 500 encodages AVIF par seconde sont possibles
- Performances de conversion JPEG → AVIF
- Environ 1 582 images peuvent être converties par seconde
- Une conversion sans perte est possible en utilisant le chemin de conversion YUV
Pourquoi le sandbox est rapide
- Aucun I/O ni pilote utilisé
- Pas d’I/O, de pilotes ni de périphériques virtuels → évite les pertes de performances
- Utilise uniquement les ressources CPU → vitesse proche du natif
- Optimisation via hugepages
- L’usage de hugepages réduit les page walks → amélioration des performances
- Atteint 99,7 % des performances natives sur de grosses charges LLM
- Appels VM rapides
- Surcoût minimal lors des appels de fonction depuis l’invité
- Traitement des données à vitesse CPU native
Limites
- Impossible de réduire le nombre de vCPU
- L’API KVM ne permet pas de réduire le nombre de vCPU
- Le multiprocessus peut être géré en exécutant plusieurs VM en parallèle
- Baisse de performances lors de la réinitialisation
- Une baisse de performances peut survenir lors de la réinitialisation de l’état de la VM
- Mais cela peut être résolu via le partage et la duplication d’état
Travaux à venir
- Ajout de la prise en charge d’Intel TDX et d’AMD SEV
- Portage vers AArch64
- Ajout d’une fonction de verrouillage mémoire (
KVM_MEM_READONLY) → sécurité renforcée
- Amélioration d’une API plus conviviale
- Ajout de la prise en charge du chargement de liens dynamiques → meilleure intégration avec Varnish
Conclusion
- TinyKVM est l’une des solutions de sandbox les plus petites et les plus rapides
- Combine renforcement de la sécurité et optimisation des performances
- Sa base de code réduite facilite la maintenance
- Disponible comme bibliothèque open source → si le sujet vous intéresse, vous pouvez consulter le dépôt de code
Dépôt TinyKVM
2 commentaires
C'est original.
Commentaires sur Hacker News
J’aime vraiment beaucoup ça. J’espère qu’ils ne s’arrêteront pas et continueront ce qu’ils font actuellement
C’est similaire à Firecracker, mais beaucoup plus rapide
Publication originale : lien
Vraiment intéressant. Les performances de restauration de snapshot en 2.5us sont comparables à Wasmtime, avec le gros avantage de pouvoir exécuter du code natif. En revanche, c’est bien plus lent tout en conservant une interopérabilité à l’échelle de la microseconde
En gros, ce n’est pas la même chose que libkrun ? lien
Ce n’est pas exactement le cas d’usage visé, mais est-ce que quelqu’un a déjà essayé d’exécuter un serveur X (ou Wayland) ?
C’est intéressant, mais j’ai du mal à comprendre la vue d’ensemble. Est-ce qu’il s’agit d’exécuter un processus utilisateur dans une VM sans noyau ? Est-ce que tous les appels système provoquent la sortie de la VM pour être proxifiés vers l’hôte ? Ou bien n’y a-t-il tout simplement pas d’appels système ?
Si cela correspond à votre cas d’usage, c’est vraiment génial
Vraiment cool
L’article ne dit pas que cela tourne au-dessus de Varnish, et en réalité l’auteur précise que ce n’est pas conçu pour exécuter Varnish