社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

VM的Guesto和Docker的Basic Image有什么区别?

David kim • 3 年前 • 1722 次点击  

我一直在重读 the Docker documentation 试图理解Docker和完整VM之间的区别。它是如何提供一个完整的文件系统、隔离的网络环境等而又不至于如此沉重的呢?

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

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/128934
 
1722 次点击  
文章 [ 22 ]  |  最新文章 3 年前
Boann Shital Shah
Reply   •   1 楼
Boann Shital Shah    4 年前

了解虚拟化和容器如何在较低级别上工作可能会有所帮助。这会让很多事情变得明朗。

注意:我在下面的描述中做了一些简化。更多信息请参见参考资料。

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

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

其最终效果是,虚拟化允许您在同一硬件上运行两个完全不同的操作系统。每个来宾操作系统都会经历引导、加载内核等所有过程。您可以拥有非常严格的安全性。例如,来宾操作系统无法完全访问主机操作系统或其他来宾操作系统,从而导致事情变得一团糟。

容器如何在低水平下工作?

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

容器和虚拟机的局限性现在应该很明显:不能像虚拟机那样在容器中运行完全不同的操作系统。不管你 可以 运行不同的Linux发行版,因为它们共享同一个内核。隔离级别没有VM中的隔离级别强。事实上,在早期的实现中,有一种方法可以让“来宾”容器接管主机。你还可以看到,当你加载一个新的容器时,操作系统的一个全新副本并不像在虚拟机中那样启动。所有容器 share the same kernel

Hassan Ahmed Touraj Ebrahimi
Reply   •   2 楼
Hassan Ahmed Touraj Ebrahimi    5 年前

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

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

假设你有一个1GB的容器图像;如果你想使用一个完整的虚拟机,你需要有1GB x数量的虚拟机。使用Docker和AuFS,您可以在所有容器之间共享1GB的大部分空间,如果您有1000个容器,您可能仍然只有略多于1GB的空间用于容器操作系统(假设它们都运行相同的操作系统映像)。

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

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

每种类型的虚拟化系统都有其优缺点。如果你想在保证资源的情况下实现完全隔离,那么一个完整的虚拟机就是最好的选择。如果您只是想将进程彼此隔离开来,并想在一台大小合理的主机上运行大量进程,那么Docker/LXC/runC似乎是一个不错的选择。

有关更多信息,请查看 this set of blog posts 这很好地解释了LXC的工作原理。

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

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

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

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

从评论中。。。

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

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