Docker与普通虚拟机有什么不同?

我不断重读Docker文档 ,试图理解Docker和完整虚拟机之间的区别。 它如何设法提供一个完整的文件系统,隔离的networking环境等,而不是一样重?

为什么将软件部署到docker图像(如果这是正确的话)比简单地部署到一致的生产环境更容易?

Docker最初使用的是LinuX Containers (LXC),但后来转向了runC (以前称为libcontainer ),它运行在与主机相同的操作系统上。 这使得它可以共享大量的主机操作系统资源。 此外,它使用分层文件系统( AuFS )和pipe理networking。

AuFS是一个分层的文件系统,所以你可以有一个只读部分和一个写部分合并在一起。 人们可以将操作系统的公共部分设置为只读(并在所有容器中共享),然后为每个容器分配自己的写入容器。

所以,假设你有一个1 GB的容器图像; 如果你想使用一个完整的虚拟机,你需要有1GB的x个虚拟机数量。 使用Docker和AuFS,您可以在所有容器之间共享1 GB的大部分内容,如果您拥有1000个容器,则容器操作系统的容量可能只有1 GB多一点(假设它们都运行相同的操作系统映像) 。

一个完整的虚拟化系统可以获得自己分配给它的一组资源,并且分配最less。 你会得到更多的隔离,但它要重得多(需要更多的资源)。 使用Docker可以减less隔离,但容器是轻量级的(需要更less的资源)。 所以你可以轻松地在主机上运行数千个容器,甚至不会眨眼。 尝试用Xen做这件事,除非你有一个真正的大主机,我不认为这是可能的。

完整的虚拟系统通常需要几分钟才能启动,而Docker / LXC / runC容器需要几秒钟的时间,通常甚至不到一秒钟。

每种types的虚拟化系统都有优点和缺点。 如果你想要保证资源的完全隔离,一个完整的虚拟机是要走的路。 如果你只是想将进程隔离开来,并想在合理大小的主机上运行大量进程,那么Doc​​ker / LXC / runC似乎就是要走的路。

欲了解更多信息,请查看这套博客文章 ,该文章很好地解释了LXC的工作原理。

为什么将软件部署到docker图像(如果这是正确的话)比简单地部署到一致的生产环境更容易?

部署一致的生产环境说起来容易做起来难。 即使你使用了Chef和Puppet这样的工具,也总会有OS更新和其他东西在主机和环境之间改变。

Docker使您能够将操作系统快照到共享映像中,并且可以轻松部署到其他Docker主机上。 在本地,dev,qa,prod等:所有相同的图像。 当然,你可以用其他工具来做到这一点,但不能简单或快速。

这对testing非常有用; 假设您有数千个需要连接到数据库的testing,并且每个testing都需要数据库的原始副本,并且会对数据进行更改。 经典的做法是在每次testing后重新设置数据库,使用自定义代码或Flyway等工具 – 这可能非常耗时,并且意味着testing必须连续运行。 但是,使用Docker,您可以创build数据库的映像,并在每个testing中运行一个实例,然后并行运行所有testing,因为您知道它们将全部运行在数据库的相同快照上。 由于testing是并行运行的,在Docker容器中,它们可以同时在同一个盒子上运行,并且应该以更快的速度运行。 尝试用一个完整的虚拟机来做这个。

来自评论…

有趣! 我想我还是被“快照”操作系统的概念弄糊涂了。 没有,做一个操作系统的形象,如何做到这一点?

那么,让我们看看我能解释一下。 您从一个基本的图像开始,然后进行更改,并使用docker提交这些更改,并创build一个图像。 这张图片只包含了与基地的区别。 当你想运行你的图像时,你也需要基础,并且使用分层文件系统在基础之上对图像进行分层:如上所述,Docker使用AUFS。 AUFS将不同的层合并在一起,你得到你想要的; 你只需要运行它。 你可以继续添加越来越多的图像(图层),它将继续保存差异。 由于Docker通常基于registry的现成图像构build,因此您很less必须自己“快照”整个操作系统。

我喜欢Ken Cochrane的回答。

