Docker镜像分层和Dockerfile
- 一.Docker镜像分层
- 1.1、Docker镜像原理
- (1)bootfs (boot file system)内核空间
- (2)rootfs ( root file system)内核空间
- (3)AUFS与overlay/overlay2 . (docker高版本)
- 1.2、Docker镜像的创建方法
- 1.3、镜像分层原则
- 二.Dockerfile
- 2.1、Dockerfile结构
- 2.2、Docker操作指令
- 三.用Dockerfile创建Tomcat和Nginx镜像
- 3.1、Tomcat
- 3.2、Nginx
一.Docker镜像分层
1.1、Docker镜像原理
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS(AUFS)。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
Docker镜像层是只读的,容器层是可写的;当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。
Docker境像位于bootfs之上
每一层镜像的下一层成为父镜像
第一层镜像成为base image(操作系统环境镜像>容器层(町读可写),在最顶层(writable)
容器层以下都是readonly
contaier读写层
images (只读)base image
bootfs + rootfs + aufs +LxC (kernel)
(1)bootfs (boot file system)内核空间
主要包含bootloader和kernel
bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs
这一场与我们典型的Linux/Unix系统是一样的,包含BOOT加载器和内核。当BOOT加载完成之后整个内核就都在内存中了,此时内存的使用全已由bootfs转交给内核,此时系统也会协助bootfs
在linux操作系统中〈不同版本的linux发行版本),linux加载bootfs时会将rootfs设置为read-only,系统自检后会将只读改为读写,让我们可以在操作系统中进行操作
(2)rootfs ( root file system)内核空间
在bootfs之上 (base images,例如centos 、 ubuntu)
包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc 等标准目录和文件
rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等
(3)AUFS与overlay/overlay2 . (docker高版本)
AUFS是一种联合文件系统。它使用同一个Linux
host上的多个目录,逐个堆叠起来,对外呈现出一个统一的文件系统。AUFS使用该特性,实现了Docker镜像的分层而docker使用了overlay/overlay2存储驱动来支持分层结构
overlayFs将单个Linux主机上的两个目录合并成一个目录。这些目录被称为层,
统一过程被称为联合挂载
overlay结构:
overlayfs在linux主机上只有两层,一个目录在下层,用来保存镜像(docker);
另外一个目录在上层,用来存储容器信息
1、rootfs基础镜像
2、lower下层信息(为镜像层,可读)
3、upper上层目录(容器信息,可写)
4、worker运行的工作目录(copy-on-write写时复制-》准备容器环境)
5、merged"视图层”(容器视图)
1.2、Docker镜像的创建方法
- 基于已有镜像创建
- 基于本地模板创建
- 基于Dockerfile创建
1.3、镜像分层原则
- Dockerfile中的每个指令都会创建一个新的镜像层
- 镜像层将被缓存和服用
- 当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像是指定的变量不同了,对应的镜像镜像层就会失效
- 某一层的镜像缓存失效后它之后的镜像层缓存都会失效
- 镜像层是不可变的,如果在某一层中添加一个文件,然后再下一层中删除,则镜像中依然会包含该文件
二.Dockerfile
2.1、Dockerfile结构
2.2、Docker操作指令
指令 | 含义 |
FROM 镜像 | 指定新镜像所基于的操作系统镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令 |
MAINTAINER + 名字 | 说明新镜像的维护人信息 |
RUN + 命令 | 在所基于的镜像执行命令,并提交到新的镜像中(每写一条指令都会创建一个镜像层) |
CMD + [“要运行的程序”,“参数1”、“参数2”] | 指令启动容器时要运行的命令或者脚本(例如 CMD [“run.sh”]),Dockerfile只能有一条CMD命令,如果指定多条则只能执行最后一条 |
EXPOSE + 端口号 | 指定新镜像加载到Docker时要开启的端口 |
ENV + 环境变量 + 变量值 | 设置一个环境变量的值,会被后面的RUN使用 |
ADD + 源文件/目录 + 目标文件/目录 | 将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中,或者是一个URL,若源文件是压缩包则会将其解压缩 |
COPY + 源文件/目录 + 目标文件/目录 | 将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中 |
VOLUME + [“目录”] | 在容器中创建一个挂载点(VOLUME ["/目录"] ) |
USER + 用户名/UID | 指定运行容器时的用户(在编写mysql es mg数据库镜像文件时可能需要时用对用户授权) |
WORKDIR + 路径 | 为下一步的RUN、CMD、ENTRYPOINT指定工作目录,相当于是一个临时的"CD",否则需要使用绝对路径 |
ONBUILD + 命令 | 指定所生成的镜像作为一个基础镜像时所要运行的命令 |
HEALTHCHECK | 健康检查 |
1.FROM
格式为 FROM 或FROM :。
第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指令(每个镜像一次)。
2 MAINTAINER
格式为 MAINTAINER ,指定维护者信息。
3 RUN
格式为 RUN 或 RUN [“executable”, “param1”, “param2”]。
前者将在 shell 终端中运行命令,即 /bin/sh -c;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", “-c”, “echo hello”]。
每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行。
4 CMD
支持三种格式
CMD [“executable”,“param1”,“param2”] 使用 exec 执行,推荐方式;
CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
CMD [“param1”,“param2”] 提供给 ENTRYPOINT 的默认参数;
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。
5 EXPOSE
格式为 EXPOSE […]。
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。
6 ENV
格式为 ENV 。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。
7 ADD
格式为 ADD 。
该命令将复制指定的 到容器中的 。 其中 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
8 COPY
格式为 COPY 。
复制本地主机的 (为 Dockerfile 所在目录的相对路径)到容器中的 。
当使用本地目录为源目录时,推荐使用 COPY。
ENTRYPOINT
两种格式:
ENTRYPOINT [“executable”, “param1”, “param2”]
ENTRYPOINT command param1 param2(shell中执行)。
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。
9 VOLUME
格式为 VOLUME ["/data"]。
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
10 USER
格式为 USER daemon。
指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要临时获取管理员权限可以使用 gosu,而不推荐 sudo。
11 WORKDIR
格式为 WORKDIR /path/to/workdir。
为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录。
可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。
三.用Dockerfile创建Tomcat和Nginx镜像
3.1、Tomcat
FROM centos:7
ADD apache-tomcat-9.0.16.tar.gz /opt
ADD jdk-8u201-linux-x64.rpm /opt
WORKDIR /opt
RUN rpm -ivh jdk-8u201-linux-x64.rpm
ENV JAVA_HOME /usr/java/jdk1.8.0_201-amd64
ENV CLASSPATH $JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
ENV PATH /usr/java/jdk1.8.0_201-amd64/bin:$PATH
RUN mv apache-tomcat-9.0.16 /opt/tomcat
CMD ["/opt/tomcat/bin/catalina.sh","run"]
3.2、Nginx
FROM centos:7
RUN yum install -y gcc pcre pcre-devel devel zlib-devel make
ADD nginx-1.15.9.tar.gz /opt
WORKDIR /opt/nginx-1.15.9
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --prefix=/usr/locat/nginx
RUN make
RUN make install
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]