DockerFile详解

大家好,本文是对 Docker 自定义镜像进行讲解,讲解如何进行构建自己的 Docker 镜像以及 Dockerfile 的操作指令。希望对大家有所帮助

镜像的定制实际上就是定制每一层所添加的配置、文件。我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

DockerFile分为四部分组成:基础镜像信、维护者信息、镜像操作指令和容器启动时执行指令。

如下步骤以构建nginx镜像为例讲解构建镜像的所使用的参数

一、镜像构建

构建所需的文件
[root@ecs dockerfile]# ll
total 6984
-rw-r--r-- 1 root root     143 Oct 13 15:07 Dockerfile
-rw-r--r-- 1 root root 7147520 Oct 13 14:45 nginx.tar
[root@ecs dockerfile]# 
文件内容如下:
###########
###########
FROM centos:7  ##基础镜像
ADD nginx.tar /usr/local   ##使用的tar包以及解压之后的路径
WORKDIR /    ###工作目录
ENV PATH /usr/local/nginx/sbin/:$PATH   ###环境变量
EXPOSE 80   ###声明端口
ENTRYPOINT ["nginx"]  ##执行的命令
CMD ["-g" , "daemon off;"]  ###上述命令执行所需要的参数

############
############
运行命令开始构建镜像
[root@ecs dockerfile]# docker build -t nginx:v4 .
Sending build context to Docker daemon   7.15MB
Step 1/7 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/7 : ADD nginx.tar /usr/local
 ---> Using cache
 ---> 4a88a896da74
Step 3/7 : WORKDIR /
 ---> Using cache
 ---> 6e8c279cc694
Step 4/7 : ENV PATH /usr/local/nginx/sbin/:$PATH
 ---> Using cache
 ---> 49a1327c8c18
Step 5/7 : EXPOSE 80
 ---> Using cache
 ---> add82ef1f24a
Step 6/7 : ENTRYPOINT ["nginx"]     ###会启动容器,id为7ccec9f9eac6
 ---> Running in 7ccec9f9eac6
Removing intermediate container 7ccec9f9eac6
 ---> 13ab8a5f416c
Step 7/7 : CMD ["-g" , "daemon off;"]   ######会启动容器,id为557b4c5e2b47
 ---> Running in 557b4c5e2b47
Removing intermediate container 557b4c5e2b47
 ---> 9a5f6f70e7ce
Successfully built 9a5f6f70e7ce
Successfully tagged nginx:v4
[root@ecs dockerfile]# 

######################
######################
使用构建的镜像启动容器测试
[root@ecs ~]# docker run -d --name test -p 81:80 nginx:v4
cf3a492f465feae38839a7c37fd21260e874d9d1444332cbe4be7e6d7e3d3188

####运行curl命令测试镜像
[root@ecs ~]# curl 127.0.0.1:81
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@ecs ~]# 

二、参数解释

  • FROM 指定基础镜像
以一个镜像为基础,在其上进行定制。上面的用例就是以centos:7为基础,在其基础之上进行修改,定制nginx镜像。基础镜像是必须指定的。而 FROM 就是指定基础镜像,因此一个 Dockerfile 中 FROM是必备的指令,并且必须是第一条指令。
####
FROM centos:7


#####################
除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。
FROM  scratch

如果你以 scratch 为基础镜像的话,意味着不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
  • RUN
RUN 指令是用来执行命令行命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一.
其运行格式有以下两种

1:shell格式,
   RUN yum install nginx
   RUN mkdir /etc/test
   Dockerfile 中每一个指令都会建立一层,RUN 也不例外。每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,commit 这一层的修改,构成新的镜像。
   上面的这种写法,创建了 2 层镜像。会产生非常臃肿、非常多层的镜像,不仅仅增加了构建部署的时间,也很容易出错。
    Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不能超过 42 层,现在是不能超过 127 层。
   正确写法如下:
   RUN yum install nginx \
       && mkdir /etc/test
    