但我想补充一些观点,这里不详细讲述。 在我看来,Docker在整个过程中也有所不同。 与虚拟机不同的是,Docker并不仅仅是硬件的最佳资源共享,而且它为包装应用程序提供了一个“系统”(优先但不是必须的,作为一组微软服务)。

对我来说,它适合面向开发人员的工具,如rpm,debian软件包,maven,npm + git和Ops工具(如Puppet,VMWare,Xen等)之间的差距。

为什么将软件部署到docker图像(如果这是正确的话)比简单地部署到一致的生产环境更容易?

你的问题假设一些一致的生产环境。 但如何保持一致? 考虑一些数量(> 10)的服务器和应用程序,stream水线中的阶段。 为了保持同步,你将开始使用像木偶,厨师或自己的供应脚本,未发布的规则和/或大量的文档…理论上,服务器可以无限期地运行,并保持完全一致和最新。 练习不能完全pipe理服务器的configuration,所以configuration漂移和正在运行的服务器发生意想不到的变化都有相当大的空间。

所以有一个已知的模式来避免这个,所谓的不可变服务器 。 但是不可变的服务器模式并没有被爱。 主要是因为在Docker之前使用了VM的限制。 处理几千兆字节的大图像,移动这些大的图像,只是为了改变应用程序的一些领域,是非常费力的。 可以理解的……

有了Docker生态系统,您将永远不需要在“小小的变化”(感谢aufs和Registry)的情况下移动千兆字节,而且您无需担心在运行时将应用程序打包到Docker容器中而导致性能的下降。 您不必担心该图像的版本。 最后,即使在你的笔记本电脑上,你甚至可以经常重现复杂的生产环境(如果你的情况不行,不要打电话给我);)

当然你可以在虚拟机中启动docker容器(这是一个好主意)。 减less在VM级别的服务器供应。 以上所有可以由Dockerpipe理。

PS同时,Docker使用自己的实现“libcontainer”而不是LXC。 但是LXC仍然可用。

很好的答案。 只是为了获得容器vs虚拟机的图像表示,请看下面的代码。

在这里输入图像描述

来源: https : //www.docker.com/what-c​​ontainer#/package_software

了解虚拟化和容器如何在低级别上工作可能会有帮助。 这将清理很多事情。

注意:我在下面的描述中简化了一下。 有关更多信息,请参阅参考

虚拟化如何在低层次上工作?

在这种情况下,VMpipe理器接pipeCPU环0(或更新的CPU中的“根模式”),并拦截来宾操作系统所做的所有特权调用,以创build客户操作系统具有自己的硬件的错觉。 有趣的事实是:在1998年以前,在x86架构中实现这一点是不可能的,因为没有办法做这种拦截。 VMWare的人们是第一个想到在guest虚拟机操作系统的特权调用中重写内存中可执行字节的人。

最终效果是虚拟化允许您在同一硬件上运行两个完全不同的操作系统。 每个客户操作系统都经历了所有引导过程,加载内核等过程。您可以拥有非常严格的安全性,例如,客户操作系统无法完全访问主机操作系统或其他客人,并搞砸了。

容器如何在低级别工作?

大约在2006年 ,包括Google员工在内的一些员工实现了名为空间的新内核级function(不过之前这个想法早已 存在于FreeBSD中 )。 操作系统的一个function是允许共享像networking和磁盘这样的全球资源进程。 如果这些全局资源被包装在命名空间中,只有在同一命名空间中运行的进程才可见,会怎么样呢? 比方说,你可以得到一块磁盘,把它放在命名空间X中,然后在命名空间Y中运行的进程不能看到或访问它。 类似地,命名空间X中的进程无法访问分配给命名空间Y的内存中的任何内容。当然,X中的进程无法看到或与命名空间Y中的进程对话。这为全局资源提供了一种虚拟化和隔离。 这就是docker的工作原理:每个容器运行在自己的名字空间中,但是使用与所有其他容器完全相同的内核。 发生隔离是因为内核知道分配给进程的名称空间,并且在API调用期间确保进程只能访问其自己的名称空间中的资源。

