为啥 docker 必须从 dockerfile 创建一个镜像,然后从该镜像创建一个容器,而不是从 Dockerfile 创建一个容器?
Posted
技术标签:
【中文标题】为啥 docker 必须从 dockerfile 创建一个镜像,然后从该镜像创建一个容器,而不是从 Dockerfile 创建一个容器?【英文标题】:Why does docker have to create an image from a dockerfile then create a container from the image instead of creating a container from a Dockerfile?为什么 docker 必须从 dockerfile 创建一个镜像,然后从该镜像创建一个容器,而不是从 Dockerfile 创建一个容器? 【发布时间】:2020-03-10 11:28:28 【问题描述】:为什么 docker 必须从 dockerfile 创建一个镜像,然后从该镜像创建一个容器,而不是直接从 Dockerfile 创建一个容器?
首先从 Dockerfile 创建映像然后再创建容器的目的/好处是什么?
-----编辑-----
这个问题What is the difference between a Docker image and a container? 没有回答我的问题。
我的问题是:为什么我们需要从图像而不是 dockerfile 创建容器?首先从 Dockerfile 创建镜像然后再从该镜像创建容器的目的/好处是什么?
【问题讨论】:
一张图片可能包含多个图层,您可以自定义这些图层。这对于容器是不可能的。 但是我也可以自定义我的 Dockerfile? What is the difference between a Docker image and a container?的可能重复 如果没有镜像,任何时候你需要运行一个容器,你都应该重新构建 dockerfile。想想看,你会得出结论,你需要一些东西来持久化 dockerfile 中定义的内容。那个东西叫做 docker image。 【参考方案1】: Dockerfile 是创建映像的秘诀 映像是一个虚拟文件系统 容器是主机上正在运行的进程您不希望每个主机都根据配方构建自己的映像。对于某些主机来说,只需下载图像并使用它会更容易。
创建图像可能非常昂贵。我有复杂的 Dockerfile,可能需要数小时才能构建,可能会下载 50 GB 的数据,但仍然只能创建一个 200 MB 的映像,我可以将其发送到不同的主机。
从现有图像启动容器非常便宜。
如果您只有 Dockerfile 来启动镜像容器,那么整个工作流程将变得非常繁琐。
【讨论】:
什么是虚拟文件系统?我在网上查过,但定义对我来说很难理解。 虚拟文件系统从字面上是否意味着虚拟的文件系统(如described here)? 所以图像的目的之一是通过保存每次都必须构建图像来节省服务器中昂贵的任务? @YulePale 我没有遵循您的“每次都构建”评论。这取决于您的用例。有些工具映像的映像可以保持多年稳定,而另一些则必须为每次部署重新构建。 docker 的工作流程是:构建镜像,将它们发布到(私有或公共)注册表中,依赖于其他镜像中的这些镜像和/或将它们作为容器在云中启动和/或在本地运行它们以进行开发。 那么如果创建镜像不贵的话,我们可以直接使用dockerfile创建容器,而不是创建、推送然后拉取镜像吗?好处是:我们不需要使用 docker 注册表。在撰写此评论时,我得出的结论是,每次我们需要使用它而不是使用现成的 exe 文件时,都希望从源代码编译应用程序。这将是矫枉过正。【参考方案2】:图像和容器是两个不同的概念。
基本上,图像就像文件系统的快照,还有一些元数据。
容器是实际运行的多个进程之一(并且基于映像)。一旦进程结束,您的容器就不再存在(好吧,准确地说是停止了)
您可以将映像视为运行容器的基础。
因此,您的 Dockerfile 将创建一个镜像(静态的),您可以将其存储在本地或推送到存储库,以便以后使用。
容器不能被“存储”,因为它是一个“活”的东西。
【讨论】:
谢谢。但我的困惑是为什么我需要图像。为什么不直接从 Dockerfiles 创建容器? 将容器视为一个进程。为了能够运行此进程,您需要首先为其构建一个环境(完整文件系统、环境变量、用户...)。这就是需要图像的地方。【参考方案3】:您可以将图像与容器视为类似于类与对象或定义与实例。该映像包含用于创建容器的文件系统和默认设置。容器包含特定实例的设置,以及运行时的命名空间和运行进程。
至于为什么要将它们分开,效率和可移植性。由于我们有单独的图像,我们也有继承,其中一个图像扩展另一个图像。该继承的关键细节是图像中的文件系统层不会为每个图像复制。这些图层是静态的,您可以通过使用新图层创建新图像来实现它们。使用覆盖文件系统(或其他联合文件系统驱动程序之一),我们可以使用我们的新映像将其他更改附加到该文件系统。容器在运行映像时执行相同的操作。这意味着您可以拥有一个 1 Gig 的基础映像,使用具有 100 Megs 更改的子映像对其进行扩展,并运行 5 个容器,每个容器写入 1 Meg 的文件,而 docker 主机上使用的总磁盘空间仅为 1.105 Gigs 而不是超过 7.6 Gigs。
当您使用注册表时,可移植性部分会发挥作用,例如码头工人中心。图像是容器的通用、可重用和可转移的部分。它不与任何主机上的实例相关联。因此,您可以推送和拉取镜像,但容器与运行它们的主机、该主机上的命名卷、该主机上定义的网络等紧密绑定。
【讨论】:
以上是关于为啥 docker 必须从 dockerfile 创建一个镜像,然后从该镜像创建一个容器,而不是从 Dockerfile 创建一个容器?的主要内容,如果未能解决你的问题,请参考以下文章