笔者在上篇学习docker笔记中学习理解并归纳了Docker数据卷的理念和命令,同时也写了一些关于dockerfile的操作。在本篇笔记中,笔者将对dockerfile的进行详细地解析以及学习理解其指令与案例。
DockerFile
在上一篇学习笔记中,我们已经清楚了构建dockerFile的基本顺序:
- 手动编写一个dockerfile文件,符合file规范
- 用docker build命令执行,获得一个自定义镜像
- 运行
那么DockerFile是什么呢?
Dockerfile 是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
以Ubuntu为例,我们在hub.docker.com中查找ubuntu。
我们随便点开一个,比如笔者点开了18.04, bionic-20200403, bionic。
scratch是源镜像,是所有镜像的父类。
add后面是一个解压包。
在最后一行,自带了/bin/bash所以在我们写入指令$docker run -it ubuntu时后面可以不写/bin/bash,当然写了更好。
Dockerfile的解析过程
- Dockerfile每条保留指令都必须为大写字母且后面要跟随至少一个参数。
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
Docker从基础镜像运行一个容器。执行一条指令并对容器做出修改。执行类似docker commit的操作,提交一个新的镜像层。Docker再基于刚提交的镜像运行一个新容器。执行dockerfile中的下一条指令直到所有指令都执行完成。
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段:
Dockerfile是软件的原材料
Docker镜像是软件的交付品
Docker容器可以认为是软件的运行态。
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器设计部署和运维,三者缺一不可。
Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或是文件、环境变量、依赖包、运行环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等
Docker镜像,在用Dockerfile定义了一个文件之后,docker build会产生一个Docker镜像,当运行Docker镜像时,开始提供服务
Docker容器,容器直接提供服务
DockerFile体系结构(保留字指令)
FROM 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER 镜像维护者的姓名和邮箱地址
RUN 容器构建时需要运行的命令
EXPOSE 当前容器对外暴露出的端口
WORKDIR 指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点。就相当于登陆以后的工作目录。
ENV用来在构建镜像过程中设置环境变量。这个环境变量可以在后续的任何RUN指令中使用,就如同在命令前面指定了环境变量的前缀。也可以在其他指令中直接使用这些环境变量。
ADD拷贝+解压缩。将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY拷贝。类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
VOLUME 容器数据卷,用于数据保存和持久化工作
CMD指定一个容器启动时要运行的命令。Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换。
ENTRYPONIT指定一个容器启动时要运行的命令。ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数。
ONBUILD当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发。
案例
Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的。
自定义镜像ubuntu
我们先打开ubuntu的容器,如果想用别的目录登陆该怎么办。
可以看到,这个精简版的ubuntu不支持ifconfig和vim等一些命令。
那么我们开始编写Dockerfile
from ubuntu
ENV mypath /tmp
WORKDIR $mypath
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD /bin/bash
我们把这个编写进我们的mydocker目录下的Dockerfile2中。
那么我们开始构建。
我们可以看到构建出错了。于是笔者把yum指令改成了如下指令,成功进行构建。
RUN apt-get update
RUN apt-get install vim
RUN apt-get install net-tools
我们等待构建完毕,需要看到successfully,然后打开docker images可以查询发现它的占用量比原先下载下来的镜像大。
并且此时,我们运行
$docker run -it myubuntu:1.3
我们可以发现落脚点已经变成了/usr/local
并且此时已经可以使用一些之前不能用的命令了。
我们可以使用
docker history ID
来查看历史,顺着加载,倒着执行。