【问题标题】:docker container does not need an OS, but each container has one. Why?docker 容器不需要操作系统,但每个容器都有一个。为什么?
【发布时间】:2017-07-18 21:33:05
【问题描述】:

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

文档的介绍部分 (https://docs.docker.com/get-started/#a-brief-explanation-of-containers) 内容如下:

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

宾果!这就是区别。容器直接运行在托管操作系统的内核上,这就是为什么它们如此轻量和快速(加上它们提供进程隔离和 docker hub 形式的良好分布机制,这与容器相互连接的能力很好) .

但请稍等。我可以使用 docker 在 Windows 上运行 Linux 应用程序 - 怎么可能?当然,有一些虚拟机。否则我们就无法完成工作......

好的,但是当我们在 Linux 主机上工作时会是什么样子???真正的混乱来了……仍然有人将操作系统定义为我们想要创建的每个映像的基础映像。即使我们说“从头开始” - 从头开始​​仍然是一些极简内核......所以来了

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

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

问题2:如果我运行两个容器,这两个容器的图像都基于同一个父图像,这个父图像会只加载到内存中一次吗?每个容器会有一个虚拟机,还是只有一个虚拟机运行两个容器?如果我们使用不同的操作系统呢?

第三个问题比较靠谱:

问题 3:是否有一些资源,描述了这类事情......因为大多数讨论 docker 的文章只是告诉“它太酷了,你一定要使用 ut . 只需运行一个命令就可以开心了”...这并没有过多解释。

谢谢。

【问题讨论】:

  • 感谢您的链接(这是对问题 3 的直接回答,对于问题 1 和问题 2 是隐含的)。总结问题 1 和 2 的答案:似乎在 Linux 上没有 VM。相反,Linux 内核是共享的,并且使用分层 FS 可以在其之上逐步构建(此时我对使用共享相同内核的不同发行版的可能性感到困惑)......
  • 两个后续问题: 1、内核版本匹配是怎么做的?如果我在没有最新内核的主机上运行 docker,然后尝试在那里运行使用最新 kerenl 功能的软件,会发生什么? 2.问题2(来自原始问题)对于windows仍然有效:有多少VM实例正在运行?是所有 Docker 容器的单个实例还是每个容器的新 VM 实例?
  • @DmitriiSemikin 1. 它会坏掉;它在较旧的内核上运行。 2. 一般情况下,所有容器都是一个VM实例。
  • @DmitriiSemikin 实际上,我已经编辑了我的答案,以包含对您后续问题的更详细的答案。但是最好编辑您的问题以包含后续问题,这样人们就不会错过它们。

标签: docker


【解决方案1】:

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

您可以通过在容器中启动一个进程并在容器外执行ps 来亲自看到这一点;您将在主机的所有进程列表中看到该进程。但是,在容器化进程中运行 ps 将只显示该容器中的进程;限制系统上进程的视图是容器化提供的便利之一。

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

回答您的具体问题:

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

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

  3. 1234563过程看到。对于与此直接相关的阅读材料,我没有任何其他特别的建议,但我认为这可能有助于了解进程和各种其他系统如何在一般的 Unix 和 POSIX 系统上工作的技术细节,因为理解这会给你背景了解容器化做了哪些事情。或许从了解 chroot(2) 系统调用并对其进行一些编程(或者甚至玩弄 chroot(8) 程序)开始;这将为您提供一个实际的动手示例,说明如何在某个特定领域进行容器化。

后续问题:

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

  2. Windows 和 Macintosh 系统不能直接运行 Linux 容器,因为它们不是具有适当设施的 Linux 内核,甚至无法运行 Linux 程序,更不用说支持相同的额外 cgroup 设施了。因此,当您在这些设备上安装 Docker 时,通常它会安装一个 Linux 虚拟机来运行容器。它几乎总是只安装一个 VM 并在该 VM 中运行所有容器;否则将浪费资源而没有任何好处。 (实际上,如上所述,能够拥有多个不同的内核版本可能会有好处。)

【讨论】:

    【解决方案2】:

    Docker 在其容器中没有操作系统。简单来说,一个 docker 容器镜像只是具有容器镜像所依赖的 linux-image 的一种文件系统快照。

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

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

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

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

    希望这会有所帮助。

    【讨论】:

    • 错了! Docker 也可以在不是 linux 的 windows 上运行。因此,主机操作系统也可以是 Windows。
    • 抱歉,您在完全不同的上下文中说“错误”。是的,它在 Windows 主机上运行,​​但问题是它是否有一个操作系统在容器内运行,而不是在容器外运行。您能否检查上面答案中提供的链接?它可能会帮助你。该链接会将您重定向到我发布的另一个答案。我只是提供了链接,而不是在此处粘贴答案以避免重复。
    • 阅读本文中的 docker 容器部分。只有 3 段,arxiv.org/pdf/1501.02967.pdf
    • @dpaks 要在 Windows 上运行 Docker,您必须首先安装适用于 Linux (WSL) 的 Windows 子系统。
    【解决方案3】:

    自从我发布这个问题以来已经很长时间了,但似乎它仍然受到点击......所以我决定回答它 - 实际上主要是标题中的问题(文本中的问题是Curt J. Sampson 仔细回答)。

    那么,“主要”问题的讨论:如果容器不是虚拟机,那么我们为什么需要虚拟机呢?

    正如你可能猜到的,我在 windows 上工作(在 Linux 上这个问题不会出现,因为在 Linux 上不需要用于 docker 的虚拟机)。

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

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

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

    【讨论】:

    • 感谢您的回答。 F.e.当我想要一个带有 postgreSQL 的 docker 时,dockerfile 总是有一个带有 debian 或 alpine 的 FROM。所以它使用的是 Linux 操作系统,并且没有在主机的操作系统/内核上运行!它可能比运行完整的 VM 更快,但显然比本地安装和运行 postgreSQL 慢得多。好吧...“容器化软件将始终以相同的方式运行,无论基础架构如何”,但它不会在主机的操作系统/内核上运行!后者可能是您首先选择 docker 或容器的最大原因之一。
    • @MattiVM:如果你想在基于 linux 的容器中使用 Docker(几乎总是这样),那么你应该使用 Linux 主机,然后使用容器 do使用主机操作系统的资源。在我看来,在 Windows(尤其是非服务器)上使用 Docker 对开发或尝试某些技术很有用。除此之外,如果你想在生产中拥有真正高性能的数据库,那么你不应该使用 Docker,而应该使用专用的 Linux 服务器,它的唯一目的是运行你的数据库。
    • @MattiVM:另一方面:正如上面所讨论的,Docker 非常适合在没有太多开销的情况下对环境进行沙箱化。即使它在 VM 中运行(如在 Windows 中),它仍然是正确的。例如。如果你想在同一台主机上运行多个容器,那么你只需要一个虚拟机——你可以运行里面的所有容器。如果您尝试使用虚拟机进行安排,您最终将需要单独的虚拟机来重新放置每个“容器”,这会占用大量资源。
    • @DmitriiSemikin,最好的答案之一,基本上清除了 docker 如何在非 Linux 内核(Mac、Windows)上运行!
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-31
      • 1970-01-01
      • 2019-09-27
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多