Chaque jour, AWS Lambda exécute des billions d'innombrables milliards d'appels de fonctions. AWS Fargate orchestre des millions de conteneurs. Chacun d'eux est une machine virtuelle complète, avec son propre noyau, démarrée en une fraction de seconde.
Comment ? Environ 50 000 lignes de Rust appelées Firecracker, qui existent parce que l'industrie a enfin admis qu'un conteneur Linux contrôlant l'utilisation des ressources n'a jamais été conçu pour être une frontière de sécurité.
Le problème de l'isolation
Chaque conteneur Docker sur votre ordinateur portable est un assemblage de trois fonctionnalités du noyau Linux dans un manteau :
- Les espaces de noms sont des bandeaux sur les yeux. Un processus à l'intérieur obtient une vue privée du système : sa propre liste de PID, pile réseau, table de montage, nom d'hôte et identifiants utilisateur. Le PID 1 à l'intérieur du conteneur est un PID aléatoire sur l'hôte ; le conteneur ne peut même pas voir les autres processus.
- Les cgroups sont des budgets. Les groupes de contrôle sont la couche de comptabilité et de limitation de débit du noyau. Ils plafonnent la quantité de CPU, mémoire, E/S disque et bande passante réseau qu'une arborescence de processus est autorisée à consommer.
- seccomp + les capacités sont des listes blanches. Les capacités découpent les pouvoirs de root en environ en environ 40 privilèges séparés (lier des ports bas, charger des modules noyau, monter des systèmes de fichiers, etc.) afin que vous puissiez accorder uniquement ceux dont vous avez besoin. seccomp est un filtre par processus qui décide quels appels système (la seule API de l'espace utilisateur vers le noyau) le processus est même autorisé à effectuer.
Vous pouvez le prouver vous-même sans Docker installé :
Tout le reste que Docker fait (couches d'image, registres, DNS) est de l'orchestration par-dessus.
Toute cette protection passe par un seul noyau Linux, environ 30 millions de lignes de code exposant 400+ appels système. Chaque conteneur sur l'hôte appelle ce même noyau. Un bogue dans l'un de l'un de ces appels système et c'est la fin de la partie pour chaque locataire sur cette machine.
Les machines virtuelles complètes résolvent l'isolation par la force brute : chaque VM obtient son propre noyau.
Les processeurs modernes ont un « mode invité » qui exécute les instructions de l'invité sur le silicium réel. L'hôte n'est sollicité que lorsque l'invité fait quelque chose de privilégié (touche du matériel réel, génère une erreur, est interrompu). Un hyperviseur est la couche mince qui arbitre ces moments.
Linux fournit son hyperviseur sous forme de module noyau appelé KVM, exposé via /dev/kvm. Il s'appuie sur les extensions matérielles de virtualisation (vmx sur Intel, svm sur AMD) :
Le problème avec les machines virtuelles complètes est qu'elles sont lentes et lourdes. Une machine virtuelle QEMU classique émule un PC imaginaire complet (BIOS, bus PCI, contrôleur IDE, carte VGA, clavier PS/2) parce que c'est ce à quoi un système d'exploitation de 1998 s'attendait pour démarrer. L'image fait des centaines de mégaoctets. Le démarrage prend des secondes. L'empreinte mémoire est de centaines de Mio avant même que votre charge de travail ne commence. Pour une requête web qui vit 40 ms, vous passeriez 40× ce temps à démarrer la machine.
Vous êtes donc coincé entre :
- Conteneurs : démarrage en 50 ms, 5 Mio de surcharge, surface d'attaque du noyau partagé.
- Machines virtuelles : démarrage en 5+ secondes, 300+ Mio de surcharge, isolées par le matériel.
Quiconque exécute du code multi-locataire non fiable (AWS, et pratiquement tous les fournisseurs de bacs à sable IA existants) a besoin des deux côtés de ce compromis à la fois.
Entrez les microVM
Un VMM (Virtual Machine Monitor) est le processus en espace utilisateur qui pilote l'hyperviseur : il configure la mémoire de l'invité, branche des périphériques virtuels et dit à KVM de commencer à exécuter le code invité.
Une microVM est un VMM avec le PC de 1998 supprimé : pas de BIOS, pas de bus PCI, pas de VGA, pas d'USB, pas d'ACPI (aucun du matériel matériel hérité qu'un bureau réel utilise pour démarrer, et rien de tout cela n'est pertinent pour un appel de fonction de 40 ms). Ce qui reste : KVM, une console série, et une poignée de périphériques virtio (réseau, bloc, vsock).
virtio est l'interface standard « Je sais que je tourne dans une VM ». L'invité coopère avec l'hyperviseur via des cartes de NIC et disques virtuels légers (virtio-net, virtio-block) au lieu de faire semblant de piloter une vraie carte Intel e1000 ou un contrôleur IDE. Cette coopération, plus tout le matériel hérité manquant ci-dessus, est la principale raison pour laquelle les microVM démarrent rapidement.
Le résultat :
- ~125 ms de démarrage du lancement du VMM à l'espace utilisateur invité exécutant init.
- <5 Mio de surcharge mémoire VMM par VM (la mémoire de comptabilité que l'hôte paie par VM, avant que la charge de travail invitée n'alloue quoi que ce soit pour elle-même).
- 150 VM/seconde de taux de création sur un seul hôte.
- ~2–8% de perte de performance par rapport au matériel nu.
Même isolation au niveau matériel qu'une VM complète avec le même ordre de grandeur de densité qu'un conteneur.

Firecracker est le VMM, le processus qui parle réellement à /dev/kvm et démarre la microVM. Le reste de cet article est cette pile de bout en bout.
Firecracker
En novembre Firecracker
En novembre 2018, AWS a open-sourcé Firecracker à re:Invent. Il faisait déjà tourner Lambda en production, ce qui rend votre import pandas assez rapide pour être facturé à la milliseconde. En 2020, l'équipe a publié l'architecture à NSDI '20.
L'architecture
Forké de Google crosvm, réécrit en Rust, avec plus de la moitié du code supprimé. Chaque processus Firecracker est une microVM, avec exactement trois types de threads (documentés dans docs/design.md) :
- Le thread API est le bureau des commandes. Un serveur REST lié à un socket Unix (un socket local uniquement qui vit sous forme de fichier sur le disque, pas un port TCP). Accepte la configuration avant le démarrage et des actions limitées après.
- Le thread VMM est l'atelier matériel. Il fait semblant d'être chaque périphérique que l'invité peut voir. Lorsque l'invité touche ce qu'il pense être un registre NIC, le CPU met l'invité en pause, le VMM gère la sollicitation (« l'invitement (« l'invité a donné un coup de pied dans la file d'attente TX, videz-la ») et reprend. Le mécanisme : l'invité lit/écrit des adresses magiques ; le CPU les intercepte vers l'hôte.[^mmio]
- Les threads vCPU sont les coureurs. Un par CPU invité, chacun dans une boucle serrée : demander à KVM d'exécuter l'invité jusqu'à ce que quelque chose d'intéressant se produise (coup de pied de périphérique, interruption, arrêt), le gérer, boucler.
Ils communiquent entre eux via des canaux Rust (files d'attente de messages en processus, sans verrou). L'invité voit exactement quatre périphériques.

Les quatre périphériques
- virtio-net est la NIC de la VM, sans émulation de 1998. L'invité écrit les paquets dans une virtqueue (un tampon circulaire en anneau en mémoire partagée) ; le VMM les vide via un périphérique TAP côté hôte (une interface Ethernet virtuelle que le noyau expose sous forme de fichier), piloté par io_uring ou epoll pour que le thread VMM ne se bloque pas.
- virtio-block est le disque de la VM, simplement des E/S fichier sur l'hôte. L'invité place des demandes de secteur dans une virtqueue ; le VMM émet de simples pread/pwrite simples contre un fichier hôte. Pas d'IDE, pas AHCI, pas SCSI.
- virtio-vsock est l'interphone de la VM avec l'hôte. Adressé par un tuple (contexte-id, port) au lieu d'une paire IP/port, afin que l'agent invité puisse contacter la base (journaux, pings de santé, métriques, métadonnées de snapshot) sans IP invitée et rien sur le fil à usurper.
- Le UART série 8250 est la console de démarrage. Une puce série héritée minuscule émulée à une adresse fixe. Utilisée pour les journaux de démarrage précoce et les vidages sur incident avant que virtio ne soit opérationnel. Peu coûteux, universelle, ne disparaîtra jamais.
Démarrage d'une microVM, de bout en bout
L'API est l'intégralité du plan de contrôle : le canal de configuration, maintenu délibérément séparé du plan de données (les threads vCPU qui exécutent réellement le code invité). Vous démarrez le binaire pointant vers un socket Unix :
Ensuite, vous y mettez la configuration :
Quatre appels HTTP. C'est tout le plan de contrôle.

L'oignon de sécurité
Une seule frontière KVM est déjà forte. Firecracker enveloppe deux couches supplémentaires autour.
Le jailer est un constructeur de bac à sable. Son seul travail est d'encapsuler le VMM avant même. Il crée un chroot (une fonctionnalité Linux qui verrouille un processus dans une seule arborescence de répertoires comme si ce répertoire était la racine du système de fichiers ; le processus ne peut littéralement rien nommer au-dessus), tombe dans un nouvel espace de noms PID afin qu'il ne peut pas voir les autres processus de l'hôte, passe à un uid/gid non privilégié, applique les limites CPU/mémoire cgroup, et alors seulement exécute le binaire Firecracker à l'intérieur de cette prison :
Maintenant, le processus VMM lui-même n'a pas de système de fichiers à l'exception d'un chroot dédié, aucune vue des autres processus sur l'hôte, et aucune capacités root. Si une évasion de l'invité vers l'hôte se produit via virtio ou KVM, l'attaquant atterrit dans ce chroot avec les limites cgroup.
seccomp est une liste blanche d'appels système par thread. Tout ce qui n'est pas sur la liste est tué (ou retourne EPERM) avant d'atteindre le gestionnaire d'appels système du noyau. Firecracker livre trois niveaux :
- Niveau 0 : désactivé. Ne pas utiliser en prod.
- Niveau 1 : liste blanche par numéro d'autorisation par numéro d'appel système.
- Niveau 2 : contraint également les valeurs des arguments (par exemple, ioctl est ok, mais seulement avec KVM_RUN comme commande). Par défaut et recommandé.
Chaque thread obtient la surface minimale possible : le thread API n'a pas besoin de ioctl(KVM_RUN) ; les threads vCPU n'ont pas besoin de socket(). Une vue simplifiée de ce à quoi ressemble une règle :
Chaque couche doit échouer indépendamment pour qu'un attaquant atteigne l'hôte.
Snapshots : le code de triche derrière Lambda SnapStart
Prenez un snapshot d'une microVM en cours d'exécution. Restaurez-le en quelques millisecondes, sur un hôte différent, dans un tout nouveau processus VMM. Sautez le démarrage du noyau, sautez init, sautez le réchauffement JIT.
Vous gelez la VM en cours d'exécution et videz la mémoire + l'état des périphériques sur disque :
Un snapshot capture l'état post-réchauffement, donc la VM restaurée se réveille au milieu de sa vie, pas au début.
C'est exactement ce que fait AWS Lambda SnapStart : initialiser une Lambda Java une fois, snapshotter la microVM, et restaurer ce snapshot à chaque démarrage à froid suivante (annonce). Les démarrages à froid JVM passent soudainement de 8+ secondes à moins d'une seconde.

Comment ils s'assemblent
gVisor est une conception différente : un noyau en espace utilisateur en Go, une réimplémentation de l'interface d'appels système Linux qui s'exécute comme un processus normal. Les appels système de l'invité frappent gVisor au lieu du noyau hôte, et gVisor décide quoi (le cas échéant) transmettre en aval. Plus rapide à démarrer qu'une microVM, 10–30% de surcharge d'appels système sur le chemin chaud, et une frontière de confiance différente.
Firecracker se situe dans la case « mon propre noyau, mais pas de BIOS PCI » : isolation matérielle, modèle de périphérique minuscule, et démarrage en millisecondes.
Choisissez votre outil :
Qui utilise cela
Il est presque plus rapide de lister les plateformes serverless qui ne reposent pas sur des microVM.
Firecracker en production :
- AWS Lambda et AWS Fargate : le cas d'utilisation original. Chaque invocation Lambda atterrit dans une microVM Firecracker ; les tâches Fargate sont des VM Firecracker avec un runtime conteneur léger à l'intérieur.
- Fly.io Machines : chaque machine fly run de fly machine est une microVM Firecracker, distribuée mondialement, avec des démarrages à froid inférieurs à la seconde et des disques persistants.
- Presque tous les bacs à sable d'exécution de code d'agent IA que vous avez utilisés au cours des dix-huit derniers mois vivent dans une microVM Firecracker.
La forme d'une API de bac à sable est à peu près la même chez tous les fournisseurs à ce stade :
En environ quatre lignes de code : une microVM Firecracker démarre, un noyau s'initialise, un processus agent à l'intérieur de l'invité reçoit votre commande via vsock, l'exécute, renvoie les résultats, et la VM meurt.
L'ère des agents : pourquoi tout cela compte maintenant
Il y a un an, « qu'est-ce qu'un bac à sable IA ? » était une question de niche. Si un LLM générait du code, il n'était probablement pas sûr à 100 % de l'exécuter sur n'importe quelle machine, vous le feriez donc tourner dans un bac à sable éphémère.
Aujourd'hui, tout produit IA sérieux livre un agent. Leurs bacs à sable se sont également améliorés, mais la forme des agents a changé, et les anciennes réponses d'exécution ne correspondent pas à la nouvelle forme.
Agents in-process vs agents au niveau de l'hôte
La première vague d'agents IA vivait à l'intérieur de votre application. Vous importiez une bibliothèque, câbliez une boucle, et l'exécutiez dans votre backend existant :
Chaque appel était un aller-retour HTTP vers un modèle. Chaque appel d'outil était une fonction dans votre propre processus. Le « bac à sable » était votre propre serveur. C'est le monde du Vercel AI SDK, LangChain, OpenAI Agents SDK. Cela fonctionne des agents. Cela fonctionne très bien et livre encore une grande partie des agents de production aujourd'hui.
La deuxième vague est différente. Claude Code, Codex, et OpenCode sont des agents au niveau de l'hôte : des binaires qui prennent le contrôle d'une machine, pas des bibliothèques qui vivent à l'intérieur de la vôtre. Ils attendent un vrai shell, un gestionnaire de paquets, et un disque inscriptible. Lorsque vous donnez une tâche à Claude Code, il exécute ce genre de chose :
C'est un shell/bash. Il a besoin d'un vrai système de fichiers, d'un vrai fork/exec, d'un gestionnaire de paquets, d'un disque sur lequel vous pouvez écrire, d'un réseau que vous pouvez atteindre. Rien de tout cela n'est exprimable comme un schéma d'outil de complétion de chat, et rien de tout cela n'est sûr à exécuter dans un conteneur à noyau partagé aux côtés d'autres locataires.
Les laboratoires font du post-entraînement de leurs modèles directement sur ces harnais (l'échafaudage autour du modèle) : le shell, l'éditeur de fichiers, le testeur, la boucle d'exécution, la boucle d'agent elle-même. Cela signifie que l'écart entre « modèle + harnais sur lequel il a été entraîné » et « modèle + échafaudage DIY » se creuse chaque trimestre chaque trimestre.
Une machine Linux entière par agent, exécutant du code non fiable que l'agent vient d'inventer est exactement la charge de travail pour laquelle Firecracker a été conçu. La convergence ci-dessus n'était pas un accident.
Nous commençons à voir plus d'expérimentations avec des agents entourant la séparation calcul & harnais. Managed Agents d'Anthropic en est un exemple, où le harnais de l'agent est exécuté à côté du bac à sable, pas à l'intérieur.
Certaines entreprises construisent même des systèmes de fichiers hébergés complets (comme Archil et Mesa), pour offrir aux agents une meilleure recherche et un meilleur stockage.
À mesure que les agents s'améliorent et changent avec le temps, il y aura beaucoup plus d'offres d'infrastructure intéressantes, construites sur Firecracker.
Ce pour quoi vous payez réellement les plateformes d'infrastructure d'agents
Les bacs à sable génériques « exécuter du code arbitraire » sont devenus une commodité maintenant. L'infrastructure est entièrement open-source. La couche microVM est Firecracker ou Cloud Hypervisor, disponible sous Apache 2.0. La conversion conteneur-à-rootfs est un script Go de 200 lignes. Des ingénieurs talentueux peuvent monter une plateforme de bac à sable fonctionnelle en un week-end.
Vous payez pour ce qui est connecté à la VM. La microVM nue est le minimum requis.
La surface produit intéressante :
- L'observabilité est le produit, pas un aide au débogage. Tout ce que l'agent (stdout, appels système, écritures de fichiers, requêtes réseau) transite par un seul socket vers un collecteur côté hôte. Les constructeurs d'ont besoin d'une relecture complète de session complète, et des artefacts par action pour créer les meilleurs produits.
- Les secrets sont négociés au niveau du fil, jamais remis à l'invité. L'invité ne voit que des variables d'environnement factices ; echo $SECRET à l'intérieur du bac à sable renvoie le factice. Un proxy de sortie côté hôte (chaque paquet sortant doit le traverser) substitue le véritable identifiant au niveau du TAP hôte (l'extrémité appartenant au noyau de la NIC virtuelle de la VM, que l'invité ne peut ni voir ni adresser), contre une liste d'autorisation explicite, avec une piste d'audit par session. L'agent peut exécuter du code arbitraire qu'il a généré il y a cinq secondes et ne peut toujours pas exfiltrer un identifiant qu'il n'a jamais eu.
- L'identité est signée au niveau de l'hôte, pas à l'intérieur de l'agent. Les requêtes sortantes peuvent porter une identité cryptographique par session (y compris les signatures Web Bot Auth, construites sur HTTP Message Signatures + Ed25519) frappée par l'hôte avant que le paquet ne quitte le pont. La clé de signature n'entre jamais dans la microVM.
- L'autre calcul est regroupé dans la même microVM que le runtime. Browserbase associe chaque runtime d'agent 1:1 avec un navigateur sur le même hôte, souvent la même microVM. La distance physique entre le processus agent et Chromium est effectivement nulle : les commandes CDP (le Chrome DevTools Protocol, le format filaire JSON-over-WebSocket utilisé pour piloter Chrome programmatiquement) passent par un socket Unix, pas à travers un réseau de services, donc la latence d'action est de l'ordre de la milliseconde. Les images de screencast n'ont pas à traverser l'internet public pour atterrir dans la relecture de session.
Et vous ne pouvez pas simplement assembler tout cela proprement sur Docker. Les coutures ne sont pas là. Notre pari est que le marché des runtimes d'agent ne sera pas gagné avec du calcul brut, mais avec la meilleure observabilité, les meilleurs secrets, la meilleure identité, les meilleurs partenariats, et le calcul colocalisé regroupement du calcul colocalisé en une seule surface produit.

Alternatives de runtime à surveiller
- Bubblewrap : bac à sable par espace de noms utilisateur non privilégié. Un utilisateur non root peut créer un bac à sable sans sudo, en utilisant les mêmes primitives du noyau que Flatpak utilise pour confiner les applications de bureau. Plus léger qu'une VM, partage toujours le noyau hôte, ce n'est donc pas un substitut aux microVM contre du code vraiment non fiable. Mais c'est une excellente couche d'isolation imbriquée pour fonctionner à l'intérieur d'une microVM, ou un bon choix pour du code de confiance sur votre propre hôte.
- Isolats V8 : le modèle de Cloudflare Workers. Chaque isolat est un contexte d'exécution JS séparé avec son propre tas, partageant un seul processus V8 avec potentiellement des milliers d'autres locataires. Le démarrage est d'environ 5 ms, deux ordres de grandeur plus rapide qu'une microVM. La frontière de confiance est le propre bac à sable de V8 ; historiquement, il a bien tenu, mais c'est une ligne beaucoup plus fine que celle d'un hyperviseur. L'autre inconvénient : vous n'obtenez que la sémantique Node. Pas de fork, pas d'exec, pas de modules natifs, systèmes de fichiers simulés. Dévastateur pour le code d'agent JS pur ; inutile si vous devez pip install numpy.
- gVisor : le noyau en espace utilisateur de Google en Go. Forte isolation sans virtualisation imbriquée (une VM invitée tournant à l'intérieur d'une autre VM, que la plupart des fournisseurs cloud désactivent par défaut ; gVisor n'en a pas besoin, donc il fonctionne dans GKE dès la sortie de la boîte). P paie environ 10–30 % sur les charges de travail lourdes en appels système. Un bon compromis lorsque la virtualisation matérielle n'est pas disponible.
- Bacs à sable WASM (wasmtime, wasmer) : déterministes, petits, rapides, mais l'écosystème est peu profond. WASI (l'API d'appels système standard pour WASM) mûrit. Pas encore une cible directe pour « exécuter ce binaire Python/Node arbitraire ».

Si vous construisez pour du code non fiable à usage général : Firecracker (ou Cloud Hypervisor, une conception VMM/virtio similaire). Si vous construisez pour des charges de travail JS connues : isolats V8. Tout le reste est une réponse spécialisée à une question spécialisée.
Le tableau général
Firecracker a pris l'une des plus vieilles idées de l'informatique, une machine virtuelle, et en a supprimé assez pour la rendre bon marché. Il parie que l'isolation renforcée par le matériel en vaut la peine si vous pouvez la rendre assez rapide.
Ce pari allait toujours payer pour le serverless. Ce qui a changé, c'est que la charge de travail « code multi-locataire non fiable » est passée d'« une fonction web que je ne veux pas mettre en bac à sable » à « un agent générant des commandes arbitraires qui pourraient toucher la prod ». Le périmètre s'est déplacé et la tolérance pour les évasions du noyau partagé est passée de « risque acceptable » à « impossible à livrer ».
Et ça a marché. C'est un binaire Rust, 50 000 lignes, qui parle à /dev/kvm.
Les conteneurs empaquettent le logiciel. Les microVM l'isolent. L'ingénierie intéressante de la prochaine décennie, c'est tout ce que vous enroulez autour de la boîte.
→ Kyle
Cet article de blog contient des composants interactifs et des animations (qui n'apparaissent pas sur les articles X. Si vous voulez voir cette version, elle est ici : https://www.browserbase.com/blog/what-is-firecracker.





