Docker和虚拟机有什么不同?

4421

我一直在反复阅读Docker文档,试图理解Docker和完整虚拟机之间的区别。它如何在不过重的情况下提供完整的文件系统、隔离的网络环境等等。

为什么将软件部署到Docker镜像(如果这是正确的术语)比仅仅部署到一致的生产环境更容易呢?


16
Docker与KVM性能分析:http://bodenr.blogspot.com/2014/05/kvm-and-docker-lxc-benchmarking-with.html本文将介绍Docker和KVM的性能比较。这篇文章使用了基准测试并针对CPU、内存、磁盘IO和网络性能进行了比较。结果表明,Docker在大多数方面都优于KVM,尤其是在启动时间、CPU性能和内存占用方面。但是,在磁盘IO和网络性能方面,KVM表现更好。总体而言,选择哪种虚拟化技术应该考虑到具体的使用情境和需求。 - Dave
1
如果你正在寻找它们的图像之间的区别,请访问以下链接:https://dev59.com/cF4b5IYBdhLWcg3wdxcv?noredirect=1&lq=1 - devesh-ahuja
45
Docker不是一种虚拟机,而是一种配置管理工具。 - aaa90210
41
不要忘记,Docker for Mac和Docker for Windows确实使用虚拟化层。 - Shapeshifter
19
Docker不是一种虚拟机,而是一种配置管理工具。 - aquirdturtle
25个回答

44
Docker基本上是容器,支持操作系统虚拟化,即您的应用程序感觉它拥有完整的操作系统实例,而VM支持硬件虚拟化。您可以像在物理机器上一样启动任何操作系统。
在Docker中,运行的容器共享主机操作系统内核,而在虚拟机中,它们有自己的操作系统文件。开发应用程序的环境(操作系统)将与您部署到各种服务环境(如“测试”或“生产”)时相同。
例如,如果您开发一个在端口4000上运行的Web服务器,当您将其部署到“测试”环境时,该端口已被其他程序使用,因此它停止工作。在容器中有层;您对操作系统所做的所有更改都将保存在一个或多个层中,并且这些层将成为映像的一部分,因此无论映像去哪里,依赖项也将存在。
在下面的示例中,主机拥有三个虚拟机。为了使虚拟机中的应用程序完全隔离,它们各自具有操作系统文件、库和应用程序代码的副本,以及一个完整的内存实例。Without Containers 而下面的图显示了使用容器的相同场景。在这里,容器仅共享主机操作系统,包括内核和库,因此它们不需要启动操作系统、加载库或为那些文件支付专用内存成本。它们所占用的唯一增量空间是应用程序在容器中运行所需的任何内存和磁盘空间。尽管应用程序的环境感觉像是专用操作系统,但应用程序部署方式就像在专用主机上一样。容器化应用程序可以在几秒钟内启动,并且比虚拟机情况下更多的应用程序实例可以适配到机器上。enter image description here

来源: https://azure.microsoft.com/zh-cn/blog/containers-docker-windows-and-trends/


37

有三种不同的设置可以提供一个运行应用程序的堆栈(这将帮助我们认识到容器是什么,并使其比其他解决方案更强大):

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

1) 传统服务器堆栈由运行操作系统和应用程序的物理服务器组成。

优点:

  • 充分利用原始资源

  • 隔离性

缺点:

  • 部署时间非常慢
  • 昂贵
  • 浪费资源
  • 难以扩展
  • 难以迁移
  • 复杂配置

2) 虚拟机堆栈由运行操作系统和管理虚拟机、共享资源和网络接口的hypervisor组成。每个虚拟机都运行一个客户操作系统、一个应用程序或一组应用程序。

优点:

  • 很好地利用资源
  • 易于扩展
  • 易于备份和迁移
  • 成本效益
  • 灵活性

缺点:

  • 资源分配有问题
  • 供应商锁定
  • 复杂配置

