zoukankan      html  css  js  c++  java
  • Dockerfile文件与常用指令详解(2) Marathon

    Dockerfile

    1.基本结构

    Dockerfile由一行行命令语句组成,并支持以#开头的注释行,如:

    # This dockerfile uses the ubuntu image
    
    # base image to use, set as the first line
    FROM ubuntu:18.04
    
    # maintainer info, username<email address>
    MAINTAINER daviswen<daviswen@docker.com>
    
    # commands to update the image
    RUN echo "it's a dockerfile print..."
    
    # if RUN cmd followed by several cmd, please merge to one RUN 
    # cmd, and seperate with ";" or "&&"
    RUN echo "1st print" && echo "2nd print"
    
    # cmds when creating a new container
    CMD /usr/sbin/nginx
    

    其中,

    • FROM, 开始必须指定基于镜像的名称
    • MAINTAINER, 维护者的信息
    • RUN, 镜像的操作指令,对镜像执行跟随的命令,每运行RUN,镜像就增加一层,并commit
    • CMD, 指定运行容器的操作命令

    接下来先来看看来自docker hub上的热门Dockerfile

    基于buildpack-deps:jessie-scm基础镜像,制作一个GO语言的运行环境

    FROM buildpack-deps:jessie-scm
    
    # gcc fo cgo
    RUN apt-get update && apt-get install -y --no-install-recommends g++ gcc libc6-dev make && rm -rf /var/lib/apt/lists*
    
    ENV GOLANG_VERSION 1.6.3
    ENV GOLANG_DOWNLOAD_RUL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
    ENV GOLANG_DOWNLOAD_SHA256 cdd5e08530c0579255d6153b08fdb3b8e47caabbe717bc7bcd7561275a87aeb
    
    RUN curl -fssL "$GOLANG_DOWNLOAD_RUL" -o golang.tar.gz && \
    echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && tar -C /usr/local -xzf golang.tar.gz && rm golang.tar.gz
    
    ENV GOPATH $GOPATH/bin:/usr/local/go/bin:$PATH
    
    RUN mkdir -p "$GOPATH/bin" && chmod -R 777 "$GOPATH"
    WORKDIR $GOPATH
    
    COPY go-wrapper /usr/local/bin
    
    

    2.指令说明

    指令的一般格式为 INSTRUNCTION args, 指令包括FROM,MAINTAINER,RUN等,具体指令说明如下:

    2.1 FROM

    指定所创建镜像的基础镜像

    指定所创建的镜像的基础镜像,如果本地不存在,则默认会去Docker Hub下载指定镜像。
      格式为:FROM,或FROM:,或FROM@
      任何Dockerfile中的第一条指令必须为FROM指令。并且,如果在同一个Dockerfile文件中创建多个镜像,可以使用多个FROM指令(每个镜像一次)。

    2.2 MAINTAINER

    指定维护者信息

    e.g. MAINTAINER image_creator@docker.com

    该信息将会写入生成镜像的Author属性域中。

    2.3 RUN

    运行命令,尽量合并层级

    运行指定命令。
      格式为:RUN或RUN [“executable”,“param1”,“param2”]
    注意:
    后一个指令会被解析为json数组,所以必须使用双引号。
    前者默认将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行,不会启动shell环境。
    指定使用其他终端类型可以通过第二种方式实现,例如:
    RUN ["/bin/bash","-c",“echo hello”]
    每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用\换行。

    例如:

    RUN apt-get update && apt-get install -y libsnappy-dev zliblg-dev libbz2-dev && rm -rf /var/cache/apt
    

    2.4 CMD

    指定启动容器时默认执行的命令,多个CMD只执行最后一个,有多个,可合并

    支持三种格式:

    1.CMD ["executable","param1","param2"] 使用exec执行,是推荐使用的方式;
    2.CMD param1 param2 在/bin/sh中执行,提供给需要交互的应用;
    3.CMD ["param1","param2"] 提供给ENTRYPOINT的默认参数。
    

    每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。入股用户启动容器时指定了运行的命令(作为run的参数),则会覆盖掉CMD指定的命令。

    2.5 LABEL

    指定生成镜像的元数据标签信息

    例如:

    LABEL version="1.0"
    

    2.6 EXPOSE

    声明镜像内服务所监听的端口

    格式为:EXPOSE […]
      例如:

    EXPOSE 22 80 443 3306
    

    注意:

    该命令只是起到声明,并不会自动完成端口映射。
    在容器启动时需要使用-P(大写P),Docker主机会自动分配一个宿主机未被使用的临时端口转发到指定的端口;使用-p(小写p),则可以具体指定哪个宿主机的本地端口映射过来。

    2.7 ENV

    指定环境变量

    在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在。
      格式为:ENV 或ENV=…。

    例如:

    ENV GOLANG_VERSION 1.6.3
    ENV GOLANG_DOWNLOAD_RUL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
    ENV GOLANG_DOWNLOAD_SHA256 cdd5e08530c0579255d6153b08fdb3b8e47caabbe717bc7bcd7561275a87aeb
    
    RUN curl -fssL "$GOLANG_DOWNLOAD_RUL" -o golang.tar.gz
    

    另一种写法:

    ENV GOLANG_VERSION=1.6.3
    

    指令指定的环境变量在运行时可以被覆盖掉,如docker run --env = built_image。

    2.8 ADD

    复制指定的路径下的内容到容器中的路径下,可以为URL;如果为tar文件,会自动解压到路径下

    ADD *.c /code/
    
    ADD app.tar.gz /app/app
    
    # ADD <src> <dest>
    # src部分是是你Dockerfile的相对路径
    

    2.9 COPY

    复制本地主机的路径下的内容到容器中的路径下;一般情况下推荐使用COPY而不是ADD

    目标路径不存在时,会自动创建。路径同样支持正则。当使用本地目录为源目录时,推荐使用COPY。

    如果COPY的是压缩包不会帮你解压。

    2.10 ENTRYPOINT

    指定镜像的默认入口

    该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数。
      支持两种格式:

    1.ENTRYPOINT ["executable","param1","param2"] (exec调用执行);
    2.ENTRYPOINT command param1 param2(shell中执行)。
    

    此时,CMD指令指定值将作为根命令的参数。
      每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个有效。
      在运行时可以被–entrypoint参数覆盖掉,如docker run --entrypoint。

    2.11 VOLUME

    创建数据挂载点

    格式为:

    VOLUME ["/data"]

    VOLUME ["/data","/data/etc"]

      可以从本地主机或者其他容器挂载数据卷,一般用来存放数据库和需要保存的数据等。

    在启动容器的时候Docker会在/var/lib/docker/的下一级目录下创建一个卷,以保存你在容器中产生的数据。若没有申明则不会创建。(可以把此指令看成shell中的mkdir)此指令不是独立数据卷,数据会随着容器的停止而消失,如果想数据持久化,请参考docker 简单命令 在run启动容器是加-V 参数!

    2.12 USER

    指定运行容器时的用户名或UID

    后续的RUN等指令也会使用特定的用户身份。
      格式为:USER daemon
      当服务不需要管理员权限时,可以通过该指令指定运行用户,并且可以在之前创建所需要的用户。例如:

    RUN groupadd -r nginx && useradd -r -g nginx nginx
    

    要临时获取管理员权限可以用gosu或者sudo。

    2.13 WORKDIR

    配置工作目录

    为后续的RUN、CMD和ENTRYPOINT指令配置工作目录。
      格式为:WORKDIR /path/to/workdir。
      可以使用多个WORKDIR指令,后续命令如果参数是相对的,则会基于之前命令指定的路径,可以理解为shell的cd。例如:

    WORKDIR /a
    WORKDIR b
    WORKDIR c
    RUN pwd
    
    # 最终路径为/a/b/c
    

    2.14 ARG

    指定镜像内使用的参数(例如版本号信息等)

    这些参数在执行docker build命令时才以–build-arg=格式传入。
      格式为:ARG[=]。
      则可以用docker build --build-arg=来指定参数值。

    2.15 ONBUILD

    配置当前所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作的命令格式为:ONBUILD [INSTRUCTION]。
      例如Dockerfile使用如下的内容创建了镜像image-A:

    [...]
    ONBUILD ADD . /app/src
    ONBUILD RUN /usr/local/bin/python-build --dir /app/src
    [...]
    

    如果基于image-A镜像创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像,会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令:

    FROM image-A
    
    # Automatically run the following
    ONBUILD ADD . /app/src
    ONBUILD RUN /usr/local/bin/python-build --dir /app/src
    

    使用ONBUILD指令的镜像,推荐在标签中注明,例如:ruby:1.9-onbuild。

    2.16 STOPSIGNAL

    容器退出的信号

    例如:

    STOPSIGNAL singnal
    

    2.17 HEALTHCHECK

    如何进行健康检查

    格式有两种:

    1.HEALTHCHECK [OPTIONS] CMD command    :根据所执行命令返回值是否为0判断;
    2.HEALTHCHECK NONE              :禁止基础镜像中的健康检查。
    

    2.18 SHELL

    指定使用SHELL时的默认SHELL类型

    格式为: SHELL [“executable”,“parameters”]
      默认值为 [“bin/sh”,"-c"]。

    3.创建镜像

    编写Dockerfile之后,可以通过docker build命令来创建镜像。
      基本的docker build [选项] 内容路径,该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下的所有内容发送给Docker服务端,由服务端来创建镜像。因此除非生成镜像需要,否则一般建议放置Dockerfile的目录为空目录。

    1.如果使用非内容路径下的Dockerfile,可以通过-f选项来指定其路径;
    
    2.要指定生成镜像的标签信息,可以使用-t选项。
    

    例如:指定Dockerfile所在路径为 /tmp/docker_builder/,并且希望生成镜像标签为build_repo/first_image,可以使用下面的命令:

    docker build -t build_repo/first_image /tmp/docker_builder
    

    4.其他tips

    4.1 使用 .dockerignore文件

    以通过 .dockeringore文件(每一行添加一条匹配模式)来让Docker忽略匹配模式路径下的目录和文件。例如:

    # comment
        */tmp*
        */*/tmp*
        tmp?
        ~*
    

    4.2 Dockerfile编写小结

    从需求出发,定制适合自己需求、高效方便的镜像,可以参考他人优秀的Dockerfile文件,在构建中慢慢优化Dockerfile文件:

    1.精简镜像用途:                 尽量让每个镜像的用途都比较集中、单一,避免构造大而复杂、多功能的镜像;
    2.选用合适的基础镜像:            过大的基础镜像会造成构建出臃肿的镜像,一般推荐比较小巧的镜像作为基础镜像;
    3.提供详细的注释和维护者信息:     Dockerfile也是一种代码,需要考虑方便后续扩展和他人使用;
    4.正确使用版本号:               使用明确的具体数字信息的版本号信息,而非latest,可以避免无法确认具体版本号,统一环境;
    5.减少镜像层数:                减少镜像层数建议尽量合并RUN指令,可以将多条RUN指令的内容通过&&连接;
    6.及时删除临时和缓存文件:        这样可以避免构造的镜像过于臃肿,并且这些缓存文件并没有实际用途;
    7.提高生产速度:                合理使用缓存、减少目录下的使用文件,使用.dockeringore文件等;
    8.调整合理的指令顺序:           在开启缓存的情况下,内容不变的指令尽量放在前面,这样可以提高指令的复用性;
    9.减少外部源的干扰:             如果确实要从外部引入数据,需要制定持久的地址,并带有版本信息,让他人可以重复使用而不出错
    

    5.启动Dockerfile创建新镜像

    在编写好Dockerfile文件后,我们可以通过docker build命令来创建新的镜像。通常我们在某个文件夹下放置 Dockerfile 文件,进入当前的文件夹:

    # docker build .
    # "."表示在当前目录下读取Dockerfile文件信息
    
    或者,我们也可以指定新镜像及tag标签信息,使用 -t 参数
    # docker build -t newImage:tag dockerfile_path
    # 指定绝对或相对路径
    

    以我用Dockerfile创建镜像为例:

    整理自:https://blog.csdn.net/weixin_43551152/article/details/85702315

  • 相关阅读:
    中国移动全球通寻宝第四期攻略
    推荐一个奥运门票交流的网站!
    国务院发出通知明确2008年部分节假日放假安排
    [转]开发人员如何谈加薪,抛砖引玉,欢迎大家各抒己见。
    中级.NET开发人员应该知道些什么?
    linux系统管理 系统安全及应用
    Linux10 进程 定时任务 僵尸进程
    shell脚本练习
    虚拟机和liunx系统的装机
    Linux三剑客awk的应用对比案例详解
  • 原文地址:https://www.cnblogs.com/davis12/p/14312256.html
Copyright © 2011-2022 走看看