为什么Docker需要从Dockerfile创建镜像然后再从镜像创建容器,而不是直接从Dockerfile创建容器?

4
为什么Docker需要从Dockerfile创建镜像,然后再从镜像创建容器,而不是直接从Dockerfile创建容器?
先从Dockerfile创建镜像,然后再从该镜像创建容器的目的/好处是什么?

一张图片可能包含多个图层,您可以自定义这些图层。但是容器不支持此功能。 - Mohammad
1
但我也可以自定义我的Dockerfile吗? - YulePale
1
可能是什么是Docker镜像和容器之间的区别?的重复问题。 - k0pernikus
如果没有镜像,每次需要运行容器时都必须重新构建Dockerfile。想一想,你会得出结论,你需要某些东西来保留在Dockerfile中定义的内容。而那个东西就叫做Docker镜像。 - leopal
3个回答

4
  • Dockerfile 是创建镜像的配方
  • 镜像是一个虚拟文件系统
  • 容器是在主机上运行的进程

你不希望每台主机都根据配方构建自己的镜像。对于一些主机来说,下载镜像并进行操作更容易。

创建镜像可能非常昂贵。我有复杂的 Dockerfile,可能需要几个小时才能构建,可能会下载 50 GB 的数据,但最终只会创建一个 200 MB 的镜像,我可以将其发送到不同的主机。

从现有镜像中启动容器非常便宜。

如果你只有 Dockerfile 来启动镜像-容器,整个工作流程将变得非常繁琐。


什么是虚拟文件系统?我在网上查过,但定义对我来说很难理解。 - YulePale
虚拟文件系统是否字面意思上就是一个虚拟的文件系统(类似于此处描述的)? - YulePale
因此,图像的一个目的是通过保存它来避免服务器执行昂贵的任务,以免每次都需要构建图像吗? - YulePale
@YulePale,我不太明白你所说的“每次构建”的意思。这取决于你的使用情况。有些工具镜像的图像可以保持数年的稳定性,而其他镜像则需要在每次部署时重新构建。Docker 的工作流程是:构建镜像,将其发布到(私有或公共)注册表中,在其他镜像中依赖这些镜像和/或在云中将其作为容器启动和/或在本地运行以进行开发。 - k0pernikus
1
那么,如果创建图像不太昂贵,我们可以直接使用Dockerfile创建容器,而不是创建、推送,然后再拉取图像?好处是:我们不需要使用Docker注册表。在撰写此评论时,我得出结论,这就像每次需要使用应用程序时从源代码编译应用程序,而不是使用准备好的exe文件。这将是过度的。 - raV720

1
您可以把Images和Containers类比于Classes和Objects或者Definition和Instance。Image包含用于创建Container的文件系统和默认设置。而Container则包含了特定实例的设置,以及运行时的命名空间和进程。
为什么要将它们分离呢?因为这样可以提高效率和可移植性。由于我们有了独立的镜像,我们也就有了继承,其中一个镜像可以扩展另一个镜像。这种继承的关键细节在于,镜像中的文件系统层并不会为每个镜像都复制一遍。这些层是静态的,您可以通过创建具有新层的新镜像来使用它们。使用覆盖文件系统(或其他联合文件系统驱动程序)我们可以将附加更改附加到该文件系统上,从而创建新的镜像。当Container运行镜像时也是这样。这意味着您可以使用1 Gig的基础镜像,扩展它以获得100兆字节的更改的子镜像,并运行5个容器,每个容器写入1兆字节的文件,Docker主机上使用的总磁盘空间仅为1.105 Gigs而不是7.6 Gigs。
使用注册表(例如Docker Hub)时,可移植性部分发挥作用。镜像是容器的通用、可重用和可传输部分。它不与任何主机上的实例相关联。因此,您可以推送和拉取镜像,但容器紧密绑定到它们正在运行的主机、该主机上的命名卷、在该主机上定义的网络等。

1

图片和容器是两个不同的概念。

基本上,图片就像文件系统的快照,以及一些元数据。

容器是实际运行的几个进程之一(基于图像)。一旦进程结束,您的容器就不存在了(确切地说,它停止了)。

您可以将图像视为您将使容器运行的基础。

因此,您的Dockerfile将创建一个图像(静态),您可以将其存储在本地或推送到存储库中,以便以后使用。

容器不能被“存储”,因为它是一个“活”的东西。


1
谢谢。但我困惑的是为什么我需要图像。为什么不直接从Dockerfiles创建容器呢? - YulePale
2
把容器看作一个进程。为了能够运行这个进程,你需要首先为它创建一个环境(完整的文件系统、环境变量、用户等)。这就是镜像的作用所在。 - Orabîg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接