zoukankan      html  css  js  c++  java
  • 使用Dockerfile制作镜像

    组成部分

    • 基础镜像信息       FROM
    • 维护者信息    MAINTAINER、LABEL
    • 镜像操作指令       RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER等
    • 容器启动时执行指令    CMD、ENTRYPOINT

    1、MAINTAINER

     (docker1.7以后的版本已被LABEL替代,但仍兼容此字段)

    格式:

        MAINTAINER <name>

    2、LABEL

    用键值对的方式提供比MAINTAINER更多的详细信息

    LABEL maintainer="WangChuang 123@qq.com" app="httpd

    3、copy和add

    COPY: 拷贝数据,不会自动解压数据

    从宿主机的当前工作目录中将文件copy到目标镜像文件的系统中

    语法如下:

    1. COPY <src>... <dest>

    2. COPY ["<src1>""<src2>""<dest>"]

    <src>: 要复制的源文件或目录,支持通配符

    <dest>:目标路径,建议使用绝对路径

    文件复制准则

    <src>必须是构建目录中的文件

    如果<src>是目录,则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制

    如果指定了多个<src>,或在<src>中使用了通配符,则<dest>必须是一个目录,且必须以"/"结尾

    如果<dest>事先不存在,它将会被自动创建,这包括其父目录路径

    ADD:

    功能和copy类似,但ADD支持使用tar文件和url网络路径

    ADD http://nginx.org/download/nginx-1.15.12.tar.gz /usr/local/src/   #如果src是网络路径,就不会解压

    ADD nginx-1.15.12.tar.gz /usr/local/src/  #会解压

    4、WORKDIR

    可以指定多次,

    WORKDIR /usr/local/src/

    ADD nginx-1.15.12.tar.gz ./

    5、VOLUME存储卷

    例:

    VOLUME /data/mysql/

    当容器创建好后,可以查看宿主机对应的存储目录

    docker inspect 6c |grep "/data"

    6、EXPOSE

    语法

    EXPOSE 11211/udp 11211/tcp

    关于端口暴露:容器端口暴露一般有两种方式:随机暴露 、指定端口暴露

    随机暴露端口-P(大写)

    随机暴露,Dockerfile中需有EXPOSE关键字, 定义待暴露的端口,但容器启动时并不会直接暴露到宿主机,如果需要暴露可以加上-P

    指定端口-p(小写)

    指定端口就和EXPOSE没有关系了。可以用-p 80:80,直接指定宿主机和容器间对应的端口 

    结论:可以看到管哪种方式容,器默认启动时端口是不会主动暴露到宿主机,并且容器中必须有真实存在的端口,加上-p或者-P才生效

    7、ENV

    ENV NAME wang  #设置单个变量

    ENV NAME=wang  PASSWD=123   #一次定义多个变量

    引用

    $NAME或者${NAME}

    注意:

    Dockerfile中的环境变量可以在两个阶段引用使用

    生成镜像阶段,

    运行容器阶段,启动容器加上-e还可以修改变量值

    7、USER

    用于指定运行image时,或运行Dockerfilez

    默认情况下,container的运行身份为root用户

    语法:

    USER u01  #确保镜像内有这个用户

    8、HEALTHCHECK

    默认情况下docker是判断容器主进程运行与否,来判断容器是否健康

    HEALTHCHECK:指定命令判断主进程是否真正正常提供服务,判断容器是否健康

    语法:

    HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost:8080 || exit 1

    每隔5分钟检测一次,超时时间为3秒, CMD指定检测命令,检测成功返回0,失败返回1

    参数:

    CMD  #指定检测命令

    --interval  #持续监测,默认每隔30秒

    --timeout  #超时时间,默认30s

    --start-period #有些容器比如tomcat,刚启动的时候主进程启动的慢,如果立即检测肯定是失败的,所以等容器启动多少时间以后再去检测 (默认0s,直接检测)

    --retries=N    #失败多少次,判断容器为故障 (默认3)

    响应值:

    0:表示检测成功

    1:检测失败

    2:预留的值,没意义

    重点:RUN、CMD 和 ENTRYPOINT

    容器内没有后台服务的概念,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。

    1、RUN

    RUN 指令通常用于安装应用和软件包。

    RUN 在当前镜像的顶部执行命令,并通过创建新的镜像层。Dockerfile 中常常包含多个 RUN 指令。

    RUN 有两种格式:

    Shell 格式:RUN

    Exec 格式:RUN ["executable", "param1", "param2"]

    2、CMD

    CMD 指令允许用户指定容器的默认执行的命令。此命令会在容器启动且 docker run 没有指定其他命令时运行。

    l  如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略。

    l  如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。

    CMD 有三种格式:

    Exec 格式:CMD ["executable","param1","param2"]  #这是 CMD 的推荐格式。

    Shell 格式:CMD command param1 param2

    Exec 格式,提供参数:CMD ["param1","param2"]  #为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT 必须使用 Exec 格式,shell格式无效。

    3、ENTRYPOINT

    ENTRYPOINT 指令可让容器以应用程序或者服务的形式运行。

    ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执行的命令及其参数。

    不同的地方在于 ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。

    ENTRYPOINT 有两种格式:

    Exec格式:ENTRYPOINT ["executable", "param1", "param2"] #这是 ENTRYPOINT 的推荐格式。

    Shell 格式:ENTRYPOINT command param1 param2

    在为 ENTRYPOINT 选择格式时必须小心,因为这两种格式的效果差别很大。

    #@ 就是代表参数,参数可调用可不调用

    第一种格式:PID不为1,自动为shell的子进程

    <command>通常是一个shell命令,且以"/bin/sh -c"来运行它,这意味着此进程在容器中的PID不为1,不能接收Unix信号。因此当docker stop <container>命令停止容器时,此进程接收不到SIGTERM信号

    第二种格式:PID为1,不会自动成为shell的子进程

    语法中的参数是一个列表,其中<executable>为要运行的命令,后面的为参数或选项;然而此种格式不会以"/bin/sh -c"来运行,因此常见的shell操作,如变量替换以及通配符(?/*等)替换将不会进行;不过如果要运行的命令依赖此shell特性的话,可以将其替换为类似下面的格式

    RUN ["/bin/bash","-c","<executable>","<param1>"]

    关于Shell 和 Exec 格式

    Shell 格式

    <instruction> <command>


    例如:

    RUN apt-get install python3  

    CMD echo "Hello world"  

    ENTRYPOINT echo "Hello world" 


    当指令执行时,shell 格式底层会调用 /bin/sh -c <command>。

    例如下面的 Dockerfile 片段:

    ENV name Cloud Man  

    ENTRYPOINT echo "Hello, $name" 


    执行 docker run <image> 将输出:

    Hello, Cloud Man

    注意环境变量 name 已经被值 Cloud Man 替换。

    下面来看 Exec 格式。

    Exec 格式

    <instruction> ["executable", "param1", "param2", ...]

    例如:

    RUN ["apt-get", "install", "python3"]  

    CMD ["/bin/echo", "Hello world"]  

    ENTRYPOINT ["/bin/echo", "Hello world"]

    当指令执行时,会直接调用 <command>,不会被 shell 解析。
    例如下面的 Dockerfile 片段:

    ENV name Cloud Man  

    ENTRYPOINT ["/bin/echo", "Hello, $name"]

    运行容器将输出:

    Hello, $name

    注意环境变量“name”没有被替换。
    如果希望使用环境变量,照如下修改

    ENV name Cloud Man  

    ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]

    运行容器将输出:

    Hello, Cloud Man

    CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。

  • 相关阅读:
    实现一个最简单的flask应用程序
    python常识
    Flex布局
    ES6的promise的学习
    通过正则获取url参数
    dom0级事件和dom2级事件
    sea.js总结
    跨域的几种方式
    人生苦短,生命也就一次,机会也就一次
    新开的博客先和大家打个招呼吧!
  • 原文地址:https://www.cnblogs.com/chuangcc/p/11234806.html
Copyright © 2011-2022 走看看