3) 容器设置与其他堆叠的关键区别在于基于容器的虚拟化使用主机操作系统的内核来运行多个隔离的客户实例。这些客户实例称为容器。主机可以是物理服务器或VM。

优点:

  • 隔离性
  • 轻量级
  • 资源有效
  • 易于迁移
  • 安全性
  • 低开销
  • 镜像生产和开发环境

缺点:

  • 相同的架构
  • 资源密集型应用程序
  • 网络和安全问题。

通过将容器设置与其前身进行比较,我们可以得出结论,容器化是到目前为止最快、最有效的、最安全的设置。容器是运行应用程序的隔离实例。Docker会以一种方式启动容器,使图层在默认存储驱动程序(覆盖驱动程序)中获得运行时内存,这些驱动程序在几秒钟内运行并创建写时复制层,一旦我们提交到容器中,它就会生成执行容器的电力。对于虚拟机,这将需要约一分钟才能将一切加载到虚拟化环境中。这些轻量级实例可以轻松替换、重建和移动。这使我们能够镜像生产和开发环境,并在CI/CD过程中提供极大的帮助。容器可以提供的优势是如此令人信服,以至于它们肯定会留下来。


请说明为什么这种设置相比虚拟机应该是“最安全的设置”。 - MKesper
@MKesper:当您从传统环境迁移到容器环境时,有多种方式来构建安全范式,其中一种是基于主动而非被动的方法来防止入侵。它允许您在更细粒度和细致的级别上保护应用程序和运行时。它们还赋予您能力,在干扰工作流程之前识别和解决潜在的安全威胁。并且,可以将静态分析与机器学习相结合,以自动化运行时防御并在整个环境中执行策略。因此,这是“最安全的设置”一词的由来。 - mohan08p

32

关于:

“为什么将软件部署到Docker镜像比部署到一致的生产环境更容易?”

大多数软件都部署到许多环境中,通常至少需要以下三个环境:

  1. 个人开发者PC
  2. 共享开发环境
  3. 个人测试者PC
  4. 共享测试环境
  5. QA环境
  6. UAT环境
  7. 负载/性能测试
  8. 现场预备环境
  9. 生产
  10. 存档

还有以下因素需要考虑:

  • 由于工作的本质,开发人员和测试人员的PC配置可能会略微或极大地不同
  • 开发人员经常可以在超出公司或业务标准化规则控制范围之外的PC上进行开发(例如在自己的机器上远程开发的自由职业者或对开源项目做出贡献但未被“雇用”或“承包”以某种方式配置其PC)
  • 某些环境将由多个机器的固定数量组成,处于负载均衡配置
  • 许多生产环境将拥有基于云的服务器,根据流量水平动态(或“弹性”)创建和销毁

正如您所看到的,组织的总服务器数量很少是单个数字,通常是三位数甚至更高。

这就意味着即使在一个绿野场景下,由于数量上的原因,创建一致的环境已经足够困难,但是考虑到服务器数量众多、新服务器的添加(动态或手动)、来自操作系统供应商、反病毒软件供应商、浏览器供应商等的自动更新,以及由开发人员或服务器技术人员执行的手动软件安装或配置更改等,保持它们的一致性几乎是不可能的。让我重申一下 - 保持环境一致几乎是不可能的(好吧,对于纯粹主义者来说,这可以做到,但它涉及巨大的时间、精力和纪律,这正是为什么虚拟机和容器(例如Docker)首先被设计出来的原因)。
所以请将你的问题看作是:“鉴于保持所有环境的一致性极其困难,是否更容易将软件部署到Docker镜像中,即使考虑到学习曲线?” 我认为你会发现答案肯定是“是”的 - 但只有通过在Stack Overflow上发布这个新问题才能找到答案。

