En cette ère de cloud computing, vous avez sûrement déjà croisé les termes « machines virtuelles » et « conteneurs ». Mais si ces deux concepts sont souvent associés au cloud computing, ils ont aussi leur rôle à jouer dans les datacenters traditionnels (y compris sur site). Dans cet article, nous allons comparer ces deux pratiques et étudier quelques cas d'usage montrant leurs avantages respectifs.
Différences techniques
Pour identifier ces différences techniques, il faut d'abord comprendre ce qu'est un noyau de système d'exploitation. Le noyau est chargé de toutes les tâches logicielles de base, notamment :
- Attribution équitable de temps de traitement
- Gestion de la mémoire vive
- Attribution d'accès aux terminaux physiques, tels que disques durs (magnétiques ou SSD), claviers, souris, écrans, interfaces réseau, etc.
- Fourniture d'une couche d'abstraction pour accéder aux fichiers sur les disques durs, plus communément appelés « fichiers système »
- Traitement des communications inter-process
- Implémentation des différentes couches de la pile réseau (IP, TCP, UDP, etc.)
- Et bien d'autres tâches encore
Les tâches confiées au noyau sont innombrables. De ce fait, les noyaux (comme le noyau Linux) sont plutôt gros et représentent plusieurs millions de lignes de code.
Quelle est donc la principale différence technique entre une machine virtuelle et un conteneur ? Une machine virtuelle exécute son propre noyau, tandis qu'un conteneur utilise le noyau de son hôte. En voici la représentation visuelle :
Les conteneurs sont parfois désignés comme « machines virtuelles légères ». Pourtant, ceux-ci exécutent bien moins de processus que les machines virtuelles (le plus souvent d'ailleurs, ils n'en exécutent qu'un). L'exécution d'un système d'exploitation complet au sein d'un conteneur est une opération très difficile, voire impossible.
Les machines virtuelles, quant à elles, « se prennent » pour un système d'exploitation complet exécuté sur du matériel physique. Ce matériel est en réalité simulé par le biais d'un élément logiciel au sein du noyau hôte appelé l'hyperviseur.
À propos des machines virtuelles
Une machine virtuelle est un système d'exploitation invité exécuté sur un système d'exploitation hôte, ce dernier étant installé sur du matériel physique. Pour pouvoir exécuter des machines virtuelles, le système d'exploitation hôte a besoin d'un hyperviseur. Ce dernier lui fournit une couche de virtualisation complète avec quelques éléments matériels simulés, de telle sorte que le système d'exploitation invité pense être exécuté sur du matériel physique. Le système d'exploitation invité se comporte exactement comme un système d'exploitation standard.
Il est important de savoir que lorsque vous exécutez une instance sur un service cloud, ce dernier fait en réalité tourner une machine virtuelle.
Avantages des machines virtuelles :
- Le système d'exploitation invité se comporte exactement comme un système d'exploitation standard et ne sait pas qu'il est exécuté sur un hyperviseur et non sur du matériel physique.
- Une machine virtuelle peut être « enregistrée » comme un fichier unique et déplacée ou répliquée simplement à un autre emplacement.
Inconvénients des machines virtuelles :
- Une machine virtuelle est gourmande en espace disque, puissance de calcul et mémoire vive, car il s'agit d'un système d'exploitation complet.
- Une machine virtuelle nécessite beaucoup de maintenance, pour la raison invoquée ci-dessus ; pour remédier à ce problème, votre infrastructure doit être immuable.
- Une machine virtuelle est légèrement plus lente que le système d'exploitation hôte du fait de la présence de la couche d'hyperviseur, mais ce ralentissement reste minime.
- Une machine virtuelle est en général un peu lente au démarrage en raison du nombre important de processus et de services qu'elle contient.
À propos des conteneurs
Pour faire simple, les conteneurs sont des processus reposant sur le noyau hôte. Ce dernier les maintient dans un environnement isolé, de sorte qu'ils ne voient pas les autres éléments exécutés sur ce noyau. Les processus d'un même conteneur peuvent communiquer entre eux, mais non avec les processus d'autres conteneurs ou du noyau hôte.
Pour que le noyau hôte puisse exécuter des conteneurs, il doit disposer d'une technologie logicielle capable de séparer les processus comme décrit précédemment. Le noyau Linux offre cette technologie, appelée « espaces de noms ».
Il est donc impossible d'exécuter un système d'exploitation complet à l'intérieur d'un conteneur, car un seul noyau est exécuté, à savoir celui du système d'exploitation hôte. Par conséquent, les conteneurs ont davantage des boîtes fermées contenant des processus que des « machines virtuelles légères ». Les processus peuvent être exécutés à l'intérieur de leur boîte uniquement et non pas accès aux autres boîtes.
Sans entrer dans les détails, le noyau hôte peut toutefois être configuré de façon à ce que les processus d'un conteneur donné puissent « voir » et « toucher » des éléments extérieurs à leur boîte. Cette opération est néanmoins dangereuse et doit être évitée dans la mesure du possible.
Avantages des conteneurs :
- Les conteneurs sont « légers » dans la mesure où ils n'exécutent que les processus requis pour un workload donné, ce qui permet de faire des économies de puissance de calcul, de mémoire vive et d'espace disque par rapport aux machines virtuelles.
- Le démarrage des conteneurs est généralement rapide mais dépend du logiciel exécuté. Quoi qu'il en soit, un logiciel démarrera toujours plus rapidement dans un conteneur que dans une machine virtuelle.
- Il existe des référentiels publics proposant un grand nombre d'images de conteneurs pour diverses applications, comme Docker Hub.
- Leur surface d'attaque est plus petite que celle des machines virtuelles.
Inconvénients des conteneurs :
- Il n'est pas possible d'exécuter un système d'exploitation complet dans un conteneur.
- En théorie, un exploit dans un conteneur peut engendrer des exploits dans d'autres conteneurs. Ce problème est cependant devenu très rare, car la technologie d'espaces de noms de Linux (utilisée pour exécuter des conteneurs) est désormais très mature et sécurisée.
- Il n'est pas possible d'enregistrer un conteneur dans un fichier unique et de le déplacer.
- Le système de fichiers racine est éphémère, ce qui signifie que tout ce que vous écrivez dans ce système de fichiers sera détruit à la fermeture du conteneur.
Différences entre machines virtuelles et conteneurs
Intéressons-nous maintenant aux différences pratiques entre les machines virtuelles et les conteneurs. La première différence notable est qu'il est possible d'exécuter des conteneurs à l'intérieur de machines virtuelles, mais pas l'inverse.
Les machines virtuelles et les conteneurs ne remplissent pas les mêmes objectifs. Une machine virtuelle exécute un système d'exploitation complet et est conçue pour être utilisée dans la durée. Un conteneur exécute quant à lui un workload spécifique ; il est éphémère et immuable par nature. Par conséquent, si vos conteneurs requièrent un stockage à long terme (par exemple, un stockage persistant conservé à chaque redémarrage du conteneur), des volumes doivent être montés, et donc déclarés et gérés séparément.
En règle générale, les conteneurs sont plus agiles que les machines virtuelles, car ils sont conçus pour exécuter une seule tâche. Si votre cas d'usage nécessite l'utilisation de machines virtuelles, il vous sera difficile d'utiliser des conteneurs à la place. Par contre, si votre cas d'usage permet l'utilisation de conteneurs, vous aurez le choix entre conteneurs et machines virtuelles (bien que les deux options présentent de grandes différences en termes d'architecture).
Vous avez sans doute entendu parler des outils d'orchestration des conteneurs, comme Kubernetes. Si vous utilisez des conteneurs, vous aurez probablement besoin d'un tel outil qui s'accompagne d'une courbe d'apprentissage et de questions de sécurité qui lui sont propres. Si vous utilisez les machines virtuelles de votre fournisseur cloud, vous n'aurez a priori besoin que des outils de gestion proposés par ce même fournisseur, tels que les groupes d'autoscaling et les répartiteurs de charge. Si vous utilisez des machines virtuelles dans un datacenter traditionnel, vous aurez sans doute besoin d'un outil d'orchestration de machines virtuelles tel que VMware vSphere, qui comporte également sa propre courbe d'apprentissage (incontestablement plus difficile que celle des outils d'orchestration des conteneurs).
Enfin, les conteneurs sont plus adaptés à la configuration d'un maillage de services, architecture alternative à l'utilisation de répartiteurs de charge internes.
Comme le montrent les schémas ci-dessus, la seconde architecture est manifestement plus gourmande en ressources que la première. Il est possible de créer un maillage de services en utilisant, par exemple HashiCorp Consul, mais cet outil est plus encombrant et difficile à configurer que Istio sur un cluster Kubernetes.
Aspects liés à la sécurité
Bien qu'apparemment similaires, les machines virtuelles et les conteneurs ne présentent pas les mêmes défis en termes de sécurité. Les couches logicielles qui sous-tendent les deux technologies (hyperviseurs et espaces de noms de noyau, respectivement), désormais très matures et sécurisées, ne présentent pas de problème particulier en matière de sécurité.
Les machines virtuelles exécutant un système d'exploitation complet, il convient d'appliquer les mêmes techniques de protection qu'un système complet, à savoir :
- Renforcement du système d'exploitation
- Implémentation d'un antivirus
- Application régulière et précise de correctifs (étape pouvant être omise en cas d'utilisation d'une infrastructure immuable)
- Exécution de processus comme utilisateurs ordinaires plutôt qu'utilisateurs root
- Renforcement du serveur SSH
- Configuration du pare-feu
- Réduction de la surface d'attaque (via la suppression des logiciels inutiles)
- Utilisation d'analyseurs pour identifier les vulnérabilités lors de la création de l'image
- Adoption d'outils pour identifier les vulnérabilités à l'exécution
Comme le montre cette liste, la protection d'une machine virtuelle est une tâche ardue. La plupart de ces tâches peuvent être effectuées lors de la création de l'image qui sera utilisée pour exécuter la machine virtuelle. Néanmoins, une charge importante de travail doit être effectuée à l'exécution pour détecter les vulnérabilités et la compromission d'un système.
À l'inverse, la protection d'un conteneur est simple :
- Veillez à ne pas exécuter le conteneur en mode à privilèges.
- Exécutez le ou les processus en tant qu'utilisateur ordinaire et non root.
- Vérifiez que les autorisations d'accès au système de fichiers sont aussi restrictives que possible.
- Utilisez des analyseurs pour identifier les vulnérabilités lors de la création de l'image.
D'autres vérifications de sécurité doivent être effectuées à l'exécution des conteneurs, mais elles sont généralement plus simples à gérer et à implémenter que dans le cas des machines virtuelles.
Dans les deux cas, toutes les mesures de protection du système d'exploitation hôte dans une machine virtuelle décrites ci-dessus s'appliquent au système d'exploitation hôte qui exécutera les machines virtuelles/conteneurs.
CrowdStrike peut vous proposer diverses solutions pour protéger vos workloads contre les virus et autres logiciels malveillants, ainsi que contre les attaques réseau.
La différence technique entre les machines virtuelles et les conteneurs est assez simple à comprendre. Les cas d'usage de ces deux architectures permettent de mieux appréhender leurs différences.
Depuis la création de Docker, l'utilisation des conteneurs a augmenté de façon régulière du fait de leur agilité et de l'application de l'immuabilité. En outre, combinés à un puissant orchestrateur tel que Kubernetes, ils présentent de nombreux avantages par rapport aux machines virtuelles. C'est pourquoi, bien que les machines virtuelles traditionnelles aient encore la cote auprès de certaines entreprises, les conteneurs leur emboîtent tout doucement le pas.