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

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


当前回答

通过这篇文章,我们将描绘虚拟机和LXC之间的一些区别。让我们先定义它们。

VM:

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

在此上下文中,VM称为来宾,而其运行的环境称为主机。

LXC:

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

现在,除非你被艾伦(Zach Galifianakis,来自《宿醉》系列)麻醉,并在拉斯维加斯呆了一年,否则你会非常清楚Linux容器技术的巨大兴趣,如果我具体说一下,在过去几个月里在世界各地引起轰动的一个容器项目是Docker,它引发了一些回响,认为云计算环境应该放弃虚拟机(VM),并将其替换为容器,因为它们的开销更低,性能可能更好。

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

a.LXC的作用域是Linux的一个实例。它可能是不同风格的Linux(例如CentOS主机上的Ubuntu容器,但它仍然是Linux。)类似地,如果我们查看VM,基于Windows的容器现在被限定为Windows的一个实例,它们的范围非常广,并且使用管理程序,您不限于操作系统Linux或Windows。

b.与虚拟机相比,LXC开销低,性能更好。基于LXC技术构建的工具,即Docker,为开发人员提供了运行应用程序的平台,同时也为运营人员提供了一个工具,允许他们在生产服务器或数据中心上部署相同的容器。它试图让运行应用程序、启动和测试应用程序的开发人员与部署该应用程序的操作人员之间的体验无缝衔接,因为这是所有摩擦的所在,DevOps的目的是打破这些孤岛。

因此,最好的方法是云基础设施提供商应该提倡适当使用VM和LXC,因为它们都适合处理特定的工作负载和场景。

到目前为止,放弃虚拟机并不现实。因此,VM和LXC都有各自的存在和重要性。

其他回答

Docker最初使用LinuX Containers(LXC),但后来改用runC(以前称为libcontainer),后者与主机在同一操作系统中运行。这允许它共享大量主机操作系统资源。此外,它使用分层文件系统(AuFS)并管理网络。

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

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

一个完整的虚拟化系统得到了它自己的一组资源分配,并且实现了最小的共享。你得到了更多的隔离,但它更重(需要更多的资源)。使用Docker可以减少隔离,但容器是轻量级的(需要更少的资源)。因此,您可以轻松地在主机上运行数千个容器,而且它甚至不会闪烁。试着用Xen做这件事,除非你有一个非常大的主机,否则我认为这是不可能的。

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

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

有关更多信息,请查看这组博客文章,它们很好地解释了LXC的工作原理。

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

部署一致的生产环境说起来容易做起来难。即使您使用Chef和Puppet等工具,主机和环境之间也总是会有操作系统更新和其他变化。

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

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

来自评论。。。

有趣的我想我仍然对“快照操作系统”的概念感到困惑。如果不制作操作系统的图像,那么如何做到这一点?

好吧,看看我能不能解释一下。您从一个基本图像开始,然后进行更改,并使用docker提交这些更改,然后创建一个图像。此图像仅包含与基础的差异。当你想运行你的镜像时,你也需要基础,它使用一个分层文件系统将你的镜像分层在基础之上:如上所述,Docker使用AuFS。AuFS将不同的层合并在一起,您可以得到所需的内容;你只需要运行它。你可以继续添加越来越多的图像(层),它将继续只保存差异。由于Docker通常基于注册表中的现成图像构建,因此您很少需要自己“快照”整个操作系统。

我喜欢肯·科克伦的回答。

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

对我来说,它正好填补了面向开发人员的工具(如rpm、Debian包、Maven、npm+Git)与操作工具(如Puppet、VMware、Xen)之间的差距,你可以这么说。。。

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

您的问题假定了某种一致的生产环境。但如何保持一致?考虑一些数量(>10)的服务器和应用程序,这是管道中的阶段。

为了保持同步,您将开始使用类似木偶、厨师或您自己的供应脚本、未发布的规则和/或大量文档。。。理论上,服务器可以无限期运行,并保持完全一致和最新。实践无法完全管理服务器的配置,因此存在很大的配置漂移和运行服务器的意外更改空间。

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

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

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

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

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

容器将库和软件包与系统隔离,以便您可以安装相同软件和库的不同版本而不发生冲突。它使用最小的存储空间和内存,使用相同的基本操作系统内核和可用的库几乎没有开销,如果可能的话,差异很小。您可以直接或间接地将硬件暴露给容器,以便可以使用加速(如gpu)进行计算。

在实践中,您可以使用预制容器的docker。您可以安装它们并在一条线上运行它们。安装tensorflow gpu和docker run-it tensorflow gpu一样简单。虽然我没有偶然发现许多lxd(lxc容器)的预制容器,但我发现它们更容易定制,更稳定和性能更好。

容器和VM都可以用来分配负载。但由于容器几乎没有开销,因此容器管理软件专注于创建容器集群,以便您轻松地将它们(从而将负载)分配给金属机器。

真实生活示例:

假设您需要50多种类型的计算环境和50种类型的服务,如mysql、网络托管和基于云的服务(如jenkins和对象存储),并且您有50多种不同的裸机服务器。这是一个典型的学院环境。您需要高效地使用资源,并且需要高可用性。当一台服务器停机时,用户应该不会遇到任何问题。为了解决这个问题,您所做的基本上是在所有服务器上安装所有类型的容器。并将负载分配给所有金属机器。当一种类型的容器需要更多时,可以在一台或多台裸机上自动生成更多容器。因此,许多不同的用户可以连续灵活地使用不同的服务和环境。

在该设置中,假设有100名学生同时使用该系统。其中95人使用服务器进行基本服务,如检查GPA、课程、图书馆数据库等,但其中5人正在进行5种不同类型的工程模拟。您将看到49台裸机服务器完全专用于工程仿真,每台服务器都有5种不同类型的计算容器,每种计算容器都与之相匹配,但与20%的硬件资源使用相平衡。当你为基本任务增加2500名学生时,这将使用所有裸机的5%。其余部分将用于计算。

因此,提供这种灵活性优势的容器最重要的区别特征是:

准备好部署预制容器,几乎没有开销,可快速繁殖具有实时可调整配额

使用.cpu_allowencess、.ram_allowances或直接cgroup。Kubernetes为您提供所有这些服务。在摆弄了docker和lxd之后,你可能想看看它。

资料来源:Kubernetes in Action。

好答案。为了获得容器与VM的图像表示,请查看下面的一个。

来源