使用Docker时,我们从一个基础镜像开始。我们启动它,进行更改,这些更改会被保存在不同的层中,形成另一个镜像。
因此,我最终拥有一个用于PostgreSQL实例的镜像和一个用于Web应用程序的镜像,对其进行的更改将继续存在。
什么是容器?
使用Docker时,我们从一个基础镜像开始。我们启动它,进行更改,这些更改会被保存在不同的层中,形成另一个镜像。
因此,我最终拥有一个用于PostgreSQL实例的镜像和一个用于Web应用程序的镜像,对其进行的更改将继续存在。
什么是容器?
docker build -t my_image dir_with_dockerfile
2)将镜像保存到.tar
文件中
docker save -o my_file.tar my_image_id
my_file.tar
将存储镜像。使用tar -xvf my_file.tar
打开它,你将看到所有的层。如果你深入研究每个层,你可以看到每个层中添加了什么变化。(它们应该非常接近Dockerfile中的命令)。sudo docker run -it my_image bash
你会发现它非常类似于一个操作系统。我认为最好在一开始进行解释。
假设你运行命令docker run hello-world
。会发生什么?
它调用Docker CLI,负责接收Docker指令并将其转换为调用Docker服务器指令。一旦Docker服务器收到运行镜像的指令,它就会检查镜像缓存是否拥有该名称的镜像。
假设hello-world不存在。 Docker服务器去Docker Hub(Docker Hub只是一个免费的图像库)询问,嘿Hub,你是否有名为hello-world
的镜像?Hub回答-是的,我有。那请给我它。下载过程开始。一旦Docker镜像下载完成,Docker服务器将其放入镜像缓存中。
因此,在我们解释Docker映像和Docker容器是什么之前,让我们先介绍一下计算机上操作系统及其如何运行软件的工作原理。
当您在计算机上运行Chrome等应用程序时,它会调用操作系统,操作系统本身会调用内核,并询问,嘿,我想运行这个程序。内核可以管理来自硬盘的文件。
现在想象一下,您有两个程序:Chrome和Node.js。 Chrome需要Python版本2才能运行,Node.js需要Python版本3才能运行。如果您只在计算机上安装了Python v2,则只会运行Chrome。
为了使两种情况都能正常工作,您需要以某种方式使用操作系统功能,称为命名空间。命名空间是一种功能,它使您有机会隔离进程、硬盘、网络、用户、主机名等。
因此,当我们谈论镜像时,我们实际上是在谈论文件系统快照。 镜像是一个物理文件,其中包含构建特定容器的指令和元数据。容器本身是镜像的实例;它使用命名空间来隔离硬盘,该命名空间仅适用于此容器。因此,容器是一组资源的进程或集合。
你可以将镜像看作是一个容器的"快照"。
你可以从一个容器中制作镜像(新的"快照"),也可以从镜像中启动新的容器(实例化"快照")。例如,你可以从基础镜像中实例化一个新容器,在容器中运行一些命令,然后将其"快照"为一个新镜像。然后,你可以从该新镜像实例化100个容器。
其他需要考虑的事项:
docker images
时会显示多次。图像相当于面向对象编程中的类定义,而图层则是该类的不同方法和属性。
容器就像对象是类的实例化或实例一样,是图像的实际实例化。
docker images
和containers
之间填补缺失的部分。Docker使用联合文件系统(UFS)来为容器提供支持,它允许多个文件系统被挂载到一个层次结构中并表现为单个文件系统。图像中的文件系统已经被挂载为只读层,对于正在运行的容器进行的任何更改都会被应用于此之上挂载的读写层。因此,Docker只需查看最顶层的读写层以查找对运行系统所做的更改。就像在编程方面一样,
图像就是源代码。
当源代码被编译和构建时,它被称为应用程序。
类似于“当为图像创建实例时”,它被称为“容器”。
一个容器是一个镜像的实例,你可以把它看作是一个运行中的程序,拥有自己独立的硬件资源,因此它有自己的一小部分内存空间、网络技术和硬盘空间。
现在让我们来看一下当您输入以下命令时会发生什么: sudo docker run hello-world
上述命令将启动Docker客户端或Docker CLI。Docker CLI负责接收您的命令,对其进行一些处理,然后将命令发送到称为Docker服务器的东西上。Docker服务器负责处理重要任务。当我们运行Docker run hello-world命令时, 这意味着我们想使用名称为hello world的镜像启动一个新的容器,hello world镜像中有一个微小的程序,其唯一目的是打印出您在终端中看到的消息。
当我们运行该命令并将其发送到Docker服务器时,一系列操作会在后台迅速发生。Docker服务器看到我们正在尝试使用名为“hello world”的映像启动一个新容器。
Docker服务器要做的第一件事是检查它是否已经有本地副本,例如个人计算机上的hello world图像或hello world文件。因此,Docker服务器查看了称为镜像缓存的东西。
现在,由于您和我刚刚在个人计算机上安装了Docker,所以镜像缓存当前为空,我们没有已经下载过的映像。
因此,由于镜像缓存为空,Docker服务器决定向一个名为Docker Hub的免费服务请求。Docker Hub是一个可供您自由下载和在个人计算机上运行的免费公共映像的存储库。因此,Docker服务器联系Docker Hub并下载了hello world文件,并将其存储在图像缓存中,以便在将来某个时间点可以快速重新运行而无需从Docker Hub重新下载它。
接下来,docker服务器将使用它来创建一个容器实例。我们知道,容器是镜像的一个实例,它的唯一目的是运行一个非常特定的程序。因此,docker服务器从镜像缓存中获取了该镜像文件,并将其加载到内存中,创建了一个容器,然后在其中运行了一个单独的程序。这个单独的程序的目的是打印出你看到的消息。我会用以下类比来阐述:
+-----------------------------+-------+-----------+
| Domain | Meta | Concrete |
+-----------------------------+-------+-----------+
| Docker | Image | Container |
| Object oriented programming | Class | Object |
+-----------------------------+-------+-----------+