那么,如果我使用15个不同的操作系统/版本组合来部署我的Docker镜像,所有的Docker镜像都会运行相同吗? - Teoman shipahi
@Teomanshipahi 如果所有这些容器都可以使用由主机提供的相同内核,那么它们都将成功运行。 - Light.G
如果我在本地使用Windows上的Docker,那么我能否以同样的方式在Linux/Mac上部署和运行? - Teoman shipahi
经常被忽视的问题是版本依赖性:1)开发人员必须在与映像相同的环境中进行开发;2)开发环境和测试环境需要运行相同(或兼容)版本的Linux内核和Docker本身...对吗? - Bogatyr

26

有许多答案更详细地解释了两者之间的区别,但这是我非常简短的解释。

一个重要的区别是VM使用单独的内核来运行操作系统。这就是它沉重,启动时间长,消耗更多的系统资源的原因。

Docker中的容器与主机共享内核,因此它很轻便,可以快速启动和停止。

在虚拟化中,资源在设置开始时分配,因此当虚拟机在许多时间处于空闲状态时,资源没有完全利用。在Docker中,容器不会被分配固定数量的硬件资源,根据需要自由使用资源,因此它具有高度可伸缩性。

Docker使用UNION文件系统 .. Docker使用写时复制技术来减少容器消耗的内存空间。在这里阅读更多内容


1
在虚拟化中,资源在设置开始时分配,因此当虚拟机在许多时间处于空闲状态时,资源并未完全利用。Hyper-V具有动态内存的概念,您可以指定最小、最大和启动RAM。 - Mariusz

26

使用虚拟机,我们有一个服务器,上面有一个宿主操作系统,然后还有一个超级监视器。在这个超级监视器之上运行,我们可以在该服务器上放置许多客户操作系统及其应用程序和相关的二进制文件和库。这使得整个客户操作系统变得非常笨重。此外,在每台物理机器上实际上可以安装的内容也存在一定限制。

输入图片说明

另一方面,Docker容器有所不同。我们有服务器和宿主操作系统。但是,不再需要超级监视器,而是使用Docker引擎。在这种情况下,我们没有带来整个客户操作系统,只带了一个非常薄的操作系统层,并且容器可以通过与宿主操作系统通信以获取内核功能。这使得容器非常轻量级。

容器中只包含应用程序代码以及其所需的任何二进制文件和库。如果需要,这些二进制文件和库可以在不同的容器之间共享。通过这种方式,我们能够实现许多功能。它们有更快的启动时间。你不能像那样在几秒钟内启动单个虚拟机。同样,关闭也很快。因此,我们可以快速地扩展和缩小规模,稍后我们将看到这一点。

输入图片描述

每个容器都认为自己正在运行自己的操作系统副本。它有自己的文件系统、注册表等,这是一种谎言。它实际上是被虚拟化了。


21

虚拟机中应用程序使用CPU和容器的差异

来源:《Kubernetes实战》。


19

我在生产环境和测试环境中广泛使用了Docker。当您熟悉它后,您会发现它非常强大,可以构建多个容器和隔离的环境。

Docker是基于LXC(Linux容器)开发的,并且在许多Linux发行版中表现完美,特别是Ubuntu。

Docker容器是隔离的环境。当您在从Docker镜像创建的Docker容器中发出 top 命令时,您可以看到它。

此外,由于dockerFile配置,它们非常轻巧和灵活。

例如,您可以创建一个Docker镜像并配置DockerFile,告诉它例如运行时wget 'this',apt-get 'that',run 'some shell script',设置环境变量等。

在微服务项目和架构中,Docker是非常有价值的资产。您可以通过Docker、Docker swarm、Kubernetes和Docker Compose实现可扩展性、弹性和弹性。

关于Docker的另一个重要问题是Docker Hub及其社区。 例如,我使用Prometheus、Grafana、Prometheus-JMX-Exporter和Docker实现了监控kafka的生态系统。

为了做到这一点,我下载了配置好的zookeeper、kafka、Prometheus、Grafana和jmx-collector的Docker容器,然后使用YAML文件挂载了自己的一些配置,或者对其他文件和配置进行了更改,并且构建了一个完整的kafka监控系统,使用多个容器的Dockers在单台机器上实现了隔离、可扩展性和弹性,这种架构可以轻松地移动到多台服务器。

