如何通俗的解释一个生僻词汇,我觉得实践出贞操,先将它装上、用上,再从实操中去体会其中的韵味。
一、不懂就问,百度百科
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖到一个可移植的镜像中,然后发布到任何流行的Linux或Windows机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
一个完成的docker有以下几个部分组成:
ce社区版,ee企业版,推荐安装企业版
- Docker有着比虚拟机更少的
四、Docker镜像常用命令
- CREATE:镜像的创建时间
- -q:只显示镜像的ID
五、docker容器常用命令
--name 容器名称 -d 后台方式运行 -it 使用交互方式运行,进入容器查看内容(例如:
3、列出所有的运行的容器
-a 列出当前正在运行的容器 -n 显示最近创建的容器 -q 只显示容器的编号
例如:docker ps -aq 显示当前正在运行的容器的编号
7、进入当前正在运行的容器
方式二:docker attach 容器id 进入容器当前正在执行的终端
8、从容器内拷贝文件到主机
(1)后台启动容器 -d
-f:内容,,,-t:时间
(3)显示容器中的进行信息
(4)查看容器的元数据
六、docker常用命令小结
|
|
提交当前容器为新的镜像
|
从容器中拷贝指定文件或者目录到宿主机中
|
创建一个新的容器,同run 但不启动容器
|
|
从docker服务获取容器实时事件
|
在已存在的容器上运行命令
|
导出容器的内容流作为一个tar归档文件(对应import)
|
|
|
从tar包中的内容创建一个新的文件系统映像(对应export)
|
|
|
强制停止指定docker容器
|
从一个tar包中加载一个镜像(对应save)
|
注册或者登陆一个docker源服务器
|
|
|
|
查看映射端口对应的容器内部源端口
|
|
从docker镜像源服务器拉取指定镜像或者库镜像
|
推送指定镜像或者库镜像至docker源服务器
|
|
|
|
移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
|
创建一个新的容器并运行一个命令
|
保存一个镜像为一个tar包(对应load)
|
|
|
|
|
|
查看容器中运行的进程信息
|
|
|
截取容器停止时的退出状态值
|
Docker容器镜像介绍及应用
1.1 查看本地容器镜像
考虑到docker容器镜像会占用本地存储空间,建议搭建其它存储系统挂载到本地以便解决占用大量本地存储的问题。
- Docker 镜像是只读的容器模板,是Docker容器基础
- 为Docker容器提供了静态文件系统运行环境(rootfs)
2.2.1 联合文件系统定义
- 联合文件系统是实现联合挂载技术的文件系统
- 联合挂载技术可以实现在一个挂载点同时挂载多个文件系统,将挂载点的原目录与被挂载内容进行整合,使得最终可见的文件系统包含整合之后的各层文件和目录
- image:image 是存储镜像相关的元数据,包括镜像的架构,镜像默认配置信息,镜像的容器配置信息等等。它是“逻辑”上的概念,并无物理上的镜像文件与之对应。
- layer:layer(镜像层) 组成了镜像,单个 layer 可以被多个镜像共享。
可以看到上述下载的镜像分为6层,如何找到这6层存储在Docker Host哪个位置呢?
首先查看nginx镜像
这个目录是查找的入口,非常重要。它存储了镜像管理的元数据。
- imagedb 记录了镜像架构,操作系统,构建镜像的容器 ID 和配置以及 rootfs 等信息
- layerdb 记录了每层镜像层的元数据。
这里仅保留我们想要的元数据 rootfs。在 rootfs 中看到 layers 有6层,这6层即对应镜像的6层镜像层。并且,自上而下分别映射到容器的底层到顶层。找到了镜像的6层,接下来的问题是每层的文件内容在哪里呢?
上示例中,镜像元数据和镜像层内容是分开存储的。因此通过 cache-id 我们需要到 /var/lib/docker/overlay2 目录下查看镜像层内容,它就存在 diff 目录下,其中 link 存储的是镜像层对应的短 ID,后面会看到它的用场。
这是因为 docker 引入了内容寻址机制,该机制会根据文件内容来索引镜像和镜像层。docker 利用 rootfs 中的 diff_id 计算出内容寻址的 chainID,通过 chainID 获取 layer 相关信息,最终索引到镜像层文件内容。
根据 “中间层” chainID 查找文件内容:
镜像层文件内容短 ID
“父”镜像层文件内容短 ID
找到最底层文件内容和“中间层”文件内容,再去找最顶层文件内容就变的不难了
可以看到,启动容器会 mount 一个 overlay 的联合文件系统到容器内。这个文件系统由三层组成:
- lowerdir:只读层,即为镜像的镜像层。
- upperdir:读写层,该层是容器的读写层,对容器的读写操作将反映在读写层。
- merge:容器内作为同一视图联合挂载点的目录。
这里需要着重介绍的是容器的 lowerdir 镜像只读层,查看只读层的短 ID:
diff 目录。而 MS2X66BYF6UZ7EKUWMZJKCF4HO映射的是容器的初始化层 init,该层内容是和容器配置相关的文件内容,它是只读的。
启动了容器,docker 将镜像的内容 mount 到容器中。那么,如果在容器内写文件会对镜像有什么影响呢?
不难理解,镜像层是只读的,在容器中写文件其实是将文件写入到 overlay 的可读写层。
这里有几个 case 可以测试:
- 读写层不存在该文件,只读层存在。
- 读写层存在该文件,只读层不存在。
- 读写层和只读层都不存在该文件。
我们简单构建一种读写层和只读层都不存在的场景:
查看读写层是否有该文件:
上节提到容器内写文件会反映在 overlay 的可读写层,那么读写层的文件内容可以做成镜像吗?
可以。docker 通过 commit 和 build 操作实现镜像的构建。commit 将容器提交为一个镜像,build 在一个镜像的基础上构建镜像。
使用 commit 将上节的容器提交为一个镜像:
可以看到镜像层自上而下的前1个镜像层 diff_id 和 centos 镜像层 diff_id 是一样的,说明每层镜像层可以被多个镜像共享。而多出来的一层镜像层内容即是上节我们写入文件的内容:
导出容器镜像,方便分享。
把他人分享的容器镜像导入到本地,这通常是容器镜像分发方式之一。
导入使用docker export导入的容器做为本地容器镜像。