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

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


当前回答

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

注意:我在下面的描述中简化了一点。有关详细信息,请参阅参考文献。

虚拟化如何在低级别工作?

在这种情况下,VM管理器接管CPU环0(或较新CPU中的“根模式”),并拦截来宾操作系统发出的所有特权调用,以产生来宾操作系统拥有自己硬件的错觉。有趣的事实:在1998年之前,人们认为在x86架构上实现这一点是不可能的,因为没有办法进行这种拦截。VMware的员工是第一个有想法重写内存中的可执行字节以供来宾操作系统的特权调用来实现这一点的人。

其净效果是虚拟化允许您在同一硬件上运行两个完全不同的操作系统。每个来宾操作系统都要经过引导、加载内核等所有过程。例如,来宾操作系统无法完全访问主机操作系统或其他来宾操作系统,从而造成混乱。

容器如何在低液位下工作?

2006年左右,包括谷歌员工在内的一些人实现了一个名为名称空间的新内核级功能(然而,这个想法早就存在于FreeBSD中)。操作系统的一个功能是允许在进程之间共享网络和磁盘等全局资源。如果这些全局资源被包装在命名空间中,以便它们只对在同一命名空间中运行的那些进程可见,该怎么办?例如,您可以获取一块磁盘并将其放在命名空间X中,然后在命名空间Y中运行的进程无法看到或访问它。同样,命名空间X中的进程无法访问分配给命名空间Y的内存中的任何内容。当然,X中的程序无法看到或与命名空间Y中的进程对话。这为全局资源提供了一种虚拟化和隔离。Docker是这样工作的:每个容器都在自己的命名空间中运行,但使用与所有其他容器完全相同的内核。之所以发生隔离,是因为内核知道分配给进程的命名空间,并且在API调用期间,它确保进程只能访问自己命名空间中的资源。

容器与虚拟机的局限性现在应该很明显:你不能像虚拟机那样在容器中运行完全不同的操作系统。但是,您可以运行不同的Linux发行版,因为它们共享相同的内核。隔离级别不如VM中的隔离级别强。事实上,在早期的实现中,“来宾”容器可以接管主机。您还可以看到,当您加载一个新容器时,OS的整个新副本并不像在VM中那样启动。所有容器共享同一内核。这就是为什么集装箱重量轻。与VM不同的是,您不必为容器预先分配大量内存,因为我们没有运行新的OS副本。这允许在一个操作系统上运行数千个容器,同时对它们进行装箱,如果我们在它们自己的VM中运行操作系统的单独副本,这可能是不可能的。

其他回答

Docker封装了一个应用程序及其所有依赖项。

虚拟机封装了一个OS,该OS可以运行它通常可以在裸机上运行的任何应用程序。

1.重量轻

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

首先,docker映像通常比VM映像小,因此易于构建、复制和共享。

第二,Docker容器可以在几毫秒内启动,而VM可以在几秒钟内启动。

2.分层文件系统

这是Docker的另一个关键特性。图像具有图层,不同的图像可以共享图层,从而更节省空间,构建速度更快。

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

3.共享OS内核

将容器视为进程!

在主机上运行的所有容器实际上都是一堆具有不同文件系统的进程。它们共享相同的OS内核,只封装系统库和依赖项。

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

为什么重要?

所有这些似乎都是进步,而不是革命。好吧,数量的积累导致质量的转变。

考虑应用程序部署。如果我们想部署一个新的软件(服务)或升级一个,最好是更改配置文件和进程,而不是创建一个新VM。因为创建一个具有更新服务的VM,测试它(开发人员和QA之间共享),部署到生产需要几个小时,甚至几天。如果出了什么问题,你必须重新开始,浪费更多的时间。因此,使用配置管理工具(木偶、盐堆、厨师等)安装新软件,最好下载新文件。

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

它改变了服务的交付方式。我们需要应用程序,但必须维护VM(这是一个难题,与我们的应用程序无关)。Docker让你专注于应用程序,让一切变得流畅。

在我看来,这取决于你的应用程序的需求,为什么决定部署到Docker,因为Docker根据其功能将应用程序分解为小部分,这变得有效,因为当一个应用程序/功能出现错误时,它对其他应用程序没有影响,与使用完整的vm相比,它的配置会更慢、更复杂,但在某些方面比码头工人更安全

对于虚拟机,我们有一台服务器,在该服务器上有一个主机操作系统,然后我们有一个管理程序。然后在该虚拟机管理程序之上运行,我们在该服务器上有任意数量的来宾操作系统,其中包含应用程序及其从属二进制文件和库。它带来了一个完整的客户操作系统,非常重量级。此外,您可以在每个物理机器上实际投入多少也是有限制的。

另一方面,Docker容器略有不同。我们有服务器。我们有主机操作系统。但在本例中,我们使用的是Docker引擎,而不是管理程序。在这种情况下,我们并没有带来一个完整的客户操作系统。我们带来了一个非常薄的操作系统层,容器可以与主机操作系统进行对话,以获得那里的内核功能。这使得我们可以拥有一个非常轻的容器。

它所包含的只有应用程序代码以及所需的任何二进制文件和库。如果您希望这些二进制文件和库也可以在不同的容器中共享。这使我们能够做的事情有很多。它们的启动时间要快得多。你不能像那样在几秒钟内建立一个虚拟机。同样地,也要尽快地把它们取下来。。所以我们可以很快地放大和缩小,稍后我们将对此进行研究。

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

关于:-

“为什么将软件部署到docker映像比简单部署到一致的生产环境?"

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

个人开发者PC共享开发人员环境单个测试仪PC共享测试环境QA环境UAT环境负载/性能测试实时登台生产档案文件

还需要考虑以下因素:

根据工作的性质,开发人员,甚至测试人员,都将拥有微妙的或完全不同的PC配置开发人员通常可以在公司或企业标准化规则无法控制的PC上进行开发(例如,在自己的机器上开发的自由职业者(通常是远程开发的),或未“受雇”或“签约”以某种方式配置其PC的开源项目的贡献者)某些环境将由负载平衡配置中的固定数量的多台计算机组成许多生产环境将根据流量级别动态(或“弹性”)创建和销毁基于云的服务器

正如你所看到的,一个组织的服务器总数很少是一位数,通常是三位数,而且很容易更高。

这一切都意味着,仅仅因为巨大的容量(即使是在绿地场景中),首先创建一致的环境就已经足够困难了,但鉴于服务器数量众多、新服务器的添加(动态或手动)、o/s供应商、防病毒供应商、浏览器供应商等的自动更新,由开发人员或服务器技术人员执行的手动软件安装或配置更改等。让我重复一遍-保持环境一致几乎是不可能的(没有双关语)(好吧,对于纯粹主义者来说,这是可以做到的,但这需要大量的时间、精力和纪律,这正是为什么VM和容器(例如Docker)最初被设计出来的原因)。

因此,请更像这样思考您的问题:“鉴于保持所有环境一致性的极端困难,即使考虑到学习曲线,将软件部署到docker映像中是否更容易?”。我想你会发现答案总是“是”——但只有一种方法可以找到,在Stack Overflow上发布这个新问题。