2: exec格式,
   RUN ["nginx", "-c", "daemon off;"]   ###这种格式基本很少用,后面讲到exec的使用方式
  • CMD
CMD命令和RUN命令很相似,格式也是一样的,有shell和exec两种格式,还多个个参数传递的功能
参数列表格式:CMD ["参数1", "参数2"...]。在指定了 ENTRYPOINT指令后,用 CMD 指定具体的参数。
ENTRYPOINT ["nginx"]  ##执行的命令
CMD ["-g" , "daemon off;"]  ###上述命令执行所需要的参数

注释:
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 systemd 去启动后台服务,容器内没有后台服务的概念。不能使用systemd的方式启动。
  • COPY
拷贝文件到容器中,同ADD,只是不支持自动下载和自动解压
COPY ./start.sh /start.sh  ###/start.sh为绝对路径

使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用。特别是构建相关文件都在使用 Git 进行管理的时候。
  • ADD
ADD 指令和 COPY 的格式和性质基本一致。
ADD nginx.tar.gz /   ###如果是url,会自动下载并解压

在 Docker 官方的 Dockerfile 最佳实践文档 中要求,尽可能的使用 COPY,因为 COPY 的语义很明确,就是复制文件而已,而 ADD 则包含了更复杂的功能,其行为也不一定很清晰。最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合。
ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。
因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD。
  • ENTERPOINT
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。ENTRYPOINT 在运行时也可以替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 --entrypoint 来指定。

当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,如下:

ENTRYPOINT ["nginx"]  ##执行的命令
CMD ["-g" , "daemon off;"]  ###上述命令执行所需要的参数
  • ENV
设置环境变量,当RUN或者CMD运行命令是,可以调用$ENV进行调用,如下:
ENV PATH /usr/local/nginx/sbin/:$PATH   ###此处增加了nginx命令的环境标量,
ENTRYPOINT ["nginx"]  ##此处可以直接使用nginx的命令否则只能使用/usr/local/nginx/sbin/nginx
CMD ["-g" , "daemon off;"]  ###上述命令执行所需要的参数

也可以设置多个变量
ENV  key1=value1 key2=value2
  • EXPOSE
声明容器运行的服务端口,如下:
EXPOSE 80 443   ###只是用于声明,并不是因为这个声明而开启这个端口

这样写有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口
  • ARG
在构建镜像时,指定一些参数,例如:
FROM centos:7
ARG user # ARG user=root
USER $user

###############
这时,我们在docker build时可以带上自定义参数user了,如下所示:
docker build --build-arg user=jiushini  .


########################
arg与env的区别
ARG 定义的变量只会存在于镜像构建过程,启动容器后并不保留这些变量
ENV 定义的变量在启动容器后仍然保留
  • WORKDIR
为RUN、CMD、ENTRYPOINT以及COPY和AND设置工作目录
使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。
WORKDIR /
  • LABEL
指明镜像的维护者及其联系方式
MAINTAINER 11111111118@163.com

不过,MAINTAINER并不推荐使用,更推荐使用LABEL来指定镜像作者,例如:
LABEL maintainer="jiushini.cn"
  • HEATHCHECK
告诉Docker如何测试容器以检查它是否仍在工作,即健康检查,如下:

HEALTHCHECK --interval=5m --timeout=3s --retries=3 \
    CMD curl -f http:/localhost/ || exit 1
其中,一些选项的说明:
 --interval=DURATION (default: 30s):每隔多长时间探测一次,默认30秒
 -- timeout= DURATION (default: 30s):服务响应超时时长,默认30秒
 --start-period= DURATION (default: 0s):服务启动多久后开始探测,默认0秒
 --retries=N (default: 3):认为检测失败几次为宕机,默认3次
  一些返回值的说明:
 0:容器成功是健康的,随时可以使用
 1:不健康的容器无法正常工作
 2:保留不使用此退出代码 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值