容器和虚拟机的限制现在应该是显而易见的:你不能在容器中运行完全不同的操作系统,就像虚拟机一样。 但是你可以运行不同的Linux发行版,因为它们共享相同的内核。 隔离级别不如在VM中那么强大。 事实上,在早期的实现中,有一种“guest”容器接pipe主机的方法。 你也可以看到,当你加载新的容器时,整个新的操作系统并不像启动虚拟机一样启动。 所有容器共享相同的内核 。 这就是为什么容器重量轻。 与VM不同的是,你不需要预先分配大量的内存给容器,因为我们没有运行新的操作系统。 这使得可以在一个操作系统上运行数千个容器,同时对它们进行沙盒处理,如果我们在自己的虚拟机中运行单独的操作系统副本,则可能无法做到这一点。

通过这篇文章,我们将在虚拟机和LXC之间划出一些区别。 我们先来定义它们。

VM

虚拟机模拟物理计算环境,但CPU,内存,硬盘,networking和其他硬件资源的请求由虚拟化层pipe理,虚拟化层将这些请求转换为底层物理硬件。

在这种情况下,VM被称为Guest,而它所运行的环境被称为主机。

LXC s:

Linux容器(LXC)是操作系统级function,可以在一个控制主机(LXC主机)上运行多个独立的Linux容器。 Linux Containers作为虚拟机的轻量级替代品,因为它们不需要虚拟机pipe理程序即viz。 Virtualbox,KVM,Xen等

现在,除非你被Alan(来自宿醉系列的Zach Galifianakis)麻醉,去年在拉斯维加斯,否则你将会非常清楚Linux容器技术的巨大兴趣,如果我将特定一个容器这个在过去几个月里引起世界各地关注的项目是:Docker引发了一些人们的观点,即云计算环境应该放弃虚拟机(VM),并用容器取而代之,因为它们开销较低,性能可能更好。

但是最大的问题是,这是可行的吗?是否明智?

一个。 LXC的范围是Linux的一个实例。 这可能是Linux的不同风格(例如CentOS主机上的Ubuntu容器,但它仍然是Linux)。同样,基于Windows的容器现在被定义为Windows实例,如果我们看看虚拟机,它们的范围相当广泛,虚拟机pipe理程序不限于操作系统Linux或Windows。

湾 与VM相比,LXC具有低开销和更好的性能。 工具即 基于LXC技术构build的Docker为开发人员提供了一个运行其应用程序的平台,同时赋予操作人员一个工具,使他们能够在生产服务器或数据中心部署相同的容器。 它试图让运行应用程序的开发人员,引导和testing应用程序的开发人员以及无缝部署该应用程序的操作人员之间的经验,因为这正是DevOps的所有摩擦所在,而DevOps的目的是打破这些孤岛。

所以最好的方法是云基础架构提供商应该主张适当使用虚拟机和LXC,因为它们都适合处理特定的工作负载和场景。

到目前为止,放弃虚拟机是不实际的。 所以虚拟机和LXC都有自己独特的存在和重要性。

Docker不是一种虚拟化方法。 它依赖于其他实际上实现基于容器的虚拟化或操作系统级虚拟化的工具。 为此,Docker最初使用LXC驱动程序,然后转移到libcontainer,现在将其更名为runc。 Docker主要关注在应用程序容器中自动部署应用程序。 应用程序容器被devise为打包和运行单个服务,而系统容器被devise为运行多个进程,如虚拟机。 因此,Docker被认为是集装箱系统上的容器pipe理或应用程序部署工具。

为了了解它与其他虚拟化有什么不同,我们来看看虚拟化及其types。 那么,理解那里的区别会更容易一些。

虚拟化

在其构思forms中,它被认为是一种逻辑划分大型机的方法,允许多个应用程序同时运行。 但是,如果公司和开源社区能够以某种方式提供处理特权指令的方法,并允许在单个基于x86的系统上同时运行多个操作系统,则情况将发生急剧变化。

pipe理程序

