深入了解docker的图像和容器。
从左到右,我们看到多个只读层,它们重叠在一起。除了底层,其他层都会有指向下一层的指针。这些层是docker内部的实现细节,可以在主机(运行docker的机器)的文件中访问。union文件系统技术可以将不同的层合并到一个文件系统中,为这些层提供统一的视图,从而隐藏多个层的存在。我们可以在图的右边看到这个透视图的形式。
您可以在您的主机文件系统上找到关于这些层的文件。这些层在运行的容器中是不可见的。在我的主机上,我发现它们存在于/var/lib/docker/image目录中。
容器的定义和图像几乎一样,也是一堆层的统一视觉。唯一的区别是容器的顶层是可读和可写的。
要点:容器=镜像+读/写层
运行容器定义
运行容器被定义为读写统一文件系统加上隔离的进程空间和其中包含的进程。下图显示了运行中的容器。
我们可以通过下面的命令来验证我们所说的内容。
find/-name happy . txt
为了整合分散的数据,我们提出了图像层的概念。下图描述了一个镜像层。通过图片我们可以发现,一个图层不仅包含了文件的变化,还包含了其他重要的信息。
元数据是关于这一层的额外信息,它不仅使Docker能够在运行时和构建时获得信息,还包括父层的层次信息。应当注意,只读层和读写层都包含元数据。
/var/lib/docker/image/overlay2:存储图像管理数据的目录。
一个容器的元数据似乎被分成了许多文件,但是可以在/var/lib/docker/containers/中找到
现在,我们结合上面提到的实现细节来理解Docker命令。
Docker create命令是给指定的图像添加一个可读层,形成一个新的容器。请注意,该容器没有运行。
docker start命令为容器文件系统创建一个进程隔离空间。注意,每个容器只能有一个进程隔离空间。
看到这个命令,读者通常会有一个疑问:docker start和docker run有什么区别?
docker run命令是通过镜像创建一个容器,然后运行该容器。这个命令非常方便,并且隐藏了这两个命令的细节。
docker ps命令列出了所有正在运行的容器。这隐藏了不运行的容器的存在。如果我们想找到这些容器,我们需要使用下面的命令。
docker PS–a命令列出了所有容器,无论它们是正在运行还是已停止。
docker images命令列出所有顶级图像。其实这里没有办法区分镜像和只读层,所以我们提出了顶层镜像。只有创建容器时使用的镜像或者直接下拉的镜像才能称为顶层镜像,每个顶层镜像下隐藏多个镜像层。
docker images–一个命令列出所有图像或所有可读层。如果您想查看一个image-id下的所有层,您可以使用docker历史来查看它们。
docker stop命令向正在运行的容器发送SIGTERM信号,然后停止所有进程。
docker kill命令向容器中运行的所有进程发送一个不友好的SIGKILL信号。
Docker stop和docker kill命令向正在运行的进程发送UNIX信号,但docker pause命令不同。它使用cgroups的特性来暂停正在运行的进程空间。但是,这种方法的缺点是发送SIGTSTP信号不够简单,无法让进程暂停所有进程。
docker rm命令删除组成容器的可读和可写层。请注意,该命令只能在非运行容器上执行。
docker rmi命令删除构成镜像的只读层。只能使用docker rmi删除顶层层(或镜像),也可以使用-f参数强制删除中间的只读层。
docker commit命令将容器的可读层转换为只读层,从而将容器转换为不可变的镜像。
Docker build命令非常有趣,它会重复执行多个命令。
从上图可以看出,build命令根据Dockerfile文件中的FROM指令获取镜像,然后重复1)run(创建并启动),2) modify,3)commit。循环中的每一步都会产生一个新层,所以会产生很多新层。
dockereexec命令在正在运行的容器中执行一个新进程。
docker inspect命令将提取容器或镜像的顶级元数据。
docker save命令创建一个镜像压缩文件,可以在另一台主机的docker上使用。与export命令不同,此命令会保存每个图层的元数据。此命令只能对图像有效。
Docker export命令创建一个tar文件,去掉元数据和不必要的图层,将多个图层整合为一个图层,只保存从当前统一视角看到的内容(译者注:expoxt后的容器导入Docker,通过docker images -tree命令只能看到一个图像;保存后的图像是不同的,它可以看到这个图像的历史图像)。
docker history命令递归输出指定镜像的历史镜像。