云原生之容器化:Dockerfile详解

文章目录

  • 1、何谓Dockerfile?
  • 2、命令详解
    • 1、FORM
    • 2、MAINTAINER
    • 3、RUN
    • 4、CMD
    • 5、VOLUME
    • 6、USER
    • 7、WORKDIR
    • 8、HEALTHCHECK
    • 9、ARG
    • 10、EXPOSE
    • 11、ENV
    • 12、ADD
    • 13、COPY
    • 14、ENTRYPOINT
    • 15、ONBUILD
    • 16、LABEL
  • 3、构建Dockerfile
  • 4、构建中常见问题
    • 1、构建报Dockerfile: no such file or directory
    • 2、ADD©提示no such file or directory

1、何谓Dockerfile?

Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
Dockerfile就是一个文件,里面包含了很多的指令,可以通过指令构建出我们想要的镜像。

2、命令详解

命令 作用
FROM 构建镜像基于哪个镜像
MAINTAINER 镜像维护者姓名或邮箱地址
RUN 构建镜像时运行的指令
CMD 运行容器时执行的shell环境
VOLUME 指定容器挂载点到宿主机自动生成的目录或其他容器
USER 为RUN、CMD、和 ENTRYPOINT 执行命令指定运行用户
WORKDIR 为 RUN、CMD、ENTRYPOINT、COPY 和 ADD 设置工作目录,就是切换目录
HEALTHCHECH 健康检查
ARG 构建时指定的一些参数
EXPOSE 声明容器的服务端口(仅仅是声明)
ENV 设置容器环境变量
ADD 拷贝文件或目录到容器中,如果是URL或压缩包便会自动下载或自动解压
COPY 拷贝文件或目录到容器中,跟ADD类似,但不具备自动下载或解压的功能
ENTRYPOINT 运行容器时执行的shell命令
ONBUILD 用于延迟构建命令的执行
LABEL 用于给镜像添加一些元数据(metadata)

1、FORM

定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。

2、MAINTAINER

镜像维护者姓名或邮箱地址

3、RUN

用于执行后面跟着的命令行命令。有以下俩种格式:

shell 格式:

RUN <命令行命令>
#<命令行命令> 等同于,在终端操作的 shell 命令。

exec 格式:

RUN ["可执行文件", "参数1", "参数2"]
#例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。

例如:

FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

FROM centos
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz

如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

4、CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

CMD 在docker run 时运行。
RUN 是在 docker build。

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

格式:
CMD
CMD [“<可执行文件或命令>”,“”,“”,…]
CMD [“”,“”,…] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数

推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。

5、VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

作用:

避免重要的数据,因容器重启而丢失,这是非常致命的。
避免容器不断变大。

格式:

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

6、USER

用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

格式:

USER <用户名>[:<用户组>]

7、WORKDIR

指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。

docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。

格式:

WORKDIR <工作目录路径>

8、HEALTHCHECK

用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

格式:

HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。

9、ARG

构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

格式:

ARG <参数名>[=<默认值>]

10、EXPOSE

仅仅只是声明端口。

作用:

  • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

格式:

EXPOSE <端口1> [<端口2>…]

11、ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

格式:

ENV
ENV = =…

以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:

ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"

12、ADD

ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

  • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
  • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。

13、COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

格式:

COPY [–chown=:] <源路径1>… <目标路径>
COPY [–chown=:] [“<源路径1>”,… “<目标路径>”]

[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。

<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:

COPY hom* /mydir/
COPY hom?.txt /mydir/

<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

14、ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。

  • 优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
  • 注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

格式:

ENTRYPOINT [“”,“”,“”,…]

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。

示例:

假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参 

不传参运行

$ docker run  nginx:test

容器内会默认运行以下命令,启动主进程。

nginx -c /etc/nginx/nginx.conf

传参运行

$ docker run  nginx:test -c /etc/nginx/new.conf

容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)

nginx -c /etc/nginx/new.conf

15、ONBUILD

用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。

当我们在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A镜像)不会产生实质性影响。

但是当我们编写一个新的Dockerfile文件来基于A镜像构建一个镜像(比如为B镜像)时,这时构造A镜像的Dockerfile文件中的ONBUILD指令就生效了,在构建B镜像的过程中,首先会执行ONBUILD指令指定的指令,然后才会执行其它指令。

格式:

ONBUILD <其它指令>

16、LABEL

LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:

LABEL = = = …

比如我们可以添加镜像的标签:

LABEL image="nginx"

3、构建Dockerfile

使用命令:docker build -t nginx:mynginx .

# cat Dockerfile                 
FROM nginx
MAINTAINER LQ@jun
RUN echo '这是LQ@jun构建的nginx镜像' > /usr/share/nginx/html/index.html
CMD ls /root/
VOLUME /opt/nginx/
USER root
WORKDIR /LQ@jun
HEALTHCHECK CMD nginx -t
ARG image=nginx
EXPOSE 80
ENV NGINX_VERSION 1.16.0
ADD jsight.zip /opt/
COPY jsight.zip /root/
ENTRYPOINT ["nginx","-c"]
ONBUILD RUN mkdir /root/LQ@jun
LABEL image="nginx"

以上包含了以上所讲的所有命令
云原生之容器化:Dockerfile详解_第1张图片

4、构建中常见问题

1、构建报Dockerfile: no such file or directory

错误信息如下:

[root@root ~]# docker build -t nginx:mynginx .
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /root/Dockerfile: no such file or directory

可能原因:

  • Dockerfile不在当前目录
  • Dockerfile文件名字错误

2、ADD©提示no such file or directory

错误信息如下:

COPY failed: stat /var/lib/docker/..... no such file or directory

可能的原因:

  • 文件不存在
  • 文件路径写法错误

正确示例如下:

ADD jsight.zip /opt/
COPY jsight.zip /root/

注:jsight为本地文件路径,/opt/为容器中的文件路径

你可能感兴趣的:(云原生,Docker,云原生,运维,docker,Dockerfile)