pipe理程序处理创build访客虚拟机操作的虚拟环境。 它监督访客系统,并确保在必要时将资源分配给访客。 pipe理程序位于物理机和虚拟机之间,并向虚拟机提供虚拟化服务。 为了实现它,它截取了虚拟机上的客户操作系统操作,并模拟了主机操作系统上的操作。

虚拟化技术的快速发展(主要在云中)推动了虚拟化技术的进一步发展,允许在XenServer,VMware Player,KVM等虚拟机pipe理程序的帮助下,在单个物理服务器上创build多个虚拟服务器。在英特尔VT和AMD-V等商品处理器中join硬件支持。

虚拟化的types

虚拟化方法可以基于它如何模拟硬件到客户操作系统并模拟客户操作环境来分类。 主要有三种types的虚拟化:

  • 仿真
  • 半虚拟化
  • 基于容器的虚拟化

仿真

仿真(也称为完全虚拟化)完全以软件运行虚拟机操作系统内核。 这种types的pipe理程序被称为2型pipe理程序。 它安装在主机操作系统的顶部,该主机操作系统负责将客户OS内核代码翻译成软件指令。 翻译完全是用软件完成的,不需要硬件的参与。 仿真使运行任何支持被仿真环境的未修改操作系统成为可能。 这种types的虚拟化的缺点是额外的系统资源开销,导致与其他types的虚拟化相比,性能下降。

仿真

这一类的例子包括VMware Player,VirtualBox,QEMU,Bochs,Parallels等。

半虚拟化

半虚拟化(也称为第1类虚拟机pipe理程序)直接在硬件上运行,即“裸机”,并直接向其上运行的虚拟机提供虚拟化服务。 它有助于操作系统,虚拟化硬件和真实硬件协作实现最佳性能。 这些pipe理程序通常具有相当小的占用空间,本身并不需要大量的资源。

这一类的例子包括Xen,KVM等

半虚拟化

基于容器的虚拟化

基于容器的虚拟化也称为操作系统级虚拟化,可以在单个操作系统内核中执行多个独立执行。 它具有最佳的性能和密度,并具有dynamic资源pipe理function。 这种types的虚拟化提供的孤立的虚拟执行环境被称为容器,可以被看作是一个被跟踪的进程组。

基于容器的虚拟化

通过添加到Linux内核版本2.6.24的命名空间function,可以实现容器的概念。 容器将其ID添加到每个进程,并为每个系统调用添加新的访问控制检查。 它由clone()系统调用访问,允许创build先前全局名称空间的单独实例。

命名空间可以用许多不同的方式使用,但是最常见的方法是创build一个隔离的容器,该容器对容器外部的对象没有可见性或访问权限。 在容器中运行的进程似乎在正常的Linux系统上运行,尽pipe它们与其他名字空间中的进程共享底层内核,对于其他types的对象也是如此。 例如,当使用名称空间时,容器内的root用户不会被视为容器外部的root用户,从而增加了额外的安全性。

Linux控制组(cgroups)子系统(用于启用基于容器的虚拟化的下一个主要组件)用于对进程进行分组并pipe理其总计资源消耗。 通常用于限制容器的内存和CPU消耗。 由于一个容器化的Linux系统只有一个内核,并且内核对容器有完全的可见性,所以只有一个级别的资源分配和调度。

有几种pipe理工具可用于Linux容器,包括LXC,LXD,systemd-nspawn,lmctfy,Warden,Linux-VServer,OpenVZ,Docker等。

容器vs虚拟机

与虚拟机不同,容器不需要引导操作系统内核,因此可以在不到一秒的时间内创build容器。 此function使得基于容器的虚拟化比其他虚拟化方法更独特和更有吸引力。

由于基于容器的虚拟化几乎不会为主机增加开销,因此基于容器的虚拟化具有接近原生的性能

对于基于容器的虚拟化,与其他虚拟化不同,不需要额外的软件。

主机上的所有容器共享主机的调度器,节省额外资源的需求。

容器状态(Docker或LXC图像)与虚拟机映像相比体积小,因此容器映像容易分发。

