zoukankan      html  css  js  c++  java
  • 19-Dockerfile中的ENTRYPOINT和CMD指令详解与比较

    Dockerfile中的ENTRYPOINT指令和CMD指令都可以设置容器启动时要执行的命令,但用途是有略微不同的。

    ENTRYPOINT指令和CMD指令虽然是在Dockerfile中定义,但是在构建镜像的时候并不会被执行,只有在执行docker run命令启动容器时才会起作用。

    在Dockerfile中,只能有一个ENTRYPOINT指令,如果有多个ENTRYPOINT指令则以最后一个为准。

    在Dockerfile中,只能有一个CMD指令,如果有多个CMD指令则以最后一个为准。

    在Dockerfile中,ENTRYPOINT指令或CMD指令,至少必有其一。

    1. ENTRYPOINT指令

    首先,执行docker run如果带有其他命令参数,不会覆盖ENTRYPOINT指令。

    不过,docker run的--entrypoint可以覆盖Dockerfile中ENTRYPOINT设置的命令,后续文章详述。

    1) exec格式用法(推荐)

    ENTRYPOINT ["top","-b", "-H"]
    exec格式,也被称为JSON风格["command","arg1"]。

    在创建容器实例执行docker run命令时,设置的任何命令参数或CMD指令的命令,都将作为ENTRYPOINT指令的命令参数,追加到ENTRYPOINT指令的命令之后。

    如,在Dockerfile中有如上ENTRYPOINT指令的情况下,执行docker run <container_name> -v启动容器。则容器启动后执行的第一条完整命令如下:

    top -b -H -v

    即将-v作为top的追加参数。

    2) shell格式用法

    ENTRYPOINT top -b -H
    这种格式屏蔽追加任何参数,即CMD指令或docker run ... <command>的参数都将被忽略。

    采用shell格式,在创建容器后会首先调用Shell,即自动在命令前面追加/bin/sh -c。如,对于上述定义,在容器启动时执行的第一条命令如下:

    /bin/sh -c top -b -H

    这样,ENTRYPOINT指令设置的top命令就不是容器中的第一个进程PID 1,这样在容器停止的时候就无法收到系统的SIGTERM信号。要想收到SIGTERM信号,务必使用Bash的内置exec命令使得top的PID 1,定义ENTRYPOINT指令如下:

    ENTRYPOINT exec top -b -H
    2. CMD指令

    首先,执行docker run如果带有其他命令参数,将会覆盖CMD指令。

    如果在Dockerfile中,还有ENTRYPOINT指令,则CMD指令中的命令将作为ENTRYPOINT指令中的命令的参数(CMD和ENTRYPOINT指令必须采用JSON风格,即exec格式,定义)。

    1) exec格式用法(推荐)

    CMD ["echo","hello", "world"]
    exec格式,也被称为JSON风格["command","arg1"]。

    这种格式,在容器执行时不会调用任何Shell,即不会进行命令中的变量替换。要进行Shell处理,需要将sh直接加入到命令中:

    CMD ["sh", "-c", "echo $HOME"]
    这样,$HOME才会被解析为真实的主目录。

    但是并不推荐将sh加入到CMD指令中,因为CMD指令的命令往往作为ENTRYPOINT指令的追加参数,因而如下形式更常见:

    CMD ["-c","echo world"]
    2) shell格式用法

    CMD echo $HW
    这种格式,在创建容器后会首先调用Shell,即自动在命令前面追加/bin/sh -c,即上述设置将执行如下命令:

    /bin/sh -c echo $HW

    3. 比较ENTRYPOINT与CMD指令

    ENTRYPOINT指令,往往用于设置容器启动后的第一个命令,这对一个容器来说往往是固定的。
    CMD指令,往往用于设置容器启动的第一个命令的默认参数,这对一个容器来说可以是变化的。
    docker run <command>往往用于给出替换CMD的临时参数。

    ENTRYPOINT&CMD
    CMDENTRYPOINT N/A ENTRYPOINT exec_entry p1_entry ENTRYPOINT [“exec_entry”, “p1_entry”]
    N/A Error /bin/sh -c exec_entry p1_entry exec_entry p1_entry
    CMD [“exec_cmd”, “p1_cmd”] exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry exec_cmd p1_cmd
    CMD [“p1_cmd”, “p2_cmd”] p1_cmd p2_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry p1_cmd p2_cmd
    CMD exec_cmd p1_cmd /bin/sh -c exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
     

    参考链接:

    https://docs.docker.com/engine/reference/builder/

  • 相关阅读:
    swiper把左右箭头放到外侧
    vue复制地址栏链接:clipboard
    移动端适配rem.js
    vue登录弹框
    vue使用vue-aplayer(还用了SiriWave波形动画插件)
    vue 锚点定位,并平滑过渡
    vue引入scss报错:scss版本太高
    Kylin |3.Cube的优化
    Kylin |2.ModuleProject
    算法| 高级动态规划
  • 原文地址:https://www.cnblogs.com/robinunix/p/12788389.html
Copyright © 2011-2022 走看看