4463 votes

Comment Docker est-il différent d'une machine virtuelle?

Je continue de relire la documentation de Docker pour essayer de comprendre la différence entre Docker et une machine virtuelle complète. Comment parvient-il à fournir un système de fichiers complet, un environnement réseau isolé, etc. sans être aussi lourd?

Pourquoi le déploiement de logiciels sur une image Docker (si c'est le bon terme) est-il plus facile que de simplement déployer dans un environnement de production cohérent?

16 votes

Analyse des performances de Docker vs KVM : bodenr.blogspot.com/2014/05/…

1 votes

Si vous recherchez la différence entre leurs images - stackoverflow.com/questions/29096967/…

46 votes

Docker n'est pas une machine virtuelle - c'est un outil de gestion de configuration.

4015voto

Ken Cochrane Points 12318

Docker utilisait initialement LinuX Containers (LXC), mais a ensuite basculé vers runC (anciennement connu sous le nom de libcontainer), qui s'exécute dans le même système d'exploitation que son hôte. Cela lui permet de partager beaucoup des ressources du système d'exploitation hôte. De plus, il utilise un système de fichiers en couches (AuFS) et gère le réseau.

AuFS est un système de fichiers en couches, vous pouvez donc avoir une partie en lecture seule et une partie en écriture qui sont fusionnées. On peut avoir les parties communes du système d'exploitation en lecture seule (et partagées entre tous vos conteneurs) puis donner à chaque conteneur son propre point de montage pour l'écriture.

Donc, disons que vous avez une image de conteneur de 1 Go; si vous vouliez utiliser une VM complète, vous auriez besoin de 1 Go x le nombre de VM que vous voulez. Avec Docker et AuFS, vous pouvez partager la majeure partie du 1 Go entre tous les conteneurs et si vous avez 1000 conteneurs, vous pourriez encore n'avoir qu'un peu plus de 1 Go d'espace pour l'OS des conteneurs (en supposant qu'ils exécutent tous la même image OS).

Un système virtualisé complet obtient son propre ensemble de ressources qui lui sont allouées et partage peu. Vous obtenez plus d'isolement, mais c'est beaucoup plus lourd (nécessite plus de ressources). Avec Docker, vous obtenez moins d'isolement, mais les conteneurs sont légers (nécessitent moins de ressources). Ainsi, vous pourriez facilement exécuter des milliers de conteneurs sur un hôte, et cela ne cillerait même pas. Essayez de le faire avec Xen, et à moins d'avoir un hôte très puissant, je ne pense pas que ce soit possible.

Un système virtualisé complet prend généralement des minutes pour démarrer, tandis que les conteneurs Docker/LXC/runC prennent des secondes, et souvent moins d'une seconde.

Il y a des avantages et des inconvénients pour chaque type de système virtualisé. Si vous voulez un isolement complet avec des ressources garanties, une VM complète est la voie à suivre. Si vous voulez simplement isoler les processus les uns des autres et exécuter un tas d'entre eux sur un hôte de taille raisonnable, alors Docker/LXC/runC semble être la voie à suivre.

Pour plus d'informations, consultez cet ensemble d'articles de blog qui expliquent bien le fonctionnement de LXC.

Pourquoi déployer un logiciel dans une image Docker (si c'est le terme approprié) est-il plus facile que de simplement déployer dans un environnement de production cohérent ?

Déployer un environnement de production cohérent est plus facile à dire qu'à faire. Même si vous utilisez des outils comme Chef et Puppet, il y a toujours des mises à jour de l'OS et d'autres éléments qui changent entre les hôtes et les environnements.

Docker vous donne la possibilité de mettre en snapshot l'OS dans une image partagée, et facilite le déploiement sur d'autres hôtes Docker. Localement, dev, qa, prod, etc. : toutes les mêmes images. Bien sûr, vous pouvez le faire avec d'autres outils, mais pas aussi facilement ou rapidement.

C'est idéal pour les tests; disons que vous avez des milliers de tests qui doivent se connecter à une base de données, et chaque test a besoin d'une copie prête de la base de données et apportera des modifications aux données. L'approche classique consiste à réinitialiser la base de données après chaque test, soit avec un code personnalisé soit avec des outils comme Flyway - cela peut prendre beaucoup de temps et signifie que les tests doivent être exécutés séquentiellement. Cependant, avec Docker, vous pourriez créer une image de votre base de données et exécuter une instance par test, puis exécuter tous les tests en parallèle car vous savez qu'ils seront tous exécutés contre le même instantané de la base de données. Comme les tests s'exécutent en parallèle et dans des conteneurs Docker, ils pourraient tous s'exécuter sur la même machine en même temps et devraient finir beaucoup plus rapidement. Essayez de faire cela avec une VM complète.

De commentaires...

Intéressant ! Je suppose que je suis toujours confus par la notion de "mettre en snapshot l'OS". Comment fait-on cela sans, bon, faire une image de l'OS ?

Eh bien, voyons si je peux expliquer. Vous commencez par une image de base, puis apportez vos modifications, et commitez ces modifications en utilisant Docker, et cela crée une image. Cette image ne contient que les différences par rapport à la base. Lorsque vous voulez exécuter votre image, vous avez également besoin de la base, et il superpose votre image sur la base en utilisant un système de fichiers en couches : comme mentionné ci-dessus, Docker utilise AuFS. AuFS fusionne les différentes couches ensemble et vous obtenez ce que vous voulez ; vous n'avez qu'à l'exécuter. Vous pouvez continuer à ajouter plus d'images (couches) et il continuera à sauvegarder uniquement les différences. Comme Docker se base généralement sur des images prêtes à l'emploi provenant d'un registre, vous avez rarement besoin de "mettre en snapshot" tout l'OS vous-même.

0 votes

Sauf sur macOS, il semble que CE soit une VM. LinuxKit VM pour être précis?

0 votes

"Alors, disons que vous avez une image de conteneur de 1 Go ; si vous voulez utiliser une VM complète, vous auriez besoin de 1 Go x nombre de VMs souhaitées" - personne en son bon sens ne regarderait un seul système bare-metal exécutant, disons, 100 conteneurs LXC contre 100 VM indépendantes communiquant entre elles sur le même matériel bare metal. Ce n'est pas le but des VM, et sûrement pas même l'OP qui a pensé cela. Vous comparez des pommes et des oranges.

0 votes

"Un système entièrement virtualisé prend généralement quelques minutes pour démarrer" - sérieusement ? C'était quand ça - en 1985 ? J'utilise des machines virtuelles tout le temps et leur démarrage est généralement de 20 à 30 secondes; c'est-à-dire à peu près la même chose que le démarrage du métal nu. Parlez-vous vraiment du démarrage de dizaines de machines virtuelles, dans une tentative malavisée de les comparer à un système unique démarrant des dizaines de LXCs ?

382voto

shuron Points 31

J'aime Ken Cochrane's answer.

Mais je veux ajouter un point de vue supplémentaire, non détaillé ici. À mon avis, Docker diffère également dans l'ensemble du processus. Contrairement aux machines virtuelles, Docker ne concerne pas (seulement) le partage optimal des ressources matérielles, il fournit en outre un "système" pour empaqueter une application (de préférence, mais ce n'est pas obligatoire, sous forme de microservices).

Pour moi, cela s'inscrit dans l'écart entre les outils orientés développeurs comme rpm, Debian packages, Maven, npm + Git d'un côté et les outils ops comme Puppet, VMware, Xen, vous l'appelez...

Pourquoi est-il plus facile de déployer un logiciel dans une image Docker (si c'est le bon terme) que de simplement le déployer dans un environnement de production cohérent?

Votre question suppose un environnement de production cohérent. Mais comment le maintenir cohérent? Pensez à un certain nombre (>10) de serveurs et d'applications, des étapes dans le pipeline.

Pour maintenir cela synchronisé, vous commencerez à utiliser quelque chose comme Puppet, Chef ou vos propres scripts de provisionnement, règles non publiées et/ou beaucoup de documentation... En théorie, les serveurs peuvent fonctionner indéfiniment et être maintenus complètement cohérents et à jour. En pratique, la gestion de la configuration d'un serveur échoue, il existe donc une possibilité considérable de dérive de configuration et de modifications inattendues des serveurs en cours d'exécution.

Il existe donc un motif connu pour éviter cela, le soi-disant serveur immuable. Mais le motif de serveur immuable n'était pas aimé. Principalement en raison des limitations des machines virtuelles qui étaient utilisées avant Docker. Traiter avec des images de plusieurs gigaoctets, déplacer ces images volumineuses juste pour modifier quelques champs dans l'application était très laborieux. Compréhensible...

Avec un écosystème Docker, vous n'aurez jamais besoin de déplacer des gigaoctets pour des "petits changements" (merci aufs et Registry) et vous n'aurez pas à vous soucier de perdre des performances en empaquetant des applications dans un conteneur Docker à l'exécution. Vous n'aurez pas à vous soucier des versions de cette image.

Et enfin, vous pourrez souvent reproduire des environnements de production complexes même sur votre ordinateur Linux (ne m'appelez pas si cela ne fonctionne pas dans votre cas ;))

Et bien sûr, vous pouvez démarrer des conteneurs Docker dans des machines virtuelles (c'est une bonne idée). Réduisez votre provisionnement de serveur au niveau de la VM. Tout ce qui précède pourrait être géré par Docker.

P.S. Entre-temps, Docker utilise sa propre implémentation "libcontainer" au lieu de LXC. Mais LXC est toujours utilisable.

1 votes

Il semble étrange d'inclure git dans un groupe d'outils comme rpm et dpkg. Je mentionne cela car je vois les tentatives d'utiliser des systèmes de contrôle de version comme git comme outil de distribution/emballage comme source de beaucoup de confusion.

5 votes

Il n'a pas tort cependant, git peut être utilisé pour la gestion des packages, bower par exemple est essentiellement internalement un outil en ligne de commande sophistiqué pour télécharger des étiquettes git.

4 votes

Emballer des applications dans des conteneurs est une approche intéressante et valide. Cependant, si vous l'emballiez dans Docker, cela serait excessif, car il n'y aurait pas de support direct pour les dépendances ou les bibliothèques partagées. C'est exactement ce que les nouvelles technologies d'emballage comme Ubuntu Snap et Flatpak pour Redhat essaient de réaliser. À mon avis, l'une de ces technologies d'emballage l'emportera et deviendra l'avenir de l'emballage sous Linux.

169voto

Pankaj Arora Points 111

À travers cet article, nous allons mettre en évidence quelques différences entre les machines virtuelles (VMs) et les conteneurs Linux (LXCs). Commençons par les définir.

VM :

Une machine virtuelle émule un environnement informatique physique, mais les demandes en CPU, mémoire, disque dur, réseau et autres ressources matérielles sont gérées par une couche de virtualisation qui traduit ces demandes vers le matériel physique sous-jacent.

Dans ce contexte, la VM est appelée le client (Guest) tandis que l'environnement sur lequel elle s'exécute est appelé l'hôte.

LXC :

Les conteneurs Linux (LXC) sont des fonctionnalités au niveau du système d'exploitation qui permettent d'exécuter plusieurs conteneurs Linux isolés, sur un hôte de contrôle (l'hôte LXC). Les conteneurs Linux servent d'alternative légère aux VMs car ils ne nécessitent pas d'hyperviseurs tels que Virtualbox, KVM, Xen, etc.

À moins que vous n'ayez été drogué par Alan (Zach Galifianakis - de la série Very Bad Trip) et que vous ayez passé un an à Vegas, vous êtes très probablement au courant de l'intérêt croissant pour la technologie des conteneurs Linux, et en particulier pour un projet de conteneurs qui a fait sensation dans le monde entier ces derniers mois - Docker. Cela a conduit à des opinions diverses selon lesquelles les environnements de cloud computing devraient abandonner les machines virtuelles (VMs) et les remplacer par des conteneurs en raison de leur faible surcharge et de leurs performances potentiellement meilleures.

Mais la grande question est : est-ce faisable ? Est-ce sensé ?

a. Les LXCs sont limités à une instance de Linux. Il peut s'agir de différentes distributions de Linux (par exemple, un conteneur Ubuntu sur un hôte CentOS, mais c'est toujours du Linux). De même, les conteneurs basés sur Windows sont limités à une instance de Windows. En revanche, les VMs ont une portée beaucoup plus large et en utilisant les hyperviseurs, vous n'êtes pas limité aux systèmes d'exploitation Linux ou Windows.

b. Les LXCs ont une faible surcharge et offrent de meilleures performances par rapport aux VMs. Des outils comme Docker, qui sont construits sur la technologie LXC, ont fourni aux développeurs une plateforme pour exécuter leurs applications et ont également donné aux équipes opérationnelles un outil qui leur permet de déployer le même conteneur sur des serveurs de production ou des centres de données. Ceci vise à rendre l'expérience entre le développeur exécutant une application, la démarrage et le test de l'application et l'opérateur déployant cette application fluide, car c'est là que réside la friction et l'objectif du DevOps est de briser ces silos.

La meilleure approche est donc que les fournisseurs d'infrastructure cloud recommandent une utilisation appropriée des VMs et des LXCs, car chacun est adapté à des charges de travail et des scénarios spécifiques.

Abandonner les VMs n'est pas pratique pour le moment. Ainsi, les VMs et les LXCs ont tous deux leur propre existence et leur importance individuelle.

4 votes

Votre partie "b" ci-dessus est exactement ce que les gens de Docker disent sur la technologie. Son objectif est de simplifier les tâches de développement et de déploiement. Et d'après mon expérience en tant que développeur et administrateur système, je dois être d'accord.

3 votes

C'est une réponse assez abstraite. Nous avons besoin de cas d'utilisation pour savoir quand utiliser/ne pas utiliser Docker. C'est la question. Tout le monde peut comprendre en quoi consiste Docker mais seulement quelques-uns peuvent expliquer sur des scénarios réels.

1 votes

Docker est désormais introduit dans le monde de Windows, car il n'est plus dépendant de LXC : blogs.msdn.com/b/nzdev/archive/2015/06/02/… veuillez me corriger si j'ai mal compris les réponses ici.

123voto

Docker encapsule une application avec toutes ses dépendances.

Un virtualiseur encapsule un OS qui peut exécuter toutes les applications qu'il peut normalement exécuter sur une machine en métal nu.

1 votes

Je suis en train d'apprendre sur LXC, corrigez-moi si je me trompe, mais est-ce que cela pourrait être une sorte de virtualenv? mais évidemment plus large, pas seulement limité à Python pour le dire.

2 votes

J'aime le mieux cette réponse. Elle est simple et va droit au but. Maintenant que l'on a une compréhension de base de CE QUE LXC et les virtualisateurs peuvent faire, les détails des autres lectures auront du sens.

2 votes

@Phil Cela a été fait après avoir lu les réponses détaillées ci-dessus en premier.

74voto

purpletech Points 349

Ils sont tous les deux très différents. Docker est léger et utilise LXC/libcontainer (qui repose sur le partitionnement du noyau et les cgroups) et n'a pas d'émulation de machine/matériel telle que l'hyperviseur, KVM. Xen qui sont lourds.

Docker et LXC sont plus destinés à l'isolement, à la conteneurisation et à l'isolation des ressources. Il utilise l'API de clonage du système hôte (actuellement seulement le noyau Linux) qui fournit du partitionnement pour l'IPC, NS (mount), réseau, PID, UTS, etc.

Qu'en est-il de la mémoire, de l'E/S, du CPU, etc.? Cela est contrôlé à l'aide des cgroups où vous pouvez créer des groupes avec des spécifications/restrictions de ressources (CPU, mémoire, etc.) et y placer vos processus. En plus de LXC, Docker fournit une infrastructure de stockage (http://www.projectatomic.io/docs/filesystems/) par exemple, un système de fichiers de montage en union où vous pouvez ajouter des couches et partager des couches entre différents espaces de montage.

C'est une fonctionnalité puissante où les images de base sont généralement en lecture seule et seulement lorsque le conteneur modifie quelque chose dans la couche, il écrira quelque chose sur la partition en lecture-écriture (alias copie sur écriture). Il fournit également de nombreuses autres fonctionnalités telles que le registre et la version des images.

Avec le LXC normal, vous devez apporter un rootfs ou partager le rootfs et lorsque vous partagez, les modifications sont répercutées sur les autres conteneurs. En raison de ces nombreuses fonctionnalités ajoutées, Docker est plus populaire que LXC. LXC est populaire dans les environnements embarqués pour mettre en œuvre la sécurité autour des processus exposés aux entités externes telles que le réseau et l'interface utilisateur. Docker est populaire dans les environnements cloud multi-locataires où un environnement de production cohérent est attendu.

Une VM normale (par exemple, VirtualBox et VMware) utilise un hyperviseur et des technologies associées ont soit un micrologiciel dédié qui devient la première couche pour le premier OS (OS hôte, ou invité OS 0) soit un logiciel qui s'exécute sur l'OS hôte pour fournir une émulation matérielle telle que CPU, USB/accessoires, mémoire, réseau, etc., aux OS invités. Les VM sont encore (en 2015) populaires dans les environnements multi-locataires à haute sécurité.

Docker/LXC peuvent être exécutés sur presque n'importe quel matériel bon marché (moins de 1 Go de mémoire est également OK tant que vous avez un noyau plus récent) contre des VM normales qui ont besoin d'au moins 2 Go de mémoire, etc., pour faire quelque chose de significatif avec. Mais le support de Docker sur l'OS hôte n'est pas disponible dans des OS tels que Windows (en nov 2014) tandis que différents types de VM peuvent être exécutés sous windows, Linux et Mac.

Voici une image de docker/rightscale : Voici une image de rightscale

0 votes

Juste pour mettre à jour, à partir de Windows 10/11 et Server 2019, Docker for Windows est pris en charge avec WSL (Windows Subsystem for Linux) activé, ce qui nécessite l'installation d'un noyau Ubuntu, et autres.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X