容器中的资源pipe理是通过cgroups来实现的。 Cgroups不允许容器消耗比分配给它们更多的资源。 但是,到目前为止,主机的所有资源都在虚拟机中可见,但是不能被使用。 这可以通过在容器和主机上同时运行tophtop来实现。 跨所有环境的输出将看起来相似。

这里的大多数答案都是关于虚拟机的。 在这个问题上,我将会给你一个单线的回应,这个问题在过去几年使用Docker的时候帮了我很大的忙。 这是:

Docker只是运行进程的一种奇特的方式,而不是虚拟机。

现在让我来解释一下这个意思。 虚拟机是他们自己的野兽。 我想解释一下, Docker能够帮助你理解这一点,而不是解释一下虚拟机是什么。 特别是因为这里有很多好的答案,告诉你到底是什么意思,当他们说“虚拟机”。 所以…

Docker容器只是一个进程(及其subprocess),在进程的其他进程中使用主机系统内核中的cgroups进行划分。 您可以通过在主机上运行ps aux来实际看到您的Docker容器进程。 例如,在一个容器中启动apache2 “就是在主机上启动apache2作为一个特殊的进程。 它只是从机器上的其他进程中划分出来的。 重要的是要注意,你的容器不在你的容器化过程的生命周期之外。 当你的过程死亡,你的容器死亡。 这是因为Docker用您的应用程序replace容器中的pid 1pid 1通常是init系统)。 关于pid 1最后一点非常重要。

就这些容器进程所使用的文件系统而言,Docker使用UnionFS- backed的映像,这就是你在执行docker docker pull ubuntu时所下载的内容。 每个“图像”只是一系列图层和相关的元数据。 分层的概念在这里非常重要。 每个图层只是从它下面的图层发生变化。 例如,当您在构buildDocker容器时删除Dockerfile中的文件时,实际上只是在最后一层上面创build了一个图层,表示“此文件已被删除”。 顺便说一句,这就是为什么你可以从你的文件系统中删除一个大文件,但是镜像仍然占用相同数量的磁盘空间。 该文件仍然存在,位于当前文件下面的图层中。 图层本身只是文件的压缩文件。 你可以用docker save --output /tmp/ubuntu.tar ubuntu来testing,然后cd /tmp && tar xvf ubuntu.tar 。 那么你可以看看周围。 所有看起来像长哈希的目录实际上是单独的图层。 每一个都包含文件( layer.tar )和元数据( json )以及关于特定图层的信息。 这些层只是描述了文件系统的变化,这些变化被保存为一个“在原始状态之上”的层。 当读取“当前”数据时,文件系统读取数据就像只查看最上层的变化。 这就是为什么该文件似乎被删除,即使它仍然存在于“以前的”层,因为文件系统只看最顶层。 这允许完全不同的容器共享其文件系统层,即使每个容器中最顶层的文件系统可能发生了一些重大变化。 这可以为您节省大量的磁盘空间,当您的容器共享其基本图像层。 但是,通过卷将主机系统中的目录和文件装载到容器中时,这些卷会绕过UnionFS,因此更改不会存储在图层中。

Docker中的networking通过使用以太网桥(主机上称为docker0 )和主机上每个容器的虚拟接口来实现。 它在docker0创build一个虚拟子网,以便容器在“彼此之间”进行通信。 这里有很多联网选项,包括为您的容器创build自定义子网,以及“共享”主机的networking堆栈以便您的容器直接访问。

Docker移动速度非常快。 它的文档是我见过的最好的文档。 它通常写得很好,简洁,准确。 我build议您查看可用的文档以获取更多信息,并且相信文档可以在线阅读,包括Stack Overflow。 如果您有任何具体的问题,我强烈build议您joinFreenode IRC的#docker ,并在那询问(您甚至可以使用Freenode的networking聊天function!)。

Docker封装了一个具有所有依赖关系的应用程序,一个虚拟器封装了一个可以运行任何应用程序的操作系统,它通常可以在裸机上运行。

他们都非常不同。 Docker是轻量级的,使用LXC / libcontainer(依赖于内核命名空间和cgroups),没有像hypervisor,KVM这样的机器/硬件仿真。 Xen很重。

