文章目录
一、联合文件系统(UnionFS)
UnionFS(联合文件系统)是一种分层、轻量级并且高性能的文件系统,它支持将对文件系统的修改作为一次提交操作来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。AUFS、OverlayFS 及 Devicemapper 都是一种 UnionFS。
UnionFS 是 Docker 镜像的基础。overlay2 是目前 Docker 默认的存储驱动,以前则是 aufs。镜像可以通过分层来进行集成,基于基础镜像(基础镜像没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统还会包含所有底层的文件和目录。
我们下载的时候看到的一层层的就是联合文件系统。 Docker 支持的联合文件系统包括 OverlayFS,AUFS,Btrfs,VFS,ZFS,Device Mapper
overlay 存储引擎结构(区别于镜像分层):
#overlayfs 在 linux 主机上只有两层,一个目录在下层,用来保存镜像(docker),另外一个目录在上层,用来存储容器信息
1、rootfs 基础镜像
2、lower 下层信息(为镜像层,可读)
3、upper 上层目录(容器信息,可写)
4、worker 运行的工作目录(copy-on-write写时复制-》准备容器环境)
5、merged "视图层"(容器视图)
docker 镜像层次结构:
1、base image:基础镜像
2、image:固化了一个标准运行环境,镜像本身的功能-封装一组功能性的文件,通过统一的方式,文件格式提供出来(只读)
3、container:容器层(读写)
4、docker-server 端
5、呈现给 docker-client(视图)
二、Docker镜像分层
Dockerfile由多条指令构成,Dockerfile中的每一条指令都会对应于Docker镜像中的每一层
- 镜像在生成的过程中是以分层的方式生成的:
- Dockerfile 中的每个指令都会创建一个新的镜像层(是一个临时的容器,执行完后将不再存在,再往后进行重新的创建与操作)
- 镜像层将被缓存和复用(后续的镜像层将基于前面的一层,每一层都会有下几层的缓存)
- 当 Dockerfile 的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了(后续操作必然更改前面的镜像层),那么对应的镜像层缓存就会失效(就会自动销毁)
- 某一层的镜像缓存失效之后,它之后的镜像层缓存就都会失效(第一层不成功,那么第二层也就再成功,相当于地基)
- 容器的修改并不会影响镜像,如果在某一层中添加一个文件,在下一层中删除它,镜像中依然会包含该文件
三、Dockerfile 概述
1.Dockerfile 定义
- Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
- 镜像的制作实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
- Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条执行的内容,就是描述该层应当如何构建。有了 Dockerfile,当我们需要定制自己额外的需求时,只需在 Dockerfile 上添加或者修改指令,重新生成 image 即可,省去了敲命令的麻烦。
- Dockerfile 中每条指定对应 Linux 中的一条命令,Docker 程序将读取 Dockerfile 中的指令生成指定镜像。
2.Docker 镜像结构的分层
镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。Docker 使用存储驱动管理镜像每层内容及可读写层的容器层。
- Dockerfile 中的每个指令都会创建一个新的镜像层
- 镜像层会被缓存和复用(下一层执行完后的缓存会给上一层使用)
- 当 Dockerfile 的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效
- 如果某层命令修改了,当前缓存层会失效,上层引用当前缓存层的也会失效,需要重构镜像,常用于版本升级(功能修改、添加)
- 镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在 Docker 容器中不可见了
- Docker 镜像每一层有唯一的编号,可以通过
docker history
来查看一个镜像由哪些层组成
docker 镜像分层(基于 AUFS 构建):
Docker 镜像位于 bootfs 之上
每一层镜像的下一层成为父镜像
第一层镜像成为 base image(操作系统环境镜像)
容器层(可读可写),在最顶层(writeout-able)
容器层以下都是 readonly
PS:
LXC 是内核中的容器技术,早期 docker 在没有将资源容器化的功能时,就是靠内核中的 LXC 来完成容器虚拟化的,现在docker 拥有了自己的 docker libcontainer 库文件,可以做到将资源容器化的操作所以对 LXC 的依赖性大大降低。
四、Dockerfile 操作指令
指令 | 含义 |
---|---|
FROM [镜像] | 指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令 |
MAINTAINER [名字] | 说明新镜像的维护人信息 |
RUN [命令] | 在所基于的镜像执行命令,并提交到新的镜像中 |
CMD [“要运行的程序”,“参数1”、“参数2”] | 指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能执行最后一条 |
EXPOSE [端口号] | 指定新镜像加载到Docker时要开启的端口 |
ENV [环境变量] [变量值] | 设置一个环境变量的值,会被后面的RUN使用 |
ADD [源文件/目录] [目标文件/目录] | 将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中,或者是一个URL,若源文件是压缩包则会将其解压缩 |
COPY [源文件/目录] [目标文件/目录] | 将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中 |
VOLUME [“目录”] | 在容器中创建一个挂载点 |
USER [用户名/UID] | 指定运行容器时的用户 |
WORKDIR [路径] | 为后续的RUN、CMD、ENTRYPOINT指定工作目录,相当于是一个临时的"CD",否则需要使用绝对路径 |
ONBUILD [命令] | 指定所生成的镜像作为一个基础镜像时所要运行的命令(是一种优化) |
HEALTHCHECK | 健康检查 |
构建镜像命令(可在构建镜像时指定资源限制)示例:
docker build -t nginx:test .
-t:tag 打标签
-f:指定 dockerfile 目录
.:指构建镜像时使用的环境(当前)目录,构建镜像时使用的上下文环境
需要遵循的格式:
- 第一行必须使用 FROM 指定新镜像所基于的镜像名称
- 之后使用 MAINTAINER 指令说明维护该镜像的用户信息
- 然后是镜像操作相关指令,如 RUN 指令。每运行一条指令,都会给基础镜像添加新的一层
- 最后使用 CMD 指令指定启动容器时要运行的命令操作
Docker 执行 Dockerfile 流程:
- docker 从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似 docker commit 的操作提交一个新的镜像层
- docker 再基于刚提交的镜像运行一个新容器
- 执行 dockerfile 中的下一条指令直到所有指令都执行完成
构建镜像命令举例:docker build -t image_name .
(不要忽视这个点)
使用镜像命令举例:docker run -d -P image_name
最后使用 docker ps -a 查看容器运行状态,如果是 up 状态就可以镜像测试验证了
1.ADD 和 COPY 的区别:
COPY 只能用于复制,ADD 复制的同时,如果复制的对象是压缩包,ADD 还可以解压。但是 COPY 比 ADD 节省资源。
2.CMD 和 ENTRYPOINT 的区别:
CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换(覆盖)。如果 docker run 没有指定任何的执行命令或者 dockerfile 里面也没有 entrypoint,那么就会使用 cmd
指定的默认的执行命令执行。CMD 命令只有最后一个会生效。
ENTRYPOINT 指定容器启动时要执行的命令,可以追加命令。ENTRYPOINT 指定的命令需要与 docker run
启动容器进行搭配,将 docker run 指令后面跟的内容当做参数作为 ENTRYPOINT 指令指定的运行命令的参数,ENTRYPOINT 指定的 linux 命令一般是不会被覆盖的。ENTRYPOINT指令并不是必须的,因为它会增加复杂度。