Dockerfile

2020-07-15  本文已影响0人  麟之趾a

Dockerfile

dockerfile是个纯文本文件,里面包含了dockerfile支持的指令
dockerfile的格式
1.注释信息
2.指令+参数
指令不区分大小写,一般使用大写。指令是按照顺序执行的
第一个非注释行,是FROM用来说明此镜像,是基于哪个基础镜像做的

docker build 命令

docker image build -h
-t --tag: 给做的镜像打个标签
-q --quiet 不显示做镜像的过程
--rm: 做镜像过程中,自动启动的工作容器。是否自动删除。默认为true

Dokefile的说明

dockerfile中的每一条指令,都是单一镜像层。
容器化使用环境变量来配置程序的配置文件,但传统的应用程序不支持环境变量的方式,为此在容器启动之前使用脚本,把环境变量注入应用的配置文件中,这个脚本通常是entrypoint.sh脚本(名称通常也是这个)

环境变量的使用

1.在构建dockefile中使用
2.在镜像运行为容器中使用

${varialbe:-world} 如果变量未设定,或者值为空,就给变量world值,否则会返回变量自身的值
${varialbe:+world}如果变量设定,有值。就返回world,如果变量为空,就返回空。
.dockerignore  指docker build过程中,忽略这个文件以及忽略这个文件所包含的文件

Dockerfile指令

FROM

FROM <respority>:<tag>
FROM <responrity>@<digest> //digest为镜像的唯一标识

MAINTANIER

AINTANIER <author' s detail>
例: MAINTANIER  "magedu"
让dockerfile 制作者提供个人信息,推荐放在FROM后面,现以废弃,但仍可以使用

LABEL

LABEL <key>=<value>  <key>=<value>
MAINTANER 替代指令,MAINTANER是个key/value 指令,只支持作者的一个key信息。LABEL可以自定义key值

COPY

用于从Docker主机复制文件至创建的新映像的文件
语法
COPY <src>  .... <dest>
COPY ["<src>",...."<dest>"]
<src>:要复制的源文件或目录,支持使用通配符
<dest>: 目标路径,即正在创建的image的文件
系统路径: 建议<dest>使用绝对路径,否则COPY指定的规则以WORKDIR为起始路径
注意: 在路径中有空白字符时,通常使用第二种格式
文件复制准则
<src>必须是build 上下文中的路径,但不能其父目录的文件
如果<src>是目录,则内部文件或子目录会被递归复制,但<src>自身不会被复制,如果指定了多个<src>,或者在<src>中使用了通配符,则<dest>必须是一个目录,且必须以/结尾。如果<dest>事先不存在,它将会被自动创建,包括父目录的路径

ADD

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

WORKDIR

设置Dockerfile中所有的RUN,CMD,ENTRYPOINT,COPY和ADD和设定工作目录
WORKDIR <dirpath>
在Dockerfile 文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过是相对此前一个WORKDIR指令的路径
另外,WORKDIR也可以调用由ENV指定定义的变量
例如: WORKDIR /var/log
WORKDIR $STATEPATH

VOLUME

用于在image中创建一个挂载点目录,以挂载Dockerhost上的卷或其他容器的卷
syntax:
VOLUME <mountpoint>
VOLUME ["<mountpoint>"]
注意: 此处只标记为它为存储卷,如果使用docker run时,没有用-v 来定义。此处为docker 管理的卷,即docker自动创建这个目录做映射关系。如果需要自定义路径,还需要-v 指定
Dokcer 挂载卷,如果挂载点有数据,会先把数据复制到存储卷上,然后再挂载,该挂载还是会隐藏原先的数据

EXPOSE

用于为容器打开指定要监听的端口,以实现与外部通信
EXPOSE <port>/<protocol> <port>/<protocol>
EXPOSE 11211/tcp  11211/udp
在容器运行时,需要-P(大写)要暴露容器所有监听的端口,将其映射为动态端口.
-p(小写) 自己指定映射的端口和容器端口

ENV

此变量在docker build 过程中生效,用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其他指令如ADD,COPY所调用
调用格式为:$variable_name 或 ${variable_name}
syntax:
ENV <key> <value>
ENV <key>=<value> <key>=<value>
第一种格式中: <key>之后的所有内容均会被视为<value>的组成部分,因此一次只能设置一个变量
第二种格式中: 可用设置多个变量,每个变量为一个"<key>=<value>" 的键值对,如果<value>中有空格,可以使反斜线(\)进行转义,也可以对<value>加引号进行标识,另外反斜线也可用于续行
定义多个变量,建议使用第二种方式,以便在同一层完成所有功能

ARG

定义一个变量在dockefile中,在build-time可以使用--build-arg <varname>=<value> 来传值,ARG变量的引用方式是相似的语法
syntax:
ARG <name>[=<default_value>]
default_value:也可以没有

RUN,CMD,ENTRYPOINT 区别

build 阶段使用RUN运行shell命令,构建目标镜像在build过程中本身,会启动一个容器,是在容器中运行RUN 指令的命令
CMD和ENTRYPOINT 是docker run中,容器默认运行的命令
假: 只有CMD指令,且CMD有多个,最后一个CMD生效
只有ENTRYPOINT,且有多个。最后一个ENTRYPOINT,生效
如果CMD和ENTRYPOINT同时存在CMD做为参数传递给ENTRYPOINT

进程的补充