Docker和LXC更适用于沙盒,集装箱和资源隔离。 它使用主机操作系统(目前只有Linux内核)克隆API,为IPC,NS(挂载),networking,PID,UTS等提供命名空间。

内存,I / O,CPU等等呢? 这是使用cgroups控制的,您可以创build具有特定资源(CPU,内存等)规范/限制的组,并将您的进程放在那里。 在LXC之上,Docker提供了一个存储后端( http://www.projectatomic.io/docs/filesystems/ ),例如union mount文件系统,您可以在其中添加图层并在不同的安装名称空间之间共享图层。

这是一个强大的function,其中基本的图像通常是只读的,只有当容器修改图层中的某些东西时,才会写入读写分区(即写入时复制)。 它还提供了许多其他的包装,如registry和版本的图像。

使用普通的LXC,你需要使用一些rootfs,或者共享rootfs,当共享时,更改会反映在其他容器上。 由于这些附加function很多,Docker比LXC更受欢迎。 LXC在embedded式环境中非常stream行,用于实现暴露于外部实体(如networking和UI)的进程的安全性。 Docker在预计一致的生产环境的云多租户环境中非常stream行。

一个普通的虚拟机(例如VirtualBox和VMware)使用虚拟机pipe理程序,相关的技术有专用的固件,成为第一个OS(主机操作系统或客户机OS 0)的第一层,或者是在主机操作系统上运行的软件为客户操作系统提供CPU,USB /附件,内存,networking等硬件仿真。 虚拟机还是(截至2015年)在高安全性的多租户环境中stream行。

Docker / LXC几乎可以在任何便宜的硬件上运行(只要内核较新,less于1 GB的内存也可以),而普通的VM至less需要2 GB的内存等,才能做到有意义的事情。 但是,主机操作系统上的Docker支持在Windows等操作系统(截至2014年11月)中不可用,在这些操作系统中,可以在Windows,Linux和Mac上运行各种types的虚拟机。

这是来自docker / rightscale的图片: 这里是一个从rightscale图片

和—关联:-

“为什么将软件部署到docker图像比简单地部署到一致的生产环境更容易?”

大多数软件都部署到许多环境中,通常至less有以下三种:

  1. 个人开发者个人电脑
  2. 共享开发者环境
  3. 个人testing器PC(s)
  4. 共享的testing环境
  5. QA环境
  6. UAT环境
  7. 负载/性能testing
  8. 实时分段
  9. 生产
  10. 档案

还有以下因素需要考虑:

  • 开发人员,甚至testing人员,都将根据工作的性质,或者微妙地或者完全不同的PCconfiguration
  • 开发人员通常可以在PC上开发,而不受公司或业务标准化规则的控制(例如,在自己的机器上开发的自由职业者(通常是远程),或者贡献者不是“雇用”或“签约”的开源项目办法)
  • 某些环境将由负载平衡configuration中的固定数量的多台机器组成
  • 许多生产环境将根据stream量级别dynamic(或“弹性地”)创build和销毁基于云的服务器

正如你所看到的,一个组织的外推服务器总数很less是单个数字,经常是三位数字,并且可以很容易地显着提高。

这一切都意味着,仅仅因为数量巨大(即使在绿色环境下),创build一致的环境也是非常困难的,但是考虑到大量服务器,增加新服务器(dynamic或手动),o / s供应商,反病毒供应商,浏览器供应商等的自动更新,由开发人员或服务器技术人员执行的手动软件安装或configuration更改等等。让我重复一遍 – 实际上(没有双关语意思)是不可能的to keep environments consistent (okay, for the purist, it can be done, but it involves a huge amount of time, effort and discipline, which is precisely why VMs and containers (eg Docker) were devised in the first place).

So think of your question more like this "Given the extreme difficulty of keeping all environments consistent, is it easier to deploying software to a docker image, even when taking the learning curve into account ?" 。 I think you'll find the answer will invariably be "yes" – but there's only one way to find out, post this new question on Stack Overflow.

Docker, basically containers, supports OS virtualization ie your application feels that it has a complete instance of an OS whereas VM supports hardware virtualization . You feel like it is a physical machine in which you can boot any OS.

In Docker, the containers running share the host OS kernel, whereas in VMs they have their own OS files. The environment (the OS) in which you develop an application would be same when you deploy it to various serving environments, such as "testing" or "production".

For example, if you develop a web server that runs on port 4000, when you deploy it to your "testing" environment, that port is already used by some other program, so it stops working. In containers there are layers; all the changes you have made to the OS would be saved in one or more layers and those layers would be part of image, so wherever the image goes the dependencies would be present as well.

In the example shown below, the host machine has three VMs. In order to provide the applications in the VMs complete isolation, they each have their own copies of OS files, libraries and application code, along with a full in-memory instance of an OS. Without Containers Whereas the figure below shows the same scenario with containers. Here, containers simply share the host operating system, including the kernel and libraries, so they don't need to boot an OS, load libraries or pay a private memory cost for those files. The only incremental space they take is any memory and disk space necessary for the application to run in the container. While the application's environment feels like a dedicated OS, the application deploys just like it would onto a dedicated host. The containerized application starts in seconds and many more instances of the application can fit onto the machine than in the VM case. 在这里输入图像描述

Source: https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/

There are three different setups that providing a stack to run an application on (This will help us to recognize what a container is and what makes it so much powerful than other solutions):

 1) Traditional Servers(bare metal) 2) Virtual machines (VMs) 3) Containers 