除了Docker Hub网站外,还有另一个名为quay.io的站点,您可以在那里拥有自己的Docker镜像仪表板并从中拉取/推送。您甚至可以将Docker镜像从Docker Hub导入到quay,然后在自己的机器上从quay运行它们。

注意:学习Docker初看起来很复杂和困难,但当您熟悉它后,就无法离开它。

我记得第一次使用Docker时,发出错误命令或错误删除容器及其所有数据和配置的那些日子。


10
这是Docker自我介绍的方式:
Docker是推动容器运动的公司,也是唯一一个跨混合云解决方案提供商,以满足各种应用需求。今天的企业面临着数字转型的压力,但受制于现有的应用程序和基础设施,同时还要合理化日益多样化的云、数据中心和应用架构组合。Docker实现了应用程序和基础设施之间的真正独立性,使开发人员和IT运营人员能够释放其潜力,并创造出更好的协作和创新模式。
因此,Docker是基于容器的,意味着您可以在当前机器上运行镜像和容器。它不像VM那样包含操作系统,而是像Java、Tomcat等不同工作包的集合。
如果您理解容器,您就会了解Docker是什么,以及它与VM有何不同...
那么,什么是容器?
一个容器镜像是一个轻量级、独立的可执行软件包,包含运行所需的所有内容:代码、运行时、系统工具、系统库和设置。适用于Linux和Windows应用程序,容器化软件始终以相同方式运行,无论环境如何。容器将软件与其环境隔离开来,例如在开发和暂存环境之间的差异,并有助于减少在同一基础设施上运行不同软件的团队之间的冲突。

Docker

正如您在下面的图片中所看到的那样,每个容器都有一个单独的包,并在单台机器上运行,共享该机器的操作系统...它们是安全且易于传输的...


10
这里有很多关于虚拟机和容器之间差异以及Docker起源的技术性答案。
对我来说,虚拟机和Docker的根本区别在于如何管理应用程序的推广。
使用虚拟机,您可以将应用程序及其依赖项从一个VM推广到下一个DEV,UAT和PRD。
1.通常这些VM的补丁和库不同。 2.多个应用程序共享VM并需要为所有应用程序管理配置和依赖项。 3.回退需要撤消VM中的更改。或者尽可能恢复它。
使用Docker,您可以将应用程序及其所需的库捆绑在自己的容器中,然后将整个容器作为单个单元进行推广。
1.除了内核外,补丁和库是相同的。 2.通常每个容器只有一个应用程序,这简化了配置。 3.回退包括停止和删除容器。
因此,在最基本的水平上,使用虚拟机推广应用程序及其依赖项是离散组件,而使用Docker则是一次性推广所有内容。
是的,容器存在问题,包括管理它们,但Kubernetes或Docker Swarm等工具大大简化了任务。

8
功能 虚拟机器 (Docker)容器
操作系统(OS) 每个虚拟机 都包含 一个操作系统。 每个 Docker 容器不包含操作系统。
硬件(H/W) 每个虚拟机都包含操作系统所需的硬件的虚拟副本。 容器没有硬件虚拟化,轻量级且快速。
重量 虚拟机很重—原因如上所述— 容器则是轻量级的,因此运行速度更快。
所需软件 虚拟化使用称为 hypervisor 的软件实现。 容器使用称为 Docker 的软件实现容器化。
核心 虚拟机提供虚拟硬件(或可安装操作系统和其他程序的硬件)。 Docker 容器不使用硬件虚拟化。**这有助于使用容器。
抽象化 虚拟机提供硬件抽象化,因此您可以运行多个操作系统。 容器提供操作系统抽象化,因此您可以运行多个容器。
启动时间 创建虚拟机需要很长时间(通常数分钟),并且占用显著的资源开销,因为它们在要使用的软件之外还运行整个操作系统。 启动时间较短,因为在Docker容器中运行的程序直接与主机的Linux内核交互。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接