【转】docker原理 range into docker
这次主要想学习一下关于images,container 即容器和镜像之间的问题,理解了这些之后,对于docker命令也应该会有一些新的认识,毕竟了解原理才能了解一切。
首先,docker利用的是统一文件系统(the union file system)来实现着关于容器和镜像的。看看这个wiki再回来看容器和镜像,会变得容易。
所谓镜像,其实是一堆只读层的叠加,
如图所示,左边有三个只读层,他们重叠在一起,除了最下面的一层,每一层都会有一个指针来指向下一层,这些在docker的内部是自己实现的,用户不感知。对普通用户来说,我们看到的是这三个可读层叠加之后的统一视角,即存在唯一一个对外的文件系统,就是右边所展示的形式。在运行中的容器,这些层是不可见的,但是在宿主机上可以找到这些层存在的痕迹,大概存在于/var/lib/docker下。
所谓容器,其实和镜像的定义是一致的,也是一堆layer的统一构建视角,不捅的是,对于顶层的layer,容器是一层可读写层。
可以发现,容器的定义并没有定义它的状态,这是合理的,容器的定义其实只是 镜像+读写层,对于容器是不是运行其实是没有必要的。
下面来聊一聊运行中的容器,包含了可读写的统一文件系统(其实就是容器,也同时是镜像+读写层),加上利用namespace进行隔离的进程空间,和其中运行的各种进程。一个运行中的容器应该包括如下图所示的部分:
namespace隔离是docker运行的基础,一个容器中的进程可能会对文件进行修改,这些改变,其实都作用于容器的可读写层,所以,当你在容器中touch了一个问题的时候,即使容器不在了,单你touch的文件还会在。
我们再往内部走远点,range!
上文提到,镜像是由一层一层的layer组成的,那么layer到底是什么呢?
一个镜像层,不仅仅包括了文件系统的改变,还能包含其他的信息。镜像层中利用metadata提供关于这个层的额外信息,它不仅可以让docker获取运行时和构建时的信息,还包括父级层的相关信息。并且,不论是只读层还是读写层,都是包括metadata的。
一个运行中容器的metadata可以在/var/lib/docker/containers/<container-id>下找到,分成了很多数据,包括日志,设备等等。
有了上面的基础概念,现在可以理解一下docker各个指令的含义了:
docker create <image-id>
docker create 指令为指定的镜像(images)添加了一个可读写层,构成了一个新的容器,可以注意到,这个容器并没有运行。
docker start <container-id>
docker start 指令为一个容器制定了namespace隔离的进程空间,注意到,每个容器仅仅只能在一个进程空间中。
docker run <image-id>
docker run 其实是create 和 start指令合集,类似git push 和 git fetch git merge指令的含义差不多,run为images添加了一层读写层,并分配了一个进程空间给它运行。
docker ps
docker ps 列出了运行中的容器,检查进程隔离空间,并调出相应的容器最上层的信息。-a参数则会列出所有容器,不仅仅调查运行中的容器,列出所有容器的上层信息。
docker images
该命令列出了所有top-level镜像,顶层镜像对外表现为整个镜像的信息。
docker stop <container-id>
stop命令会进程空间内的进程发送一个SIGTERM信号,然后终止所有的进程空间内的进程。
docker rm <container-id>
rm指令实际上只是移除了容器的可读写层,如果不加-f的话,只能对运行中的容器进行
docker rmi <image-id>
rmi移除了的top-level的只读层,可以利用-f来强制删除中间层。
docker commint <container-id>
commit指令把读写层转换成可读层,这样就完成了从容器(container)到镜像(images)的转换
docker build
这也是一个复合指令,它会反复执行很多命令:
build命令根据dockerfile文件中的FROM指令获取镜像,然后重复run(create & start)----->做一些修改和安装------> commit
在每一次的循环中,都会生成一个新的layer,因此许多新的layer都会被创建,最终,变成一个新的镜像。
docker exec <running-container-id>
该指令实际上是在运行容器外部的进程空间内执行相应的新进程
docker inspect <image-id>/<container-id>
该命令实际上提取了容器或者镜像的最顶层metadata
docker save <image-id>
save 命令会创造出一个镜像的压缩文件,这个文件可以被另一个机器上的docker使用,与export命令不同的是,这个命令把每一层都保存了metadata,因此这个命令只能对镜像生效。
docker export <container-id>
exprot 命令创建了一个压缩文件tar,并且移除了其中各层的metadata和没有必要的层,并将多个层整合成一个层,只保存了整合后的统一视角,如果export出来的奖项,再次improt到新的容器中,那么只能看到一个镜像,但是save出来的镜像不同,可以看到整个镜像的历史镜像。
docker history <image-id>
递归得出镜像的各个历史镜像
- 点赞
- 收藏
- 关注作者
评论(0)