docker容器不需要操作系统,但每个容器都有一个。为什么呢?

时间:2017-07-18 21:33:05

标签: docker

“docker”现在是一个流行词,我正在试图找出它是什么以及它是如何工作的。更具体地说,它与普通VM有何不同(例如VirtualBox,HyperV或WMWare解决方案)。

文档的引言部分(https://docs.docker.com/get-started/#a-brief-explanation-of-containers)读取:

  

容器在主机内核上本机运行应用程序。它们比仅通过虚拟机管理程序获得对主机资源的虚拟访问的虚拟机具有更好的性能特征。容器可以获得本机访问,每个访问都在一个独立的进程中运行,不会占用任何其他可执行文件的内存。

宾果!这是区别。容器直接在托管操作系统的内核上运行,这就是为什么它们如此轻量级和快速(加上它们提供隔离的进程和码头中心形状的良好分发机制,这与连接容器的能力相得益彰)

但等一下。我可以使用docker在Windows上运行Linux应用程序 - 它怎么可能?当然,有一些VM。否则我们就不会完成工作......

好的,但是当我们在Linux主机上工作时它看起来怎么样?真正令人困惑的是......我们仍然将操作系统定义为我们想要创建的每个图像的基本图像。即使我们说“从头开始” - 划痕仍然是一些简约的内核......所以这里来了

问题1 :如果我运行,例如CentOS主机,我可以创建容器,它会直接使用这个主机操作系统的内核(而不是VM,包括自己的操作系统)?如果是,我该怎么办?如果不是,为什么docker的文档对我们说谎(因为docker图像总是在某个VM中运行,并且它与其他VM没有太大区别,或者不是吗?)?

经过一番思考并环顾四周后,我想知道,如果对运行图像进行了一些优化。来了

问题2 :如果我运行两个容器,这两个容器的图像都基于相同的父图像,那么这个父图像是否只会加载到内存中一次?每个容器还是只有一个VM,它会运行两个容器吗?如果我们使用不同的操作系统怎么办?

第三个问题被打败了:

问题3 :在某处有一些资源,它描述了这种事情......因为大多数讨论码头工人的文章只是告诉它“它太酷了,你一定要使用ut只需运行一个命令并高兴“......这不能解释太多。

感谢。

4 个答案:

答案 0 :(得分:3)

Docker“容器”不是虚拟机;它们只是在主机系统上运行的常规进程(因此总是在主机的Linux内核上),具有一些特殊配置,可以将它们与系统的其余部分分开。

您可以通过在容器中启动进程并在容器外部执行ps来自行查看;您将在主机的所有进程列表中看到该进程。但是,在容器化过程中运行ps将仅显示该容器中的进程;限制系统进程的观点是集装箱化提供的设施之一。

通常还会为容器提供许多其他系统资源的有限或单独视图,例如文件,网络接口和用户。特别是,容器化进程通常被赋予完全不同的根文件系统和用户集,使其看起来几乎就像在单独的机器上运行一样。 (但事实并非如此;它仍然共享主机的CPU,内存和I / O带宽。)

回答您的具体问题:

  1. 在CentOS(或任何其他系统)上,您创建的所有容器都在使用主机的内核。无法创建使用不同内核的容器;你需要为此启动虚拟机。

  2. 图像只是磁盘上的文件;这些文件以与任何文件相同的方式“加载到内存中”。所以不,对于共享父映像中文件的任何特定磁盘块,内存中永远不会有多个该磁盘块的副本。但是,每个容器在基本图像层上方都有自己的私有“透明”文件系统层,用于处理写入,因此如果更改文件,更改的块将存储在那里,现在将与底层图像分开其他进程(未更改该文件中的任何块)请参阅。

  3. 在Linux中,您可以尝试man cgroupsman cgroup_namespaces获取有关cgroup机制的一些相当技术性的详细信息,这就是Docker(以及Linux上的任何其他容器化方案)用来限制和改变集装箱化过程看到的东西。我对与此直接相关的读数没有任何其他特别的建议,但我认为通常可以帮助学习过程和各种其他系统如何在Unix和POSIX系统上工作的技术细节,因为理解可以为您提供背景知识了解集装箱化的作用。也许从学习chroot(2)系统调用和编程(或者甚至使用chroot(8)程序)开始;这将为您提供一个实用的动手实例,介绍一个特定的集装箱化领域。

  4. 后续问题:

    1. 没有内核版本匹配;只使用一个主机内核。如果容器中的程序不能在该内核的那个版本上运行,那么你就是运气不好。例如,尝试在具有4.19或更高版本内核的Linux系统上运行Docker官方centos:6centos:5容器,当您尝试启动它时,您会看到/bin/bash段错误。内核和用户程序不兼容。如果程序试图使用不在内核中的新设施,它同样会失败。这与在容器外运行相同的二进制文件(程序和共享库!)没什么不同。

    2. Windows和Mac无法运行Linux容器,因为它们不是具有运行Linux程序的适当工具的Linux内核,更不用说支持相同的额外cgroup工具了。因此,当您在这些上安装Docker时,通常会安装一个运行容器的Linux VM。它几乎总是只安装一个VM并运行该VM中的所有容器;否则将是浪费资源而无益。 (实际上,如上所述,能够有几个不同的内核版本可能会有好处。)

答案 1 :(得分:1)

Docker 容器中没有操作系统。简单来说,Docker容器映像仅具有该容器映像所依赖的 linux-image 的一种文件系统快照。

container-image包含一些基本程序,例如bash-shell,vim-editor等,以帮助开发人员轻松使用docker映像。此外,Docker映像可以包含预装的依赖项,例如nodeJS,redis-server等,我们可以在docker hub上找到它们。

幕后的Docker使用主机操作系统(Linux本身)来运行其容器。我们以docker容器形式看到的类似linux的文件系统快照中包含的程序实际上在主机操作系统上独立运行

容器映像听起来像是其他Linux发行版,但它们是这些发行版的文件系统快照。所有Linux发行版均基于同一内核。它们在附带的程序,工具和依赖项上有所不同。

也请注意此评论 [click]。与这个问题非常相关。

希望这会有所帮助。

答案 2 :(得分:1)

如果是Windows,我们需要一个VM在主机上运行docker(这是通过docker工具箱实现的),而在Linux上,我们甚至不需要它。一旦我们拥有一个docker toolbox容器本身就不需要VM,每个容器都有一个基线映像,该映像非常小,并且可以在主机内核中重复使用很多东西,因此与VM相比它是轻量级的。您可以使用单个主机内核运行许多这样的容器。

答案 3 :(得分:0)

我发布这个问题已经很久了,但是似乎它仍然很受欢迎……所以我决定回答这个问题-实际上主要是标题中的问题(文本中的问题是由Curt J. Sampson仔细地回答了。)

因此,讨论“主要”问题:如果容器不是VM,那么为什么我们需要VM?

您可能会猜到,我正在Windows上工作(在Linux上不会出现此问题,因为在Linux上不需要Docker虚拟机)。

原因很明显,为什么我们需要在Winodows中为容器使用虚拟机(也许这就是原因,为什么没有人明确提到它)。正如这里已经提到的,还有许多其他常见问题解答,容器重用了内核以及托管OS的其他资源。考虑到目前可用的大多数容器都是基于Linux的,可能会得出结论,这些容器需要主机OS才能提供Linux内核才能运行。在Windows上这本来就不容易(我不确定,也许现在可以通过Linux子系统实现)。这就是为什么在Windows上需要一个VM的原因,该VM在该VM内运行Linux和docker服务。然后,当我们启动容器时,它们也在虚拟机内部启动(并重用其Linux OS的资源)。所有容器都在同一VM中运行。获得更多技术知识:默认情况下,docker使用Hyper-V运行此linux VM,但也可以使用Docker-Toolbox,后者使用Oracle VirtualBox。顺便说一下,可以在Virtual Box界面中自由查看VM。令人高兴的是Docker(或Docker工具箱)负责管理此VM,我们不需要关心它。

现在有一些奖励问题,那个时候让我更加困惑。有人可能会想:“好,现在很清楚。如果我们在Winodws OS上运行Linux容器,那么我们需要Linux内核,因此需要具有Linux的VM。但是如果我们在Windows上运行Windows容器(顺便说一句,它确实存在),那么就不需要VM,对吧?...”答案:“错”(或几乎错了)。 :)问题是,基于Windows的容器(至少我看到的那些容器)使用Windows服务器内核,例如,该内核不可用。在Windows 10中。因此,仍然需要运行特殊版本Windows Server的VM。实际上,MS甚至创建了Windows Server的特殊版本,该版本可以在VM上免费运行以用于开发目的,专门用于支持基于Windows Server的容器的开发。如果我的理解是正确的,则这些容器应该可以在Windows Server上没有VM的情况下运行。我应该承认,尽管我从未检查过。

我希望这个混乱的解释可以帮助某人更好地理解这个话题。