我一直在重读Docker文档,试图理解Docker和完整VM之间的区别。它是如何设法提供一个完整的文件系统、隔离的网络环境等而不那么沉重的?
为什么将软件部署到Docker映像(如果这是正确的术语)比简单地部署到一致的生产环境更容易?
我一直在重读Docker文档,试图理解Docker和完整VM之间的区别。它是如何设法提供一个完整的文件系统、隔离的网络环境等而不那么沉重的?
为什么将软件部署到Docker映像(如果这是正确的术语)比简单地部署到一致的生产环境更容易?
当前回答
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是轻量级的,使用LXC/libcontainer(它依赖于内核命名空间和cgroups),并且没有机器/硬件仿真,如管理程序、KVM。Xen,它们很重。
Docker和LXC更多地用于沙箱、容器化和资源隔离。它使用主机操作系统(目前只有Linux内核)的克隆API,为IPC、NS(装载)、网络、PID、UTS等提供命名空间。
内存、I/O、CPU等呢。?这是使用cgroups来控制的,在cgroups中,您可以创建具有特定资源(CPU、内存等)规范/限制的组,并将进程放入其中。在LXC之上,Docker提供了一个存储后端(http://www.projectatomic.io/docs/filesystems/)例如,联合安装文件系统,您可以在不同的安装名称空间之间添加层和共享层。
这是一个强大的功能,其中基本映像通常是只读的,只有当容器修改层中的某些内容时,才会将某些内容写入读写分区(也称为写时复制)。它还提供了许多其他包装,如图像的注册和版本控制。
对于普通的LXC,您需要附带一些rootfs或共享rootfs,当共享时,这些更改会反映在其他容器上。由于这些新增功能,Docker比LXC更受欢迎。LXC在嵌入式环境中很受欢迎,用于围绕暴露于外部实体(如网络和UI)的进程实现安全性。Docker在需要一致生产环境的云多租户环境中非常流行。
一个普通的虚拟机(例如VirtualBox和VMware)使用一个虚拟机管理程序,相关技术要么有专用的固件,成为第一个操作系统(主机操作系统或客户操作系统0)的第一层,要么有一个在主机操作系统上运行的软件,为客户操作系统提供硬件仿真,如CPU、USB/附件、内存、网络等。截至2015年,VM在高安全性多租户环境中仍然很受欢迎。
Docker/LXC几乎可以在任何便宜的硬件上运行(只要你有更新的内核,少于1 GB的内存也可以),而正常的VM需要至少2 GB的内存等,才能使用它进行任何有意义的操作。但主机操作系统上的Docker支持在Windows(截至2014年11月)等操作系统中不可用,在Windows、Linux和Mac上可以运行各种类型的VM。
这是docker/rightscale的照片:
Feature |
Virtual Machine |
(Docker) Containers |
---|---|---|
OS | Each VM Does contains an Operating System |
Each Docker Container Does Not contains an Operating System |
H/W | Each VM contain a virtual copy of the hardware that OS requires to run. | There is No virtualization of H/W with containers |
Weight | VM's are heavy -- reason sited above-- | containers are lightweight and, thus, fast |
Required S/W | Virtuliazation achieve using software called a hypervisor | Containerzation achieve using software called a Docker |
Core | Virtual machines provide virtual hardware (or hardware on which an operating system and other programs can be installed) | Docker containers don’t use any hardware virtualization. **It helps to use container |
Abstraction | Virtual machines provide hardware abstractions so you can run multiple operating systems. | Containers provide OS abstractions so you can run multiple containers. |
Boot-Time | It takes a long time (often minutes) to create and require significant resource overhead because they run a whole operating system in addition to the software you want to use. | It takes less time because Programs running inside Docker containers interface directly with the host’s Linux kernel. |
Docker封装了一个应用程序及其所有依赖项。
虚拟机封装了一个OS,该OS可以运行它通常可以在裸机上运行的任何应用程序。
了解虚拟化和容器如何在低级别上工作可能会有所帮助。这将澄清很多事情。
注意:我在下面的描述中简化了一点。有关详细信息,请参阅参考文献。
虚拟化如何在低级别工作?
在这种情况下,VM管理器接管CPU环0(或较新CPU中的“根模式”),并拦截来宾操作系统发出的所有特权调用,以产生来宾操作系统拥有自己硬件的错觉。有趣的事实:在1998年之前,人们认为在x86架构上实现这一点是不可能的,因为没有办法进行这种拦截。VMware的员工是第一个有想法重写内存中的可执行字节以供来宾操作系统的特权调用来实现这一点的人。
其净效果是虚拟化允许您在同一硬件上运行两个完全不同的操作系统。每个来宾操作系统都要经过引导、加载内核等所有过程。例如,来宾操作系统无法完全访问主机操作系统或其他来宾操作系统,从而造成混乱。
容器如何在低液位下工作?
2006年左右,包括谷歌员工在内的一些人实现了一个名为名称空间的新内核级功能(然而,这个想法早就存在于FreeBSD中)。操作系统的一个功能是允许在进程之间共享网络和磁盘等全局资源。如果这些全局资源被包装在命名空间中,以便它们只对在同一命名空间中运行的那些进程可见,该怎么办?例如,您可以获取一块磁盘并将其放在命名空间X中,然后在命名空间Y中运行的进程无法看到或访问它。同样,命名空间X中的进程无法访问分配给命名空间Y的内存中的任何内容。当然,X中的程序无法看到或与命名空间Y中的进程对话。这为全局资源提供了一种虚拟化和隔离。Docker是这样工作的:每个容器都在自己的命名空间中运行,但使用与所有其他容器完全相同的内核。之所以发生隔离,是因为内核知道分配给进程的命名空间,并且在API调用期间,它确保进程只能访问自己命名空间中的资源。
容器与虚拟机的局限性现在应该很明显:你不能像虚拟机那样在容器中运行完全不同的操作系统。但是,您可以运行不同的Linux发行版,因为它们共享相同的内核。隔离级别不如VM中的隔离级别强。事实上,在早期的实现中,“来宾”容器可以接管主机。您还可以看到,当您加载一个新容器时,OS的整个新副本并不像在VM中那样启动。所有容器共享同一内核。这就是为什么集装箱重量轻。与VM不同的是,您不必为容器预先分配大量内存,因为我们没有运行新的OS副本。这允许在一个操作系统上运行数千个容器,同时对它们进行装箱,如果我们在它们自己的VM中运行操作系统的单独副本,这可能是不可能的。
好答案。为了获得容器与VM的图像表示,请查看下面的一个。
来源