1) Traditional server stack consist of a physical server that runs an operating system and your application.

优点:

  • Utilization of raw resources

  • 隔离

缺点:

  • Very slow deployment time
  • Expensive
  • Wasted resources
  • Difficult to scale
  • Difficult to migrate
  • Complex configuration

2) The VM stack consist of a physical server which runs an operating system and a hypervisor that manages your virtual machine, shared resources, and networking interface. Each Vm runs a Guest Operating System, an application or set of applications.

优点:

  • Good use of resources
  • 易于扩展
  • Easy to backup and migrate
  • 成本效益
  • 灵活性

缺点:

  • Resource allocation is problematic
  • Vendor lockin
  • Complex configuration

3) The Container Setup , the key difference with other stack is container-based virtualization uses the kernel of the host OS to rum multiple isolated guest instances. These guest instances are called as containers. The host can be either a physical server or VM.

优点:

  • 隔离
  • 轻量级
  • Resource effective
  • Easy to migrate
  • 安全
  • Low overhead
  • Mirror production and development environment

缺点:

  • Same Architecture
  • Resource heavy apps
  • Networking and security issues.

By comparing the container setup with its predecessors, we can conclude that containerization is the fastest, most resource effective, and most secure setup we know to date. Containers are isolated instances that run your application. Docker spin up the container in a way, layers get run time memory with default storage drivers(Overlay drivers) those run within seconds and copy-on-write layer created on top of it once we commit into the container, that powers the execution of containers. In case of VM's that will take around a minute to load everything into the virtualize environment. These lightweight instances can be replaced, rebuild, and moved around easily. This allows us to mirror the production and development environment and is tremendous help in CI/CD processes. The advantages containers can provide are so compelling that they're definitely here to stay.

There are many answers which explain more detailed on the differences, but here is my very brief explanation.

One important difference is that VMs use a separate kernel to run the OS . That's the reason it is heavy and takes time to boot, consuming more system resources.

In Docker, the containers share the kernel with the host; hence it is lightweight and can start and stop quickly.

In Virtualization, the resources are allocated in the beginning of set up and hence the resources are not fully utilized when the virtual machine is idle during many of the times. In Docker, the containers are not allocated with fixed amount of hardware resources and is free to use the resources depending on the requirements and hence it is highly scalable.

Docker uses UNION File system .. Docker uses a copy-on-write technology to reduce the memory space consumed by containers. 在这里阅读更多

1. Lightweight

This is probably the first impression for many docker learners.

First, docker images are usually smaller than VM images, makes it easy to build, copy, share.

