这里有很多很好的技术答案,清楚地讨论了VM和容器之间的差异以及Docker的起源。
对我而言,VM和Docker之间的根本区别在于您如何管理应用程序的推广。
使用VM,您可以将应用程序及其依赖项从一个VM升级到下一个DEV到UAT到PRD。
使用Docker,我们的想法是将应用程序与其所需的库一起捆绑在自己的容器中,然后进行推广 的 整个 强> 容器作为一个单元。
因此,在最基本的VM级别,您可以将应用程序及其依赖项作为独立组件进行升级,而使用Docker,您可以在一次命中中提升所有内容。
是的,容器存在问题,包括管理它们,尽管像Kubernetes或Docker Swarm这样的工具大大简化了任务。
好的答案。只是为了得到容器与VM的图像表示,请看下面的那个。
资源
Docker,基本上是容器,支持 的 OS虚拟化 强> 即您的应用程序认为它具有完整的操作系统实例,而VM支持 的 硬件虚拟化 强> 。您觉得它是一台物理机器,您可以在其中启动任何操作系统。
在Docker中,运行的容器共享主机操作系统内核,而在VM中,它们拥有自己的操作系统文件。当您将应用程序部署到各种服务环境(例如“测试”或“生产”)时,开发应用程序的环境(OS)将是相同的。
例如,如果您开发在端口4000上运行的Web服务器,当您将其部署到“测试”环境时,该端口已被其他程序使用,因此它将停止工作。在容器中有层;您对操作系统所做的所有更改都将保存在一个或多个图层中,这些图层将成为图像的一部分,因此无论图像在何处,依赖关系都会出现。
在下面显示的示例中,主机有三个VM。为了使VM中的应用程序完全隔离,它们每个都有自己的OS文件,库和应用程序代码副本,以及操作系统的完整内存实例。 而下图显示了与容器相同的情况。容器只是共享主机操作系统,包括内核和库,因此它们不需要启动操作系统,加载库或为这些文件支付专用内存成本。它们采用的唯一增量空间是应用程序在容器中运行所需的任何内存和磁盘空间。虽然应用程序环境感觉像专用操作系统,但应用程序就像在专用主机上一样部署。容器化应用程序在几秒钟内启动,并且应用程序的更多实例可以适合机器而不是VM情况。
资源: https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/
资料来源:Kubernetes in Action。
有许多答案可以解释这些差异的更详细,但这是我非常简短的解释。
一个重要的区别是 的 VM使用单独的内核来运行OS 强> 。这就是它很重的原因,需要时间来启动,消耗更多的系统资源。
的 在Docker中,容器共享内核 强> 与主人;因此它重量轻,可以快速启动和停止。
在虚拟化中,资源在设置开始时分配,因此当虚拟机在许多时间空闲时,资源未被充分利用。 在Docker中,容器没有分配固定数量的硬件资源,并且可以根据需要自由使用资源,因此具有高度可扩展性。
Docker使用 的 UNION文件系统 强> .. Docker使用写时复制技术来减少容器消耗的内存空间。 在这里阅读更多
和---关联:-
“为什么比简单地将软件部署到docker镜像更容易 部署到一致的生产环境?“
大多数软件都部署到许多环境中,通常至少有以下三种:
还有以下因素需要考虑:
正如您所看到的,组织的外推服务器总数很少以单个数字表示,通常是三位数,并且可以很容易地显着提高。
这一切都意味着,首先创建一致的环境是非常困难的,因为它的体积非常大(即使在绿色场景中),但是 的 保持一致几乎是不可能的 强> 给定大量服务器,添加新服务器(动态或手动),来自o / s供应商,防病毒供应商,浏览器供应商等的自动更新,手动软件安装或由开发人员或服务器技术人员执行的配置更改等让我再说一遍 - 实际上(没有双关语)不可能保持环境一致(好吧,对于纯粹主义者来说,它可以完成,但它涉及大量的时间,精力和纪律,这正是VM和容器的原因(例如Docker)首先设计了)。
所以想想你的问题更像这样 “鉴于保持所有环境一致的极端困难,将软件部署到码头图像是否更容易,即使考虑到学习曲线?” 。我想你会发现答案肯定会是“是” - 但是只有一种方法可以找到,在Stack Overflow上发布这个新问题。
这可能是许多码头学习者的第一印象。
首先,docker镜像通常比VM镜像小,因此易于构建,复制,共享。
其次,Docker容器可以在几毫秒内启动,而VM可以在几秒钟内启动。
这是Docker的另一个关键功能。图像具有图层,不同的图像可以共享图层,使其更加节省空间并且构建速度更快。
如果所有容器都使用Ubuntu作为基本映像,并非每个映像都有自己的文件系统,但是共享相同的下划线ubuntu文件,并且只有它们自己的应用程序数据不同。
的 将容器视为流程! 强>
在主机上运行的所有容器确实是一堆具有不同文件系统的进程。它们共享相同的操作系统内核,仅封装系统库和依赖项。
这对大多数情况都很好(没有额外的操作系统内核维护),但如果容器之间需要严格的隔离,则可能会出现问题。
所有这些似乎都是改进,而不是革命。好, 量化积累导致质的转变 。
考虑应用程序部署。如果我们要部署新软件(服务)或升级软件(服务),最好更改配置文件和进程,而不是创建新VM。因为创建具有更新服务的VM,对其进行测试(在Dev& QA之间共享),部署到生产需要数小时甚至数天。如果出现任何问题,你必须重新开始,浪费更多时间。因此,使用配置管理工具(puppet,saltstack,chef等)安装新软件,首选下载新文件。
说到docker,就不可能使用新创建的docker容器来替换旧的docker容器。维护更容易!构建新映像,与QA共享,测试,部署它只需要几分钟(如果一切都是自动化的),在最坏的情况下需要几个小时。这就是所谓的 的 不可变基础设施 强> :不要维护(升级)软件,而是创建一个新软件。
它改变了服务的交付方式。我们需要应用程序,但必须维护VM(这很痛苦,与我们的应用程序关系不大)。 Docker让您专注于应用程序并平滑一切。
了解虚拟化和容器如何在低级别工作可能会有所帮助。这将清除很多事情。
注意:我在下面的描述中简化了一点。有关更多信息,请参阅参考
的 虚拟化如何在低级别工作? 强>
在这种情况下,VM管理器接管CPU环0(或较新CPU中的“根模式”)并拦截来宾操作系统所做的所有特权调用,以创建客户操作系统具有自己的硬件的错觉。有趣的事实:在1998年之前,人们认为在x86架构中无法实现这一点,因为没有办法进行这种拦截。 VMWare的人 是第一个 谁有想法重写内存中的可执行字节,以实现客户操作系统的特权调用。
实际效果是虚拟化允许您在同一硬件上运行两个完全不同的操作系统。每个客户操作系统都经历了引导,加载内核等所有过程。您可以拥有非常严格的安全性,例如,客户操作系统无法完全访问主机操作系统或其他客户并搞砸了。
的 容器如何在低水平工作? 强>
周围 2006年 人们包括谷歌的一些员工实施了新的内核级别功能 命名空间 (不过这个想法 长 之前 存在于FreeBSD中 )。操作系统的一个功能是允许将全局资源(如网络和磁盘)共享到进程。如果将这些全局资源包装在名称空间中,以便它们仅对在同一名称空间中运行的那些进程可见,该怎么办?比如说,你可以获得一大块磁盘并将其放在命名空间X中,然后在命名空间Y中运行的进程无法查看或访问它。类似地,名称空间X中的进程无法访问分配给名称空间Y的内存中的任何内容。当然,X中的进程无法查看或与名称空间Y中的进程通信。这为全局资源提供了一种虚拟化和隔离。这就是docker的工作原理:每个容器都在自己的命名空间中运行,但完全使用 相同 内核作为所有其他容器。发生隔离是因为内核知道分配给进程的命名空间,并且在API调用期间确保进程只能访问其自己的命名空间中的资源。
容器与VM的限制现在应该是显而易见的:您不能在VM中的容器中运行完全不同的操作系统。不管你 能够 运行Linux的不同发行版,因为它们共享相同的内核。隔离级别不如VM中那么强。实际上,“guest”容器有一种方法可以在早期实现中接管主机。您还可以看到,当您加载新容器时,操作系统的整个新副本不会像在VM中那样启动。所有容器 共享相同的内核 。这就是容器重量轻的原因。与VM不同,您不必为容器预先分配大量内存,因为我们没有运行新的操作系统副本。这样就可以在一个操作系统上运行数千个容器,同时对它们进行沙盒处理,如果我们在自己的VM中运行单独的操作系统副本,这可能是不可能的。