基于dockerfile来制作镜像

一:dockerfile简介:

dockerfile纯文本文件,里面包含多个指令。
制作Docker image 有两种方式:
(1)是使用 Docker container,直接构建容器,再导出成 image 使用;
(2)是使用 Dockerfile,将所有动作写在文件中,再 build 成 image

二:dockerfile的基本架构。

  Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,
  ’#’ 为 Dockerfile 中的注释。

三:dockerfile中相关指令。
FROM指令

(1)这指令是最重要的一个且必须为dockerfile文件开篇的第一非注释行,用于为镜像文件构建过程指定的底层镜像,后续的指令
运行于此基准镜像所提供的运行环境
(2)实践中基准镜像可以是任何可用镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时
则会在docker hub registry上拉取所取的镜像文件。
注意:如果找不到指定的镜像文件,docker build时会返回一个错误信息

FROM语法:FROM <repository>[:<tag>]  或者 FROM<resository>@<digest(镜像hash码)>
repository:指定作为base image的名称, tag:base image的标签,可选项省略时默认为latest

MAINANIER (depreacted)指令

这个指令指的是制作者的用户信息。

copy指令:用于从docker主机复制文件到创建的新镜像文件。

语法:copy <src> ......<dest> 或 copy ["<src>"....."<dest>"]
<src>:要复制的源文件或目录,支持使用通配符
<dest>: 目标路径,即正在创建的image的文件系统路径,建议为<dest>使用绝对路径,否则copy指定则以workdir为起始路径
注意:在路径中有空白字符时,通常使用第二种格式。

文件复制准则:
(1)<src>必须是build上下文中的路径,不能是其父目录中的文件
(2)如果<src>是目录则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制
(3)如果指定多个<src>或在<src>中使用了通配符,则<dest>必须是一个目录,且必须以/结尾
(4)如果<dest>事先不存在,它将会自动创建,这包括其父目录路径

ADD指令:

ADD指令类似于copy指令,ADD支持使用tar文件和url路径
语法:ADD <src>......<dest>或ADD ["<src>"...."<dest>"]
操作准则:
(1)同copy指令
(2)如果<src>为URL且<dest>不以/结果,则<src>指定的文件将被下载并直接被创建为<dest>;如果<dest>/结果则文件名URL指定
的文件将被直接下载并保存为<dest>/<filename>
(3)如果<src>是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于tar  -x命令然而,通过URL获取到的tar文件将不会自动展开
(4)如果<src>有多个,或其间接或直接使用了通配符,则<dest>必须是一个以/结尾的目录路径;如果<dest>不以/结尾,则其被视作一个不同文件,<src>的内容将被直接写入到<dest>

WORKDIR指令:

(1)用于为Dockfile中所有的RUN,CMD,ENTRYROINT,COPY和ADD指令设定的工作目录。
语法:在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过,其是相对此前一个WORKDIR指令指定的路经
(2)另外,WORKDIR也可调用由ENV指定定义的变量。
例如:1,WORKDIR  /var/log      2,WORKDIR  $STATEPATH

volume指令:

(1)用于在image中创建一个挂载点目录,已挂载docker host上的卷或其他容器上的卷
语法:
volume<mountpoint> 或 volume["<mountpoint>"]
如果挂载点目录路径下此前在文件存在,docker  run命令时会在卷挂载完成后将此前的所有文件复制到新的挂载的卷中

Expose指令:

(1)用于为容器打开指定要监听的端口以实现与外部通信。
Expose <port> [/<protocol>] [port]>[<protocol>]...
<protocol>用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议。

ENV指令:

(1)用于为镜像定义所需的环境变量,并可被dockerfile文件中位于其后的其他指令。如(ENV,ADD,COPY)所调用
调用格式为:$variable_name或$[variable_name]
(2)语法:
ENV  <key>  <value>或ENV <key>=<value>
(3)第一种语法格式中<key>之后的所有内容均会被视为其<value>的组成部分,因此一次只能设置一个变量
(4)第二种格式可用一次设置多个变量,每个变量为一个“<key>=<value>"的键值对,如果<value>中包含空格可以以反斜线\  进行转义,也可通过多<value>加引号进行标识;另外反斜线也用于续行;
(5)定义多个变量时,建议使用第二种格式,以便在同一层中完成所有功能。

