首页 文章

Docker与虚拟机有何不同? [关闭]

提问于
浏览
3112

我一直在重读the Docker documentation以试图理解Docker和一个完整的VM之间的区别 . 它如何设法提供完整的文件系统,隔离的网络环境等,而不是那么重?

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

19 回答

  • 51

    Difference between how apps in VM use cpu vs containers

    资料来源:Kubernetes in Action .

  • 2970

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

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

    How virtualization works at low level?

    在这种情况下,VM管理器接管CPU环0(或更新的CPU中的"root mode")并拦截来宾操作系统所做的所有特权调用,以创建客户操作系统具有自己的硬件的错觉 . 有趣的事实:在1998年之前,人们认为在x86架构中无法实现这一点,因为没有办法进行这种拦截 . VMWare were the first的人有一个想法,即在内存中重写可执行字节,以实现对来宾操作系统的特权调用 .

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

    How containers works at low level?

    2006左右,包括Google的一些员工在内的人们实现了名为命名空间的新内核级功能(不过long之前的想法是existed in FreeBSD) . 操作系统的一个功能是允许将全局资源(如网络和磁盘)共享到进程 . 如果将这些全局资源包装在命名空间中,以使它们仅对在同一命名空间中运行的那些进程可见,该怎么办?比如说,你可以获得一大块磁盘并将其放入命名空间X中,然后在命名空间Y中运行的进程可以访问分配给命名空间Y的内存中的任何内容 . 当然,X中的进程无法查看或与进程通信在命名空间Y中 . 这为全局资源提供了一种虚拟化和隔离 . 这就是docker的工作原理:每个容器都在自己的命名空间中运行,但使用与所有其他容器完全相同的内核 . 发生隔离是因为内核知道分配给进程的命名空间,并且在API调用期间确保进程只能访问其自己的命名空间中的资源 .

    容器与VM的限制现在应该是显而易见的:您不能在VM中的容器中运行完全不同的操作系统 . 但是,您可以运行不同的Linux发行版,因为它们共享相同的内核 . 隔离级别不如VM中那么强 . 事实上,"guest"容器有一种方法可以在早期实现中接管主机 . 您还可以看到,当您加载新容器时,操作系统的整个新副本不会像在VM中那样启动 . 所有容器share same kernel . 这就是容器重量轻的原因 . 与VM不同,您不必为容器预先分配大量内存,因为我们没有运行新的OS副本 . 这样就可以在一个操作系统上运行数千个容器,同时对它们进行沙盒处理,如果我们在自己的VM中运行单独的操作系统副本,这可能是不可能的 .

  • 400

    和---关联:-

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

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

    • 个人开发者个人电脑

    • 共享开发人员环境

    • 个人测试仪PC

    • 共享测试环境

    • QA环境

    • UAT环境

    • 负载/性能测试

    • 实时分期

    • 生产环境

    • 档案

    还有以下因素需要考虑:

    • 开发人员,实际上是测试人员,根据工作的性质,都会有微妙或完全不同的PC配置

    • 开发人员通常可以在不受公司或业务标准化规则控制的PC上进行开发(例如,在自己的机器上(通常是远程)开发的自由职业者或开源项目的贡献者,这些开源项目不是以某种方式配置他们的PC)

    • 某些环境将由负载 balancer 配置中的固定数量的多台计算机组成

    • 许多 生产环境 环境将根据流量级别动态(或'elastically')创建和销毁基于 Cloud 的服务器

    正如您所看到的,组织的外推服务器总数很少以单个数字表示,通常是三位数,并且可以很容易地显着提高 .

    这一切都意味着首先创建一致的环境只是因为数量庞大(即使在绿色领域的情况下),但是 keeping them consistent is all but impossible 给定大量服务器,添加新服务器(动态或手动),自动更新o / s供应商,防病毒供应商,浏览器供应商等,由开发人员或服务器技术人员执行的手动软件安装或配置更改等 . 让我重复一遍 - 实际上(没有双关语)不可能保持环境一致(好吧) ,对于纯粹主义者来说,它可以完成,但它涉及大量的时间,精力和纪律,这正是为什么VM和容器(例如Docker)首先被设计出来的原因 .

    所以想想你的问题更像是"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 ?" . 我认为你只有一种方法可以找到,在Stack Overflow上发布这个新问题 .

  • 150

    有三种不同的设置可以提供堆栈来运行应用程序(这将有助于我们识别容器是什么以及什么使它比其他解决方案更强大):

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

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

    Advantages:

    • 原始资源的利用

    • 隔离

    Disadvantages:

    • 部署时间非常慢

    • 浪费资源

    • 难以扩展

    • 难以迁移

    • 复杂配置

    2) VM stack 由运行操作系统的物理服务器和管理虚拟机,共享资源和网络接口的管理程序组成 . 每个Vm运行客户操作系统,应用程序或应用程序集 .

    Advantages:

    • 善用资源

    • 易于扩展

    • 易于备份和迁移

    • 成本效益

    • 灵活性

    Disadvantages:

    • 资源分配存在问题

    • 供应商锁定

    • 复杂配置

    3) Container Setup ,与其他堆栈的关键区别在于基于容器的虚拟化使用主机操作系统的内核来浏览多个隔离的客户端实例 . 这些客户机实例称为容器 . 主机可以是物理服务器或VM .

    Advantages:

    • 隔离

    • 轻量级

    • 资源有效

    • 易于迁移

    • 安全

    • 低开销

    • 镜像 生产环境 和开发环境

    Disadvantages:

    • 相同的架构

    • 资源繁重的应用程序

    • 网络和安全问题 .

    通过将容器设置与其前身进行比较,我们可以得出结论,容器化是迄今为止我们所知道的最快,最有效,最安全的设置 . 容器是运行应用程序的隔离实例 . 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. 如果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'肯定会留在这里 .

  • 101

    这就是 Docker 自我介绍的方式:

    Docker是推动集装箱运输的公司,也是唯一能够解决混合 Cloud 中每个应用程序的容器平台提供商 . 今天的企业面临数字化转型的压力,但受现有应用和基础设施的限制,同时使日益多元化的产品组合合理化 Cloud ,数据中心和应用程序架构 . Docker实现了应用程序和基础架构之间的真正独立性,开发人员和IT运营商可以发挥其潜力,并创建更好的协作和创新模型 .

    因此 Docker 是基于容器的,这意味着您可以在当前计算机上运行图像和容器 . 它不包括像 VM 这样的操作系统,而是像一堆不同的工作包,如Java,Tomcat等 .

    如果你了解容器,你会得到Docker是什么以及它与 VM 的不同之处......

    那么,什么是容器?

    容器映像是一个轻量级,独立的,可执行的软件包,包含运行它所需的一切:代码,运行时,系统工具,系统库,设置 . 适用于基于Linux和Windows的应用程序,无论环境如何,容器化软件都将始终运行相同 . 容器将软件与周围环境隔离开来,例如开发和登台环境之间的差异,有助于减少在同一基础架构上运行不同软件的团队之间的冲突 .

    因此,如下图所示,每个容器都有一个单独的包,并在一台机器上运行,共享该机器的操作系统......它们安全且易于运输......

  • 25

    好的答案 . 只是为了得到容器与VM的图像表示,请看下面的一个 .

    Source

  • 18

    通过这篇文章,我们将在VM和LXC之间划出一些差异 . 我们先来定义它们 .

    VM

    虚拟机模拟物理计算环境,但是对CPU,内存,硬盘,网络和其他硬件资源的请求由虚拟化层管理,该虚拟化层将这些请求转换为底层物理硬件 .

    在此上下文中,VM被称为Guest,而其运行的环境称为主机 .

    LXC s:

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

    现在,除非你被艾伦(Zach Galifianakis-来自宿醉系列)吸毒,并且去年一直在拉斯维加斯,你会非常清楚Linux容器技术的巨大兴趣,如果我将特定的一个容器最近几个月在全球引起轰动的项目是 - Docker引发了一些人们对 Cloud 计算环境应该放弃虚拟机(VM)的看法,并且由于其较低的开销和可能更好的性能而将其替换为容器 .

    但最重要的问题是,它是可行的吗?它会是明智的吗?

    一个 . LXC的范围限定为Linux的一个实例 . 它可能是Linux的不同风格(例如,CentOS主机上的Ubuntu容器,但它仍然是Linux . )同样,如果我们查看具有相当广泛范围的VM并使用它,基于Windows的容器现在限定为Windows实例 . 虚拟机管理程序您不仅限于操作系统Linux或Windows .

    湾与VM相比,LXC具有低开销并且具有更好的性能 . 工具即 . 构建在LXC技术肩上的Docker为开发人员提供了运行其应用程序的平台,同时为操作人员提供了一个工具,使他们能够在 生产环境 服务器或数据中心部署相同的容器 . 它试图在运行应用程序的开发人员,启动和测试应用程序以及无缝部署该应用程序的操作人员之间进行体验,因为这是所有摩擦所在的地方,DevOps的目的是打破这些孤岛 .

    因此,最好的方法是 Cloud 基础架构提供商应该提倡适当使用VM和LXC,因为它们都适合处理特定的工作负载和方案 .

    放弃虚拟机目前尚不实用 . 因此,VM和LXC都有自己的个体存在和重要性 .

  • 16

    这里的大部分答案都是关于虚拟机的 . 我将在过去几年使用Docker的过程中给你一个回答这个问题的问题 . 就是这样:

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

    现在,让我解释一下这意味着什么 . 虚拟机是他们自己的野兽 . 我想解释Docker将帮助您理解这一点,而不仅仅是解释虚拟机是什么 . 特别是因为这里有很多很好的答案,告诉你当他们说"virtual machine"时究竟是什么意思 . 所以...

    Docker容器只是一个进程(及其子进程),它在主机系统内核中使用cgroups从其余进程中划分出来 . 您可以通过运行 ps aux 实际看到您的Docker容器进程在主持人 . 例如,启动 apache2 "in a container"只是作为主机上的特殊进程启动 apache2 . 它's just been compartmentalized from other processes on the machine. It is important to note that your containers do not exist outside of your containerized process'一生 . 当您的过程死亡时,您的容器会死亡 . 那是因为Docker用您的应用程序替换容器内的 pid 1pid 1 通常是init系统) . 关于 pid 1 的最后一点非常重要 .

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

    Docker中的网络是通过使用以太网桥(在主机上称为 docker0 )和主机上每个容器的虚拟接口来实现的 . 它在 docker0 中创建一个虚拟子网,供您的容器相互通信"between" . 这里有许多网络选项,包括为容器创建自定义子网,以及容器可以直接访问主机网络堆栈的能力 .

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

  • 17

    它们都非常不同 . Docker是轻量级的,使用LXC / libcontainer(它依赖于内核命名空间和cgroup),并且没有机器/硬件仿真,如虚拟机管理程序,KVM . Xen很重 .

    Docker和LXC更适用于沙盒,容器化和资源隔离 . 它使用主机操作系统(目前只有Linux内核)克隆API,为IPC,NS(mount),网络,PID,UTS等提供命名空间 .

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

    这是一个强大的功能,其中基本图像通常是只读的,并且只有当容器修改了图层中的某些内容时,它才会将某些内容写入读写分区(a.k.a. copy on write) . 它还提供了许多其他包装器,例如图像的注册表和版本控制 .

    使用普通的LXC,你需要带一些rootfs或共享rootfs,并在共享时,更改会反映在其他容器上 . 由于这些增加的功能很多,Docker比LXC更受欢迎 . LXC在嵌入式环境中很受欢迎,用于实现暴露于外部实体(如网络和UI)的流程的安全性 . Docker在 Cloud 多租户环境中很受欢迎,预计会有一致的 生产环境 环境 .

    普通VM(例如,VirtualBox和VMware)使用管理程序,相关技术要么具有专用固件,要么成为第一个操作系统(主机操作系统或客户操作系统0)的第一层,要么是在主机操作系统上运行的软件提供硬件对客户操作系统进行仿真,如CPU,USB /配件,内存,网络等 . 在高安全性多租户环境中,虚拟机仍然(截至2015年)流行 .

    Docker / LXC几乎可以运行在任何便宜的硬件上(只要你有更新的内核,只有不到1 GB的内存也可以),而普通的虚拟机需要至少2 GB的内存等,用它来做任何有意义的事情 . 但是主机操作系统上的Docker支持在Windows(截至2014年11月)等操作系统中不可用,因为可以在Windows,Linux和Mac上运行类型的VM .

    这是来自docker / rightscale的照片:

  • 297

    Docker,基本上是容器,支持 OS virtualization ,即您的应用程序认为它具有完整的OS实例,而VM支持 hardware virtualization . 您觉得它是一台物理机器,您可以在其中启动任何操作系统 .

    在Docker中,运行的容器共享主机操作系统内核,而在VM中,它们拥有自己的操作系统文件 . 当您将应用程序部署到各种服务环境(例如“测试”或“ 生产环境 ”)时,开发应用程序的环境(OS)将是相同的 .

    例如,如果您开发在端口4000上运行的Web服务器,当您将其部署到“测试”环境时,该端口已被其他程序使用,因此它将停止工作 . 在容器中有层;您对操作系统所做的所有更改都将保存在一个或多个图层中,并且这些图层将成为图像的一部分,因此无论图像在何处,依赖关系都会存在 .

    在下面显示的示例中,主机有三个VM . 为了使VM中的应用程序完全隔离,它们每个都有自己的OS文件,库和应用程序代码副本,以及OS的完整内存实例 . 而下图显示了与容器相同的情况 . 这里,容器只是共享主机操作系统,包括内核和库,因此它们不需要引导操作系统,加载库或为这些文件支付专用内存成本 . 他们采取的唯一增量空间是任何内存和磁盘应用程序在容器中运行所需的空间 . 虽然应用程序的环境感觉像专用操作系统,但应用程序的部署方式与专用主机一样 . 容器化应用程序在几秒钟内启动,并且应用程序的更多实例可以适应机器而不是VM情况 .

    资料来源:https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/

  • 125

    我喜欢Ken Cochrane的回答 .

    但是我想添加额外的观点,这里没有详细介绍 . 在我看来,Docker在整个过程中也有所不同 . 与VM相比,Docker不仅(仅)关于硬件的最佳资源共享,而且它为打包应用程序提供了一个“系统”(最好,但不是必须的,作为一组微服务) .

    对我而言,它适用于面向开发人员的工具(如rpm,Debian软件包,Maven,npm Git)和ops工具(如Puppet,VMware,Xen)之间的差距,您可以将其命名为......

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

    您的问题假设一些一致的 生产环境 环境 . 但如何保持一致?考虑一些(> 10)服务器和应用程序,管道中的阶段 .

    为了使其保持同步,您将开始使用Puppet,Chef或您自己的配置脚本,未发布的规则和/或大量文档...理论上,服务器可以无限期运行,并保持完全一致和最新 . 实践无法完全管理服务器的配置,因此存在相当大的配置偏差范围,以及对运行的服务器的意外更改 .

    所以有一种已知的模式可以避免这种情况,即所谓的 immutable server . 但是不可变的服务器模式并不受欢迎 . 主要是因为Docker之前使用的VM的局限性 . 处理几千兆字节的大图像,移动那些大图像,只是为了改变应用程序中的某些字段,非常非常费力 . 可以理解的......

    使用Docker生态系统,您永远不需要在“小变化”上移动千兆字节(感谢aufs和Registry),并且您不必担心在运行时将应用程序打包到Docker容器中会导致性能下降 . 您无需担心该图像的版本 .

    最后,即使在Linux笔记本电脑上,您甚至经常能够重现复杂的 生产环境 环境(如果在您的情况下不起作用,请不要打电话给我;))

    当然,您可以在VM中启动Docker容器(这是一个好主意) . 减少VM级别的服务器配置 . 以上所有内容都可以由Docker管理 .

    附:同时Docker使用自己的实现"libcontainer"而不是LXC . 但LXC仍然可以使用 .

  • 66

    1.轻量级

    这可能是许多码头学习者的第一印象 .

    首先,docker镜像通常比VM镜像小,因此易于构建,复制,共享 .

    其次,Docker容器可以在几毫秒内启动,而VM可以在几秒钟内启动 .

    2.分层文件系统

    这是Docker的另一个关键功能 . 图像具有图层,不同的图像可以共享图层,使其更加节省空间并且构建速度更快 .

    如果所有容器都使用Ubuntu作为基本映像,并非每个映像都有自己的文件系统,但是共享相同的下划线ubuntu文件,并且只有它们自己的应用程序数据不同 .

    3.共享操作系统内核

    Think of containers as processes!

    在主机上运行的所有容器确实是一堆具有不同文件系统的进程 . 它们共享相同的操作系统内核,仅封装系统库和依赖项 .

    这对大多数情况都很好(没有额外的操作系统内核维护),但如果容器之间需要严格的隔离,则可能会出现问题 .

    为什么重要?

    所有这些似乎都是改进,而不是革命 . 那么,量化积累会导致质的转变 .

    考虑应用程序部署 . 如果我们要部署新软件(服务)或升级软件(服务),最好更改配置文件和进程,而不是创建新VM . 因为创建具有更新服务的VM,测试它(在Dev&QA之间共享),部署到 生产环境 需要数小时甚至数天 . 如果出现任何问题,你必须重新开始,浪费更多时间 . 因此,使用配置管理工具(puppet,saltstack,chef等)安装新软件,首选下载新文件 .

    说到docker,就不可能使用新创建的docker容器来替换旧的docker容器 . 维护更容易!构建新映像,与QA共享,测试,部署它只需要几分钟(如果一切都是自动化的),在最坏的情况下需要几个小时 . 这称为 immutable infrastructure :不维护(升级)软件,而是创建一个新软件 .

    它改变了服务的交付方式 . 我们需要应用程序,但必须维护VM(这很痛苦,与我们的应用程序关系不大) . Docker让您专注于应用程序并平滑一切 .

  • 8

    我在 生产环境 环境中使用过Docker和非常分阶段 . 当你习惯它时,你会发现它非常强大,可以构建一个多容器和隔离的环境 .

    Docker是基于LXC(Linux容器)开发的,可以在许多Linux发行版中完美运行,尤其是Ubuntu .

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

    除此之外,由于dockerFile配置,它们非常轻巧灵活 .

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

    在微服务项目和架构中,Docker是一种非常可行的资产 . 您可以使用Docker,Docker swarm,Kubernetes和Docker Compose实现可扩展性,弹性和弹性 .

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

    为此,我为zookeeper,kafka,Prometheus,Grafana和jmx-collector下载了已配置的Docker容器,然后使用yml文件为其中一些安装了我自己的配置,或者为了其他我在Docker容器中更改了一些文件和配置,我构建了一个整体系统用于在单台机器上使用多容器Docker监控kafka,具有隔离,可扩展性和弹性,可以轻松地将该架构移动到多个服务器中 .

    除了Docker Hub站点之外,还有另一个名为quay.io的站点,您可以使用它来拥有自己的Docker镜像仪表板并从中拉/推 . 您甚至可以将Docker Hub中的Docker映像导入码头,然后在您自己的计算机上从码头运行它们 .

    注意:首先学习Docker似乎很复杂而且很难,但是当你习惯它时,如果没有它就无法工作 .

    我记得当我发出错误的命令或错误地删除我的容器以及所有数据和配置时,使用Docker的第一天 .

  • 7

    使用 virtual machine ,我们有一台服务器,我们在该服务器上有一个主机操作系统,然后我们有一个虚拟机管理程序 . 然后运行在该虚拟机管理程序之上,我们有任意数量的客户操作系统,其中包含应用程序及其依赖二进制文件,以及该服务器上的库 . 它带来了一个完整的客户操作系统 . 它实际上可以放在每台物理机器上的数量是一个限制 .

    另一方面, Docker containers 略有不同 . 我们有服务器 . 我们有主机操作系统 . 但是 instead a hypervisor ,在这种情况下我们有 Docker engine . 在这种情况下,我们不会带来整个客户操作系统 . We're bringing a very thin layer of the operating system ,容器可以向下进入主机操作系统,以便在那里获得内核功能 . 这使我们拥有一个非常轻量级的容器 .

    它所拥有的只是应用程序代码以及它需要的任何二进制文件和库 . 如果你想要它们,那么这些二进制文件和库实际上可以在不同的容器之间共享 . 这使我们能做的事情有很多 . 他们有 much faster startup time . 你可以稍后再看一下 .

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

  • 4

    Docker封装了一个具有所有依赖关系的应用程序 .

    虚拟器封装了一个可以运行它通常可以在裸机上运行的任何应用程序的操作系统 .

  • 4

    Docker不是虚拟化方法 . 它依赖于实际实现基于容器的虚拟化或操作系统级虚拟化的其他工具 . 为此,Docker最初使用LXC驱动程序,然后转移到libcontainer,现在重命名为runc . Docker主要专注于在应用程序容器内自动部署应用程序 . 应用程序容器旨在打包和运行单个服务,而系统容器则设计为运行多个进程,如虚拟机 . 因此,Docker被视为容器化系统上的容器管理或应用程序部署工具 .

    为了了解它与其他虚拟化的不同之处,让我们来看看虚拟化及其类型 . 然后,更容易理解那里有什么不同 .

    Virtualization

    在其构思形式中,它被认为是逻辑上划分大型机以允许多个应用程序同时运行的方法 . 但是,当公司和开源社区能够以某种方式提供处理特权指令的方法并允许在单个基于x86的系统上同时运行多个操作系统时,场景发生了巨大变化 .

    Hypervisor

    管理程序处理创建虚拟客户虚拟机运行的环境 . 它监督客户系统并确保在必要时为客户分配资源 . 虚拟机管理程序位于物理机和虚拟机之间,并为虚拟机提供虚拟化服务 . 为了实现它,它拦截虚拟机上的客户操作系统操作并模拟主机操作系统上的操作 .

    虚拟化技术的快速发展,主要是在 Cloud 中,通过允许在虚拟机管理程序(如Xen,VMware Player,KVM等)的帮助下在单个物理服务器上创建多个虚拟服务器,进一步推动了虚拟化的使用 . 在商用处理器中加入硬件支持,例如Intel VT和AMD-V .

    Types of Virtualization

    可以基于虚拟化方法如何模仿客户操作系统的硬件并模拟客户操作环境来对虚拟化方法进行分类 . 主要有三种类型的虚拟化:

    • 仿真

    • 半虚拟化

    • 基于容器的虚拟化

    Emulation

    仿真,也称为完全虚拟化,完全在软件中运行虚拟机操作系统内核 . 此类型中使用的管理程序称为Type 2管理程序 . 它安装在主机操作系统的顶部,负责将客户操作系统内核代码转换为软件指令 . 翻译完全由软件完成,无需硬件参与 . 仿真使得可以运行支持所模拟环境的任何未修改的操作系统 . 此类虚拟化的缺点是额外的系统资源开销导致与其他类型的虚拟化相比性能下降 .

    此类别中的示例包括VMware Player,VirtualBox,QEMU,Bochs,Parallels等 .

    Paravirtualization

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

    此类别中的示例包括Xen,KVM等 .

    Container-based Virtualization

    基于容器的虚拟化(也称为操作系统级虚拟化)可在单个操作系统内核中实现多个独立执行 . 它具有最佳的性能和密度,并具有动态资源管理功能 . 此类虚拟化提供的隔离虚拟执行环境称为容器,可以视为一组跟踪的进程 .

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

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

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

    Linux容器有多种管理工具,包括LXC,LXD,systemd-nspawn,lmctfy,Warden,Linux-VServer,OpenVZ,Docker等 .

    Containers vs Virtual Machines

    与虚拟机不同,容器不需要引导操作系统内核,因此可以在不到一秒的时间内创建容器 . 此功能使基于容器的虚拟化比其他虚拟化方法更加独特和可取 .

    由于基于容器的虚拟化为主机增加了很少或没有开销,因此基于容器的虚拟化具有接近本机的性能

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

    主机上的所有容器共享主机的调度程序,从而节省了额外资源的需求 .

    与虚拟机映像相比,容器状态(Docker或LXC映像)的大小很小,因此容器映像很容易分发 .

    资源管理在容器中通过cgroup实现 . Cgroups不允许容器消耗比分配给它们更多的资源 . 但是,截至目前,主机的所有资源都在虚拟机中可见,但无法使用 . 这可以通过在容器和主机上同时运行 tophtop 来实现 . 所有环境的输出看起来都很相似 .

    更新:

    How does Docker run containers in non-Linux systems?

    如果由于Linux内核中可用的功能而可以使用容器,那么显而易见的问题是非Linux系统如何运行容器 . Docker for Mac和Windows都使用Linux VM来运行容器 . Docker Toolbox用于在Virtual Box VM中运行容器 . 但是,最新的Docker在Windows中使用Hyper-V,在Mac中使用Hypervisor.framework .

    现在,让我描述Docker for Mac如何详细运行容器 .

    Docker for Mac使用https://github.com/moby/hyperkit来模拟管理程序功能,Hyperkit在其核心使用hypervisor.framework . Hypervisor.framework是Mac的本机管理程序解决方案 . Hyperkit还分别使用VPNKit和DataKit来命名网络和文件系统 .

    Docker在Mac中运行的Linux VM是只读的 . 但是,你可以运行:

    screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty .

    现在,我们甚至可以检查此VM的内核版本:

    # uname -a Linux linuxkit-025000000001 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:86_64 Linux .

    所有容器都在此VM内运行 .

    hypervisor.framework有一些限制 . 因为Docker不会在Mac中公开 docker0 网络接口 . 因此,您无法从主机访问容器 . 截至目前, docker0 仅在VM内可用 .

    Hyper-v是Windows中的本机管理程序 . 他们还试图利用Windows 10的功能本地运行Linux系统 .

  • 16

    Docker最初使用LinuX Containers(LXC),但后来切换到runC(以前称为 libcontainer ),它在与其主机相同的操作系统中运行 . 这允许它共享许多主机操作系统资源 . 此外,它使用分层文件系统(AuFS)并管理网络 .

    AuFS是一个分层文件系统,因此您可以将只读部分和写入部分合并在一起 . 可以将操作系统的公共部分设置为只读(并在所有容器之间共享),然后为每个容器提供自己的挂载以进行写入 .

    所以,假设你有一个1 GB的容器图像;如果您想使用完整的VM,则需要1 GB x倍的VM数量 . 使用Docker和AuFS,您可以在所有容器之间共享1 GB的大部分,如果您有1000个容器,您仍然可能只有1 GB以上的空间用于容器OS(假设它们都运行相同的OS映像) .

    完整的虚拟化系统可以获得分配给它的自己的资源集,并实现最小的共享 . 你得到更多隔离,但它更重(需要更多资源) . 使用Docker可以减少隔离,但容器很轻(需要的资源更少) . 因此,您可以在主机上轻松运行数千个容器,甚至不会闪烁 . 尝试使用Xen,除非你有一个非常大的主机,我认为这是不可能的 .

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

    每种类型的虚拟化系统都有利弊 . 如果您希望使用有保证的资源进行完全隔离,则可以使用完整的VM . 如果您只想将进程彼此隔离并希望在合理大小的主机上运行大量进程,那么Docker / LXC / runC似乎就是您的选择 .

    有关更多信息,请查看this set of blog posts,它可以很好地解释LXC的工作原理 .

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

    部署一致的 生产环境 环境说起来容易做起来难 . 即使您使用ChefPuppet等工具,也总会有操作系统更新以及其他在主机和环境之间发生变化的事情 .

    Docker使您能够将操作系统快照到共享映像中,并使其易于部署在其他Docker主机上 . 本地,开发,qa,prod等:所有相同的图像 . 当然,你可以使用其他工具,但不是那么容易或快速 .

    这非常适合测试;假设您有数千个需要连接到数据库的测试,每个测试都需要数据库的原始副本,并且会对数据进行更改 . 对此的经典方法是在每次测试后使用自定义代码或使用Flyway等工具重置数据库 - 这可能非常耗时并且意味着测试必须以串行方式运行 . 但是,使用Docker,您可以创建数据库的映像并在每个测试中运行一个实例,然后并行运行所有测试,因为您知道它们都将针对数据库的同一快照运行 . 由于测试是并行运行的,并且在Docker容器中,它们可以同时在同一个盒子上运行并且应该完成快多了 . 尝试使用完整的VM .

    来自评论......

    有趣!我想我仍然对“快照[操作系统”的概念感到困惑 . 如果没有,那么,如何制作操作系统的图像?

    好吧,让我们看看我是否可以解释 . 您从基础映像开始,然后进行更改,并使用docker提交这些更改,并创建一个映像 . 此图像仅包含与基础的差异 . 当您想要运行图像时,您还需要基础,并使用分层文件系统将图像分层在基础之上:如上所述,Docker使用AUFS . AUFS将不同的层合并在一起,就可以得到你想要的东西;你只需要运行它 . 您可以继续添加越来越多的图像(图层),它将继续只保存差异 . 由于Docker通常 Build 在registry的现成图像之上,因此您很少需要自己使用整个操作系统 .

  • 350

    有许多答案可以更详细地解释这些差异,但这是我非常简短的解释 .

    一个重要的区别是 VMs use a separate kernel to run the OS . 这就是它很重的原因,需要时间来启动,消耗更多的系统资源 .

    In Docker, the containers share the kernel 与房东;因此它重量轻,可以快速启动和停止 .

    在虚拟化中,资源在设置开始时分配,因此当虚拟机在许多时间空闲时,资源未被充分利用 . 在Docker中,容器没有分配固定数量的硬件资源,并且可以根据需要自由使用资源,因此具有高度可扩展性 .

    Docker使用 UNION File system .. Docker使用写时复制技术来减少容器占用的内存空间 . Read more here

  • 3

    这里有很多很好的技术答案,清楚地讨论了VM和容器之间的差异以及Docker的起源 .

    对我来说,VM和Docker之间的根本区别在于您如何管理应用程序的推广 .

    使用VM,您可以将应用程序及其依赖项从一个VM升级到下一个DEV到UAT到PRD .

    • 这些VM通常会有不同的补丁和库 .

    • 多个应用程序共享VM的情况并不少见 . 这需要管理所有应用程序的配置和依赖关系 .

    • Backout需要撤消VM中的更改 . 或者尽可能恢复它 .

    使用Docker的想法是,将应用程序与其所需的库一起捆绑在自己的容器中,然后将 whole 容器作为一个单元进行升级 .

    • 除了内核,补丁和库是相同的 .

    • 作为一般规则,每个容器只有一个应用程序,可简化配置 .

    • Backout包括停止和删除容器 .

    因此,在最基本的VM级别,您可以将应用程序及其依赖项作为独立组件进行升级,而使用Docker,您可以在一次命中中提升所有内容 .

    是的,容器存在问题,包括管理它们,尽管像Kubernetes或Docker Swarm这样的工具大大简化了任务 .

相关问题