Second, Docker containers can start in several milliseconds, while VM starts in seconds.

2. Layered File System

This is another key feature of Docker. Images have layers, and different images can share layers, make it even more space-saving and faster to build.

If all containers use Ubuntu as their base images, not every image has its own file system, but share the same underline ubuntu files, and only differs in their own application data.

3. Shared OS Kernel

Think of containers as processes!

All containers running on a host is indeed a bunch of processes with different file systems. They share the same OS kernel, only encapsulates system library and dependencies.

This is good for most cases(no extra OS kernel maintains) but can be a problem if strict isolations are necessary between containers.

Why it matters?

All these seem like improvements, not revolution. Well, quantitative accumulation leads to qualitative transformation .

Think about application deployment. If we want to deploy a new software(service) or upgrade one, it is better to change the config files and processes instead of creating a new VM. Because Creating a VM with updated service, testing it(share between Dev & QA), deploying to production takes hours, even days. If anything goes wrong, you got to start again, wasting even more time. So, use configuration management tool(puppet, saltstack, chef etc.) to install new software, download new files is preferred.

When it comes to docker, it's impossible to use a newly created docker container to replace the old one. Maintainance is much easier!Building a new image, share it with QA, testing it, deploying it only takes minutes(if everything is automated), hours in the worst case. This is called immutable infrastructure : do not maintain(upgrade) software, create a new one instead.

It transforms how services are delivered. We want applications, but have to maintain VMs(which is a pain and has little to do with our applications). Docker makes you focus on applications and smooths everything.

I have used docker in production environment and staging very much. when you get used to it you will find it very powerful for building a multi container and isolated environment.

Docker has been developed base on LXC (Linux Container) and works perfectly in many linux distributions specially ubuntu.

Docker containers are isolated environment you can see it when you issue a top command in a docker container that has been created from a docker images.

beside that they are very light-weight and flexible thanks to dockerFile configuration.

for eg you can create a docker image and config a DockerFile and tell that for example when it is running then wget 'this', apt-get 'that', run 'some shell script', setting environment variables and so on.

In micro-services projects and architecture docker is a very viable asset. you can achieve scalability, resiliency and elasticity with docker, docker swarm, kubernetes and docker compose.

another important issue regarding docker is docker HUb and its community. for Example I myself implemented an ecosystem for monitoring kafka using Prometheus, Grafana, Prometheus-JMX-Exporter and dokcer.

for doing that I downloaded configured dockers for zookeeper, kafka, prometheus, grafana and jmx-collector then mounted my own configuration for some of them using yml files or for others I changed some files and configuration in the docker container and i build a whole system for monitoring kafka using multi-container dockers on a single machine with isolation and scalability and resiliency that this architecture can be easily moved into multiple servers.

beside docker hub site there is another site called quay.io that you can use it to have your own docker images dashboard there and pull/push to/from it. even you can import docker images from docker hub to quay then running them form quay on your own machine.

Note: Learning docker at the first place seems complex and hard but when you get used to it then you can not work without it.

I myself remember firs days of working with docker when I issued wrong commands or removing my containers and all of data and configurations mistakenly.

Simple answer to your question is:-

You wanted to know, Difference between Virtual Machine and Docker

Basic Concept: Docker is a container based virtualization, with the help of which we can create containers and deploy our applications onto the containers. So the major key point to remember here is – Docker uses the same OS kernel for running "n" number of containers on that server host. whereas, If you use Virtualization you can create "n" number of virtual machines (based on capacity of your host) and install OS for that VM and then run/deploy your application on that VM.

Size & Capacity: If you create VM and install linux on that VM, its base setup would probably going to eat up around 8 to 16 Gb of your machine (Linux Image itself is 4 to 6Gb) If you install Docker on your hosts – you would be able to spin up Linux container in very few time and that would practically take 200-500 Mb of space of your host

Time Creating VM, Installing images and making the VM ready will take atleast 1 hrs (as per my experience) whereas Docker can make your linux container ready in 5 to 10 mins max; rather much less than that (considering you have good network speed)