RUN指令:

(1)用于指定docker build过程中运行的程序,其可以是任何命令。
语法:RUN <command> 或 Run ["<executable>","<param1>","<param2>"]
(2)第一种格式中<command>通常是一个shell命令,且以“/bin/sh -c 来运行它,这意味着此进程在容器中的PID不为1,不能接受uninx信号,因此当使用docker stop <command>命令停止容器时,接受不到sicterm信号。
(3)第二种格式:参数是一个json的数组,其中<executable>为要运行的命令,后面的<param1>为传递给命令的选项或参数,此种格式指定的命令不会以”/bin.sh  -c“ 来发起,不过如果要运行的命令依赖于此shell特性的话可以使用
以下格式:RUN ["/bin/bash","-c","<executable>","<param2>"]
注意:json数组要使用双引号。

在这里插入图片描述
CMD指令:

(1)类似于Run指令,CMD指令也可用运行任何命令或应用程序,不过二者的运行时间点不同。
(2)Run指令运行于镜像文件过程中,二CMD运行于基于dockerfile构建出来的新镜像中启动一个容器时
(3)CMD指令的首要目的在于为启动的容器指定默认要运行的程序,但其运行结束后,容器也将终止;不过CMD指定的命令其可以被Dockefile run的命令选项多覆盖
(4)在dockerfile中可以存在多个CMD指令,但仅最后一个会生效。

