目录
- [1. 为何Docker CentOS镜像比传统CentOS镜像小得多?](#1. 为何Docker CentOS镜像比传统CentOS镜像小得多?)
- [2. 镜像的分层结构及其优势](#2. 镜像的分层结构及其优势)
- [3. 讲一下容器的copy-on-write特性,修改容器里面的内容会修改镜像吗?](#3. 讲一下容器的copy-on-write特性,修改容器里面的内容会修改镜像吗?)
- [4. 简单描述一下Dockerfile的整个构建镜像过程](#4. 简单描述一下Dockerfile的整个构建镜像过程)
1. 为何Docker CentOS镜像比传统CentOS镜像小得多?
一个完整的Linux操作系统包含Linux内核和rootfs根文件系统,即我们熟悉的/dev、/proc/、/bin等目录。我们平时看到的centOS除了rootfs,还会选装很多软件,服务,图形桌面等,所以centOS镜像有好几个G也不足为奇。
而对于容器镜像而言,所有容器都是共享宿主机的Linux 内核的,而对于docker镜像而言,docker镜像只需要提供一个很小的rootfs即可,只需要包含最基本的命令,工具,程序库即可,这就极大地减少了镜像的大小。
2. 镜像的分层结构及其优势
一个新的镜像其实是从 base 镜像一层一层叠加生成的。每安装一个软件,dockerfile中使用RUM命令,就会在现有镜像的基础上增加一层,这样一层一层的叠加最后构成整个镜像。所以我们docker pull拉取一个镜像的时候会看到docker是一层层拉去的。
分层机构最大的一个好处就是 :共享资源。比如:有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
3. 讲一下容器的copy-on-write特性,修改容器里面的内容会修改镜像吗?
我们知道,镜像是分层的,镜像的每一层都可以被共享,同时,镜像是只读 的。当容器启动时,会创建一个可写层,称为"容器层 "。该层位于镜像的顶部,并且是唯一可写的一层,"容器层"之下的都叫"镜像层"。
所有对容器的改动 - 无论添加、删除、还是修改文件,都只会发生在容器层中,因为只有容器层是可写的,容器层下面的所有镜像层都是只读的。
- 添加文件:在容器中创建文件时,新文件被添加到容器层中。
- 读取文件:在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后打开并读入内存。
- 修改文件:在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
- 删除文件:在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。
通过这种方式,只有在真正需要修改文件时,Docker才会复制数据,这种机制被称为Copy-on-Write。这样做的优点在于,容器层只保存了镜像的变化部分,而不会修改镜像本身,确保了镜像的稳定性和一致性。
4. 简单描述一下Dockerfile的整个构建镜像过程
-
首先,创建一个目录用于存放应用程序以及构建过程中使用到的各个文件等;
-
然后,在这个目录下创建一个Dockerfile文件,一般建议Dockerfile的文件名就是Dockerfile;
-
编写Dockerfile文件,接下来,你将在 Dockerfile 中定义以下几种类型的指令:
- 基础镜像 (FROM):指定要从哪个基础镜像开始构建。
- 维护者信息 (MAINTAINER):可选,指定镜像的作者。
- 复制文件 (COPY 或 ADD):将本地文件复制到镜像中。
- 设置工作目录 (WORKDIR):指定在容器中执行命令时的默认工作目录。
- 执行命令 (RUN):运行命令以安装软件、创建文件等。
- 暴露端口 (EXPOSE):声明容器将监听的端口。
- 环境变量 (ENV):设置环境变量。
- 入口点 (ENTRYPOINT):定义容器启动时执行的命令。
- 默认命令 (CMD):提供默认要执行的命令及相关参数
-
Dockerfile编写完成就可以构建镜像 了,使用以下命令构建 Docker 镜像:
docker build -t <image_name> .
这里的
-t
选项用于指定构建后的镜像名称,.
表示当前目录下的 Dockerfile 将被用来构建镜像。docker会默认寻找当前目录下的Dockerfile文件来构建镜像,如果不使用默认,可以使用
-f
参数来指定dockerfile文件,如:docker build -t 镜像名:tag -f /xx/xxx/Dockerfile
; -
使用
docker build
命令构建之后,docker就会将当前目录下所有的文件发送给docker daemon
,顺序执行Dockerfile文件里的指令,在这过程中会生成临时容器 ,在临时容器里面安装RUN指定的命令,安装成功后,docker底层会使用类似于docker commit
命令来将容器保存为镜像,然后删除临时容器,以此类推,一层层的构建镜像,运行临时容器安装软件,直到最后的镜像构建成功。