我们平时通过ssh连进去,运行一个tail -f 命令,当我们ssh断了,里面的shell(/bin/bash)和tail进程也就中断了。我们在命令行界面运行的任何命令都是shell的子进程
守护进程: nohup tail -f **.log &
&: 意味着把进程,运行为后台
nohup: 意味着把当前进程,剥离当前终端。即shell停止,这个进程也不会停止。此为守护进程的意义和价值
ls * #/ * 并不是ls的参数,而是有shell解析完成后传递给ls的
crontab 运行我们的命令使用绝对路径,此命令为init的子进程,而不是shell创建的
进程有两种运行方式,一种由init运行,一种由shell运行

RUN

用于指定docker build过程中运行的程序,其可以是任何一个命令(上层镜像必须存在此命令)
syntax
RUN <command>
RUN ["<executable>","<param1>","<param2>]"
第一种命令格式,<command>通常是一个shell命令,且以"/bin/sh -c"来运行他,意味着此进程,在容器的PID不为1,不能接受unix信号,因此使用docker stop <container> 命令停止容器,此进程接受不到SIGTERM信号
第二种语法格式的参数,是一个json格式的数组,其中<executable>为要运行的命令,后面的<param1>为传递命令的选项或参数,然而此种格式指定的命令不会以"/bin/sh -c"来发起,因此常见的shell操作,如变量的替换以及通配符(?*),输入输出重定向,管道符将不会进行,如果要运行命令的命令,依赖此shell的化
RUN ["/bin/bash","-c","<executable>","<param1>"]
只要带上[],命令都不会以shell子进程运行,除非明确指定

CMD

类似于RUN指令,CMD运行于docker run 中,可以有多个,最后一个生效。CMD指定的命令就可以被docker run的命令所覆盖
syntax
CMD <command>
CMD ["<executable>","<param1>","<param2>"] 
CMD ["<param1>","<param2>"]
前两种语法意义与RUN相同,最后一种为ENTRYPOINT提供的参数
docker run --name web1 -it --rm php-httpd:v0.2 /bin/bash
让/bin/bash 覆盖原先的CMD命令

ENTRYPOINT

与CMD命令差不多,docker run后面的命令,会当作参数传给ENTRYPOINT命令
如果想ENTRYPOINT被覆盖,在docker run 中加入参数--entrypoint
docker run --name web --it --rm --entrypoint "/bin/bash" php-httpd:v0.3
一般: ENTRYPOINT ["/bin/entrypoint.sh"] 运行一个脚本,这个脚本用来传递环境变量来设置配置文件
vim entrypoint.sh //这个脚本一定有基础镜像支持
#!/bin/bash
server_name=${SERVER_NAME:-localhost}
doc_root=${DOC_ROOT:-/var/www/html/}
cat > /etc/httpd/conf.d/myweb.conf  <<EOF
<VirtualHost  *:80>
  ServerName  "$server_name"
  DocumentRoot "$doc_root"
 <Directory "$doc_root">
    Options none
    Allow Override none
    Require all granted
</Directory>
</VirtualHost>
EOF
exec "$@"
--------------------------------------------------------------------------------------------------------------------------
$@为CMD传递过来的参数,$@ 代表所有的参数。exec为目标进程替代当前进程,希望此进程在容器是PID为1的进程
让entrypoint.sh脚本有执行权限,并且把这个脚本传到新做的镜像里面去
docker container run --name myweb --rm -e SERVER_name=magedu php-httpd:v0.4
使用-e参数往里面传递参数,传进去的任何变量都可以在容器中看到,内部没定义也可以看到。也可以用printenv传递命令

USER

用于指定运行image或运行Dockerfile中任何RUN,CMD和ENTRYPOINT指令,指定的程序时的用户名或UID
默认情况下,container的运行的身份为root用户
syntax
USER <UID>|<UserName>
需要注意的是,<UID>可以为任意数字,但实践中,其必须为/etc/passwd的有效UID,否则docker run将运行失效

HEALTHCHECK

健康状态检测
一般情况下,容器是否存活,是看容器内的这个进程是否存在。如果进程依然存在,但已停止工作,会出现问题HEALTHCHECK是一个用命令探测,容器内的进程是否正常工作,如果不正常,则重启容器。
注意:此命令是在容器内执行,因此容器内必须支持此命令用来排查
syntax
HEALTCHECK [options]  CMD command
HEALTCHECK none 不做健康状态检查
CMD是固定字符串
[options]
--interval=DURATION(default 30s) 发起请求的间隔时间
--timeout=DURATION(default 30s)等待响应结果的超时时间
--start-period=DURATION(default 0s) 开始检测之前,等待进程起来的时间
--retries=N (default 3) 重试次数
命令的返回码
0 成功
1 失败
2 不要使用这个码,容器自己定义的
HEALTCHECK --interval=5m --timeout=3s \ CMD curl -f http://localhost || exit 1
docker stas 查看各个容器的资源
docker top web 查看web容器内,进程的占用情况
如果Dockerfile没有定义,HEALTHCHECK可以
docker container run 时
--health-cmd
--health-interval
--health-retries
--health-start-period
--health-timeout

SHELL

定义运行命令时的shell,默认是linux默认是sh
windows 默认是cmd
syntax
SHELL ["executable","paramers"]

ONBUILD

写在自己的dockerfile中,在构建镜像时,不运行,在其他人使用自己镜像做基础镜像,构建镜像时运行
syntax
ONBUILD <INSTRUCTION>
INSTRUCTION 为dockerfile指令
docker image history --help 查看镜像打包的历史
docker image prune 删除所有未被使用的镜像
上一篇 下一篇

猜你喜欢

热点阅读