语法格式:
(1)CMD <command>或 CMD ["<executable>","<param1>","<param2>"或  CMD["<param1>",<param2>"]
(2)前两种语法格式的意义同RUN
(3)第三种则用于为ENTRYROINT指令提供的默认参数。

ENTRYPOINT指令。

(1)类似CMD指令的功能,用于为容器指定默认运行程序从而使得容器像是一个单独的可执行程序
(2)与CMD不同的是,由ENTRPOINT启动的程序,不会被docker run 命令指定的参数所覆盖,而且这些命令行参数会被当作参数传递给ENTRPOINT指定的程序
注意:不过,docker run命令的 --entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序

语法格式:
(1)ENTRYPOINT <command>
(2)ENTRYPOINT ["executable>“,"<param1>","<param2>"]
注意:docker run 命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用dockerfile文件
中可以有多个ENTRYPOINT指令,但仅有最后一个生效。

四:镜像创建,基于dockerfile创建一个简单的镜像。

[root@node2 ~]# mkdir dockerfile/
[root@node2 dockerfile]# ls       创建,和复制所需文件
Dockerfile  index.html  yum.repos.d
[root@node2 dockerfile]# 
#Description:test image
FROM busybox:latest
MAINTAINER "yanss <yanss@shuoshuo.com>"
ENV DOC_ROOT=/data/web/html/ \     斜杠代表着换行。
    web_server_package="nginx-1.15.2.tar.gz"
COPY index.html ${DOC_ROOT}
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/${web_server_package} /usr/local/src/
WORKDIR /usr/local/
VOLUME /data/mysql/
EXPOSE 80/tcp
RUN cd /usr/local/src && \
    tar -xf ${web_server_package} && \
    mkdir webserver && \ 
    mv nginx-* webserver   
~    

[root@node2 dockerfile]# docker build -t tinyhttpd:v0.1-8 ./
Sending build context to Docker daemon  38.91kB
Step 1/10 : FROM busybox:latest
 ---> be5888e67be6
Step 2/10 : MAINTAINER "yanss <yanss@shuoshuo.com>"
 ---> Using cache
 ---> f7498a528d1c
Step 3/10 : ENV DOC_ROOT=/data/web/html/     web_server_package="nginx-1.15.2.tar.gz"
 ---> Using cache
 ---> 62c252434551
Step 4/10 : COPY index.html ${DOC_ROOT}
 ---> Using cache
 ---> abe659afe685
Step 5/10 : COPY yum.repos.d /etc/yum.repos.d/
 ---> Using cache
 ---> 802b908d405a
Step 6/10 : ADD http://nginx.org/download/${web_server_package} /usr/local/src/
Downloading [==================================================>]  1.026MB/1.026MB
 ---> Using cache
 ---> 03144b1d6dbf
Step 7/10 : WORKDIR /usr/local/
 ---> Using cache
 ---> 8b62bb0b9cba
Step 8/10 : VOLUME /data/mysql/
 ---> Using cache
 ---> 7ccaa2450bff
Step 9/10 : EXPOSE 80/tcp
 ---> Using cache
 ---> 84d83ea007ef
Step 10/10 : RUN cd /usr/local/src &&     tar -xf ${web_server_package} &&     mkdir webserver &&     mv nginx-* webserver
 ---> Using cache
 ---> 42d6cd3ef954
Successfully built 42d6cd3ef954
Successfully tagged tinyhttpd:v0.1-8
[root@node2 dockerfile]# docker image ls -a
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tinyhttpd1          latest              42d6cd3ef954        17 hours ago        9.39MB
tinyhttpd           v0.1-8              42d6cd3ef954        17 hours ago        9.39MB

利用创建的启动容器,看是否有相关参数。 在这里-P指明的是暴露端口,dockerfile中虽然指明暴露的端口,但是并不是真的暴露
也可以 -e 指明向容器注入的环境变量。
[root@node2 dockerfile]# docker run --name tinyweb1 --rm -P -it tinyhttpd:v0.1-8  
/usr/local # 
/usr/local # ls
src
/usr/local # env
HOSTNAME=0f9c0c18936b
DOC_ROOT=/data/web/html/
SHLVL=1
HOME=/root
web_server_package=nginx-1.15.2.tar.gz
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/usr/local
/usr/local # ls
src
/usr/local # find / -name webserver
/usr/local/src/webserver
fs/usr/local # 
/usr/local # cd src/
/usr/local/src # ls
webserver
/usr/local/src # cd webserver/
/usr/local/src/webserver # ls
nginx-1.15.2         nginx-1.15.2.tar.gz
/usr/local/src/webserver # 

查看运行的容器。
[root@node2 dockerfile]# docker container ls -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS                         PORTS                   NAMES
0f9c0c18936b        tinyhttpd:v0.1-8     "sh"                     2 minutes ago       Up 2 minutes                   0.0.0.0:32768->80/tcp   tinyweb1                                        

USER指令:

(1)用于指定运行image时的或运行dockerfile中的任何RUN,CMD,或ENTRYPOINT指令指定的程序时的用户名或UID
(2)默认情况下,container运行的用户身份是root
语法:
(1)USER <UID>|<Username>
(2)需要注意的是<UID>可以为任意数字,但实践中其必须为/etc/passwd中的某用户的有效UID,否则docker run命令将运行失败。

HEALTHCHECK指令:做健康检测机制。

语法格式:
HEALTHCHECK  [options]  CMD  command    CMD表示关键词。
HEALTHCHECH选项:
--interval=DURATION(default30s)    表示每隔多长时间检测一次
--timeout = DURATION(default30)     表示健康检测超时时长
--start-period=DURATION(default0s) 表示等主进程多长时间发起检测机制。
--retries=N(default: 3s)             表示往健康检测发起几次,不能一次就好

健康检测状态的反应码?
0:sucess   1:unhealthy(不健康的)   2,reserved(多余的无意义)
例如:HEALTHCHECK  --interval=5m  --timeout=3s \  表示每5s执行一次检测,超时时长为3s,执行命令为请求主机名,失败就退出。
                  CMD curl  -f  https:/localhost/ || exit1

ARG指令:

(1)作用:能在dockerfile中定义变量,并且接受在docker  --build 中传递的参数。
  参数:--build-arg <varname=<value> flag
语法:ARG <name>[=<default value>]
例如:
(1)ARG version=1.14
(2)ARG user=shuoshuo

例如:简单做个小镜像验证ARG的作用。
[root@node2 image1]# vim Dockerfile 
FROM nginx:1.14-alpine
ARG author="yanss <yanss@mingyuan.com>"
LABEL maintainer="${author}"
~                                  
[root@node2 image1]# docker build --build-arg author="shuoshuo <shu@qq.com>" -t tinyhttpd2 ./  在docker build过程中想要传送变量必须设置ARG指令。
[root@node2 image1]# docke image inspect tinyhttpd2 查看元数据信息,作者信息已经发生改变了。
注意:我们在Dockerfile文件中定义的ENV环境变量,在docker build中是无法传环境变量的在docker run中启动容器时是可以传送变量的如果想要在docker build中传送变量,那么要使用ARG定义变量。

在这里插入图片描述
ONBUILD指令:

(1)用于在dockerfile中定义一个触发器。
(2)dockerfile用于build镜像文件,此镜像文件可作为base image 被另一个dockerfile用作FROM指令的参数,并以之构建的镜像文件
(3)在后面的这个dockerfile中的FROM指令在build过程中被执行时,将会触发创建其base image的dockerfile文件中的ONBUILD指令定义的触发器。

语法:
ONBUILD<instruction>
(1)尽管任何指令都可注册成为触发器指令,但ONBUILD不能自我嵌套,且不会触发FROM和MAINIAINER指令
(2)使用包含ONBUILD指令的dockerfile构建的镜像应使用特殊标签,例如:rudy:2.0-onbuild
(3)在ONbuild指令中使用ADD或COPY指令应该格外小心因为新构建过程上下文在缺少指定源文件时会失效

例如:在一个dockfile文件中设置ONBUILD那么做成镜像时,不会在此镜像中执行。
做一个ONBUILD实列:
[root@node2 image1]# vim Dockerfile
利用nginx:1.14-alpine为基础镜像做一个镜像:
FROM nginx:1.14-alpine
WORKDIR /usr/local/
ONBUILD RUN mkdir yanss      这个触发器是创建一个yanss目录
ARG author="yanss <yanss@mingyuan.com>"
LABEL maintainer="${author}"

[root@node2 image1]# docker build -t tinyh5 ./
Sending build context to Docker daemon  3.072kB
Step 1/5 : FROM nginx:1.14-alpine
 ---> 8a2fb25a19f5
Step 2/5 : WORKDIR /usr/local/
 ---> Running in 51033a1bfc88
Removing intermediate container 51033a1bfc88
 ---> d89058d0a8d2
Step 3/5 : ONBUILD RUN mkdir yanss
 ---> Running in 45cb6c842a8f
Removing intermediate container 45cb6c842a8f
 ---> 11fccbc7a094
Step 4/5 : ARG author="yanss <yanss@mingyuan.com>"
 ---> Running in e6df0a17a6e7
Removing intermediate container e6df0a17a6e7
 ---> afbf9c836cba
Step 5/5 : LABEL maintainer="${author}"
 ---> Running in cba701e31bd0
Removing intermediate container cba701e31bd0
 ---> ede064a8dd00
Successfully built ede064a8dd00
Successfully tagged tinyh5:latest

[root@node2 image1]# docker run --name tinyh5 -it tinyh5 ls  运行容器检查到ONBUILD指令没有运行。
bin    lib    share
[root@node2 image1]# 

(2)在根据我们上述的镜像为基础镜像,验证ONBUILD 
[root@node2 image2]# vim Dockerfile    
FROM tinyh5:latest     根据上述镜像。
RUN mkdir /tmp/test
[root@node2 image2]# docker build -t tinyh6 ./    我们在基于一个有ONBUILD指令的镜像为基础镜像做镜像时,ONBUILD才会触发。
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM tinyh5:latest
# Executing 1 build trigger
 ---> Running in d7774b2cd8ab
Removing intermediate container d7774b2cd8ab
 ---> dcc1f2e2de28
Step 2/2 : RUN mkdir /tmp/test
 ---> Running in 26b4d0741e8b
Removing intermediate container 26b4d0741e8b
 ---> ca91727fde19
Successfully built ca91727fde19
Successfully tagged tinyh6:latest
[root@node2 image1]# docker exec -it tinyh6 /bin/sh   进入容器查看到触发器已经触发
/usr/local # ls
bin    lib    share  yanss
/usr/local #                                 

总结:Dockerfile如何制作和一些指令的使用,已经就绪完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值