zoukankan      html  css  js  c++  java
  • 六、Dockerfile构建镜像

    1、介绍

    使用Dockerfile这种方式是将制作镜像的操作全部写入到一个文件中,而docker build 命令可以读取这个文件中的所有操作,并根据这些配置创建相应的镜像。

    2、Dockerfile 中的内容主要以两种形式出现

    注释行和指令行:

    ①注释行

    以#开头的文本均为注释行,可以在其中写上我们对Dockerfile 的解释,以及每行指令代表的意义。

    ②指令行

    • 行首 INSTRUCTION
    • 指令所接收的参数 arguments

    注意:指令是不区分大小写的,也就是说,可以使用小写形式的指令,但为了更清晰地分辨指令和参数,指令一般采用大写形式。

    3、指令解析行

    在Dockerfile 中, 并非所有以#开头的行都是注释行,有一类特殊的参数是通过以#开头的行来指定的,这类行的基本形式是:

    # directive=value

    此类行称为解析指令行( Parser Directives ),它的主要作用是提供一些解析Dockerfile需要使用的参数。

    4、具体的指令含义

    I、基础指令

    ① FROM指令 即我们所要构建的镜像所基于的镜像,通常情况下我们会选择一个系统镜像来布置完整的应用,当然也可以通过基于其他己完成的应用镜像。

    特点:

    • 必须在注释之外的第一行
    •  一个DockerFile可以包含多个From,但是每一个From作为镜像的分割,生成多个,不建议这样写,还是一个DockerFile一个From比较好。

    格式:

    •  FROM <image>
    •  FROM <image>:<tag>
    •  FROM <image>@<digest>

     ②MAINTAINER指令  用处是提供镜像的作者信息

    格式:

    • MAINTAINER <name>

    II、控制指令

    控制指令是Dockerfile 的核心部分,我们通过控制指令来描述整个镜像的构建过程。

    ①RUN指令  用来给定这些需要被执行的操作的。

    特点:

    • 每一次执行RUN指令之后,就会创建一个新的镜像层。
    • RUN指令执行的时候是有缓存的,如果使用的指令一致,即使两次执行的结果不一致,也会返回原来的值,所以如果存在这样的事情,需要在docker build的是添加 --no-cache 参数。

    格式: 这两种使用格式代表的意义不同,适用的场景也有区别。

    • RUN command param1 param2 .”
    • RUN [” executable ”,” param1 ”,”param2 ”,…]

    第一种方式,是以shell中执行的方式,默认使用的是/bin/sh, 最大的优势在于支持换行书写,通过 来进行换行,对应比较长的命令,可以使用这种方式, 通过Shell指令可以切换shell

    第二种方式,是直接执行命令,可以有效规避在某些基础镜像中没有Shell 程序,或者用于需要临时切换Shell 程序的时候。

    ②WORKDIR

    WORKDIR 指令用于切换构建过程中的工作目录,对于 RUN,CMD,COPY,ADD 指令将会在指定的工作目录中去执行。也可以理解为命令执行时的当前目录。

    特点:

    可以给出的是绝对目录,也可以给出的是相对目录,甚至可以使用环境变量

    格式:

    •  WORKDIR /usr
    •  WORKDIR local

    ③ONBUILD

    它可以携带另一条指令,但是不是在本次build的时候执行,而是在构建其他镜像并使用FROM 指令把当前的镜像作为基础镜像时执行。类似一个触发器。

    特点:

    • ONBUILD 指令只会在构建子镜像中执行,当子镜像构建完成后,这些指令也随之消失,所以它们不会继承到子镜像或者更后辈的镜像中
    • 不允许 ONBUILD  ONBUILD  这样嵌套使用

    格式:

    •  ONBUILD INSTRUCTION arguments

    III、引入指令

    希望将文件加入到即将构建的镜像中,引入指令就能够帮助我们实现这个目的。

    ①ADD指令

    ADD指令可以将一些软件源码、配置文件、执行脚本等从外部导入到镜像的构建过程。

    特点:

    • 设置导入文件<src>路径时,需要使用相对路径,这样才能保证移动Dockerfile和其目录后不需要再进行修改。
    • 所有被复制进镜像的文件都将放置到<dest>给出的目录下,这个目录可以是绝对路径,也可以是相对于镜像的工作目录而言的相对路径
    • ADD能添加网络文件,但是对于带认证的服务器不支持,能够支持自动的文件解压缩,自动解压文件只对本地文件有效,如果<src>给出的是网络路径, Docker 不会对文件进行解压。

    格式:

    • ADD <src> ... <dest>
    • ADD ["<src>”,...”<dest>”]

    ②COPY指令

    特点

    • 和ADD主要的区别就在于COPY 指令不能识别网络地址,也不会自动对压缩文件进行解压

    格式:

    • COPY <src> ... <dest>
    • COPY ["<src>”,...”<dest>”]

    IV.执行指令

    执行指令能够指定通过镜像建立容器时,容器默认执行的命令。我们通常使用这些命令来启动镜像中的主要程序。

    ①CMD

    特点:

    •  因为容器中只会绑定一个应用程序,所以在Dockerfile 中只存在一个CMD 指令,如果我们给出了多个CMD 指令,之后的指令会覆盖掉之前的指令。
    •  可以在启动容器的时候,通过手动输入的方式来覆盖DockerFile当中的CMD 

    格式:

    • CMD ["executable”,”paraml”,”param2 ”,..]
    • CMD [”paraml”,”param2", ... ]
    • CMD command paraml param2 ... 

    第一种和第二种和RUN指令类似,对于第三种这种格式则是将给出的参数传给ENTRYPOINT指令给出的程序。

    备注:

    不要混淆了CMD 指令和RUN 指令,它们的区别是很大的。

    RUN 指令是在镜像构建的过程中执行,并将执行结果提交到新的镜像层中;

    CMD 指令在镜像构建的过程中不能执行,它只是配直镜像的默认入口程序。

    V.ENTRYPOINT

    启动主程序之前可能会涉及到其他程序的启动和运行,那么使用CMD可以做到,但是把主程序启动和其他程序启动都杂糅到一起,会显得比较混乱。

    ENTRYPOINT 指令就是专门用于主程序启动前的准备工作的。

    特点:

    如果使用了ENTRYPOINT指令,CMD 指令的值会被当作 ENTRYPOINT 指令的参数附加到 ENTRYPOINT 指令的后面,并且如果 docker run 中指定了参数,会覆盖 CMD 中给出的参数。

    举个例子:

    FROM ubuntu:latest ENTRYPOINT ["ls", "-a"] CMD ["-l"]

    如果执行 docker run <image>  相当于执行 docker run <image> ls -a -l (ENTRYPOINT  + CMD )

    如果执行 docker run <image> -i -s 相当于执行  docker run <image>  ls -a -i -s (ENTRYPOINT  + CMD被覆盖 )

    应该避免在使用ENTRYPOINT 时把CMD 指令的形式配置成shell 格式,即CMD command paraml param2 ...。因为如果这样做,在ENTRYPOINT 里是以次级命令的方式,启动CMD 的Shell 进程的,所以这个进程在容器中的PID 井不是1, Docker 就不会把容器的生命周期绑定到这个进程上。这就会使我们在外部对容器发出的信号无法发送到这个进程上,包括容器停止时发出的信号,而没有收到信号的程序会被强制结束,这就会造成数据的损坏以及其他意想不到的结果。

    格式:

    使用ENTRYPOINT 指令的方式与使用CMD 指令的方式非常相似。

    • ENTRYPOINT [”executable”,”paraml", "param2"]
    • ENTRYPOINT command param1 param2 …

    VI.配置指令

    ①EXPOSE (开放端口但不是实际映射)

    如果容器中的应用程序需要让其他镜像访问到它提供的端口,需要显式给出对外提供的端口号。而没有给出的端口号,即使容器中的应用程序对它们进行了监听,但Docker 没有对它们进行转接,所以在容器外依然是访问不到的。

    格式:

    • EXPOSE <port> [<port> .. . ]

    注意

    EXPOSE 指定在容器运行时监听指定的网络端口,它与 docker run 命令的 -p 参数不一样,并不实际映射端口,只是将该端口暴露出来,允许外部或其它的容器进行访问。

    要将容器端口暴露出来,需要在 dcoker run 命令中使用 -p 或者 --publish 参数。如果采用 -P 随机映射端口的方式,Docker 会将在 DockerFile 中声明的所有 EXPOSE 的端口随机映射。

    ②ENV

    ENV 指令用于设置环境变量

    特点:

    • 环境变量也是能够继承的,所有在基础镜像中设置的环境变量,也都会被继承到将要构建的镜像中。
    • 我们可以通过docker inspect 命令查看镜像中的环境变量,在容器创建时也可以通过一env 参数来新增和替换环境变量: docker run --env <key>=<value>

    格式:

    •  ENV <key> <value>
    •  ENV <key>=<value> <key>=<value>...

    ③LABEL

    使用LABEL 指令,可以为即将生成的镜像提供一些元数据作为标记,这些标记能够帮助我们更好地展示镜像的信息。

    格式:LABEL <key>=<value> <key>=<value> <key>=<value>

    ④USER

    USER 指令用于设置执行用户,我们可以传入用户的名称或UID作为USER 指令的参数。

    特点:在Dockerfile 中可以指定一个用户,后续的 RUN,CMD 以及 ENTRYPOINT 指令都会使用该用户去执行,但是该用户必须提前存在。

    格式:USER nginx

    ⑤ARG

    ARG主要是用于设置变量的。

    特点:

    • 和ENV指令不同的是,它不会作用于继承该镜像的镜像,而只会在该镜像Build的时候生效。也可以在docker build的时候通过--build-arg 来进行指定。
    • 如果ARG定义的变量和ENV重复,那么ENV 指令所定义的变量永远都会覆盖ARG 指令所定义的变量即可,即使它们定义的顺序是相反的。

    格式:

    • ARG <name>
    • ARG <name>=<default>

    ARG定义是变量,如果不设置默认值,需要从外部传入,举例:

    FROM busybox ARG user USER $user
    

    在build的时候,可以传入这个user变量的值

    docker build --build-arg user=root ./busybox
    

     

    ⑥STOPSIGNAL

    当我们停止容器时, Docker会向容器中的应用程序传递停止信号,我们可以通过STOPSIGNAL 指令来修改Docker 所传递的信号。

    STOPSIGNAL 支持两种格式定义的信号, 一种是用Linux 内核syscall 信号的数字表示,另一种是用信号的名称表示。

    格式:

    • STOPSIGNAL 9
    • STOPSIGNAL  Kill

    ⑦SHELL

    CMD 、ENTRYPOINT 等指令都支持以shell 形式执行,而SHELL指令可以为它们选定Shell 程序。SHELL 指令的使用格式如下:

    • SHELL [” executable”,”parameters”]

    举例:Docker 默认使用的Shell 程序是/bin/sh ,若要改为/bin/bash ,可以使用如下SHELL指令:

    • SHELL ["/bin/bash","-C"]
  • 相关阅读:
    数据库 'tempdb' 的日志已满的解决方法
    SQL Server2005|身份验证模式修改转载
    GRUB讲解转载
    远程连接sql server 2000服务器的方法,及配置sql数据库服务器转载
    SQL 删除一列的语句
    陶哲轩实分析 命题 8.2.6 证明
    陶哲轩实分析 引理 8.2.3 证明
    陶哲轩实分析 习题 7.5.3
    陶哲轩实分析 习题 7.5.3
    陶哲轩实分析 引理8.2.7 注
  • 原文地址:https://www.cnblogs.com/dcz2015/p/12470429.html
Copyright © 2011-2022 走看看