GVKun编程网logo

docker 中 entrypoint 和 CMD 的执行总结(docker cmd与entrypoint)

7

在这里,我们将给大家分享关于docker中entrypoint和CMD的执行总结的知识,让您更了解dockercmd与entrypoint的本质,同时也会涉及到如何更有效地Docker--entryp

在这里,我们将给大家分享关于docker 中 entrypoint 和 CMD 的执行总结的知识,让您更了解docker cmd与entrypoint的本质,同时也会涉及到如何更有效地Docker -- entrypoint与cmd解析、Docker CMD 指令与 ENTRYPOINT 指令的使用与区别、Docker ENTRYPOINT变量未结转到CMD中、docker RUN CMD ENTRYPOINT 区别的内容。

本文目录一览:

docker 中 entrypoint 和 CMD 的执行总结(docker cmd与entrypoint)

docker 中 entrypoint 和 CMD 的执行总结(docker cmd与entrypoint)

网上关于 CMD 和 entrypoint 的相关介绍很多,在实际工程中也确实需要了解,经过总结,有如下重点
  • 如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略。
  • 如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。
  • 在 Dockerfile 中,只能有一个 ENTRYPOINT 指令,如果有多个 ENTRYPOINT 指令则以最后一个为准。
  • 如果镜像中设定了 ENTRYPOINT,那么命令中的 CMD 也可以作为参数追加到 ENTRYPOINT 中。
  • entrypoint 如果有多个,只会执行最后一个 entrypoint
  • docker run 的 --entrypoint 可以覆盖 Dockerfile 中 ENTRYPOINT 设置的命令。

Docker -- entrypoint与cmd解析

Docker -- entrypoint与cmd解析

entrypoint和cmd用在dockerfile中,它们都可以指定容器启动时运行的命令,在使用时,通常用entrypoint指定命令,cmd指定命令参数。

exec和shell

entrypoint和cmd的写法:exec模式、shell模式

exec模式:[]的写法,推荐使用

FROM ubuntu
CMD [ "top" ]

容器运行时,top命令是1号进程。

shell模式:/bin/sh -c "cmd"的写法

FROM ubuntu
CMD top

容器运行时,sh是1号进程,top是sh创建的子进程。

典型用法:CMD

简单的可以在CMD中指定:命令和参数

FROM ubuntu
EXPOSE 8080
CMD [ "nginx", "-s", "reload" ]

典型用法:EntryPoint + CMD (推荐)

通用的方法,在EntryPoint中指定命令,在CMD中指定参数

# prometheus通过CMD指定运行参数
USER       nobody
EXPOSE     9090
VOLUME     [ "/prometheus" ]
WORKDIR    /prometheus
ENTRYPOINT [ "/bin/prometheus" ]        #exec写法:指定命令
CMD        [ "--config.file=/etc/prometheus/prometheus.yml", \
             "--storage.tsdb.path=/prometheus", \
             "--web.console.libraries=/usr/share/prometheus/console_libraries", \
             "--web.console.templates=/usr/share/prometheus/consoles" ]        #exec写法:指定参数

典型用法:kubernetes

在pod的spec中,可以通过command参数覆盖镜像中的EntryPoint参数:

# kubectl explain pod.spec.containers.command
DESCRIPTION:
     Entrypoint array. Not executed within a shell. The docker image''s
     ENTRYPOINT is used if this is not provided. 

在pod的spec中,可以通过args参数覆盖镜像中的CMD参数:

# kubectl explain pod.spec.containers.args
DESCRIPTION:
     Arguments to the entrypoint. The docker image''s CMD is used if this is not
     provided. 

所以,为了业务应用的image可以在kubernetes上运行,推荐在镜像的dockerfile中:entrypoint指定命令,cmd指令参数,以便在运行时可以灵活覆盖。

比如Prometheus的container在kubernetes中运行时,使用args覆盖镜像中的CMD参数:

......
spec:
  containers:
  - args:
    - --web.console.templates=/etc/prometheus/consoles
    - --web.console.libraries=/etc/prometheus/console_libraries
    - --config.file=/etc/prometheus/config_out/prometheus.env.yaml
    - --storage.tsdb.path=/prometheus
    - --storage.tsdb.retention.time=24h
    - --web.enable-lifecycle
    - --storage.tsdb.no-lockfile
    - --web.route-prefix=/
    image: 178.104.162.39:443/dev/huayun/amd64/prometheus:v2.20.0
    imagePullPolicy: IfNotPresent

Docker CMD 指令与 ENTRYPOINT 指令的使用与区别

Docker CMD 指令与 ENTRYPOINT 指令的使用与区别

CMD 指令使用测试

cat Dockerfile
FROM centos
CMD ["ls", "-a"]
# 构建镜像
docker build -f Dockerfile -t cmd-test .

# 基于镜像运行容器
docker run cmd-test
.
..
.dockerenv
bin
dev
etc
home
lib
......

# 测试追加命令 ls -al,报错,不能追加
docker run cmd-test -l
Error response from daemon...

# 测试完整命令 ls -al,成功,并且替换了原有的CMD命令
docker run cmd-test ls -al

ENTRYPOINT 指令使用测试

cat Dockerfile
FROM centos
ENTRYPOINT ["ls", "-a"]
# 构建镜像
docker build -f Dockerfile -t entrypoint-test .

# 基于镜像运行容器
docker run entrypoint-test
.
..
.dockerenv
bin
dev
etc
home
lib
......

# 测试追加命令 ls -a -l,成功,直接拼接在了 ENTRYPOINT 命令之后
docker run entrypoint-test -l

Docker ENTRYPOINT变量未结转到CMD中

Docker ENTRYPOINT变量未结转到CMD中

我有一个基本映像,它在ENTRYPOINT shell脚本docker-entry.sh中导出了许多变量.

现在,我使用基本映像并通过mongo-entry.sh运行CMD.我希望在mongo-entry.sh中访问从ENTRYPOINT导出的变量.

我可以看到输出了docker-entry.sh中变量的日志语句,但是我无法在mongo-entry.sh中访问它

我已经尝试在我的DockerFile中将docker-entry.sh和mongo-entry.sh称为ENTRYPOINT

码:

基本映像ENTRYPOINT docker-entry.sh

 export var1 = "var1"

当前图像

FROM 'baseimage'
copY ["mongo-entry.sh"]
CMD ["mongo-entry.sh"]

mongo-entry.sh

echo "var1=$VAR1"

乌普图

var1=
最佳答案
我怀疑有1-2个问题:

> ENTRYPOINT和CMD不是从FROM图像继承的
>您可能正在使用ENTRYPOINT | CMD的exec形式

ENTRYPOINT和CMD有两种形式,即shell和exec形式. exec形式“不调用命令外壳”,因此您将不会获得环境变量处理:

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

这是显示通过FROM’d图像传递的ENV值的示例:

echo '
FROM bash
ENV DOG=Freddie
ENTRYPOINT echo "dog=${DOG}"
' | docker build --tag=1st --file=- .
echo '
FROM 1st
ENV CAT=emmett
ENTRYPOINT echo "dog=${DOG}" "cat=${CAT}"
' | docker build --tag=2nd --file=- .
docker run 1st
docker run 2nd

结果是:

dog=Freddie
dog=Freddie cat=emmett

注意:${DOG}(及其值)是从1st继承的

docker RUN CMD ENTRYPOINT 区别

docker RUN CMD ENTRYPOINT 区别

 

原文链接: docker RUN CMD ENTRYPOINT 区别

上一篇: docker 常用命令

下一篇: Dockerfile中ENTRYPOINT 和 CMD的区别

RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。

CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换。

ENTRYPOINT 配置容器启动时运行的命令。

 

如果在使用docker run 启动容器时使用了命令行参数,那么dockerfile 中的cmd 指令将无效:

通过ENTRYPOINT 指定的命令需要与docker run 启动容器进行搭配,将docker run 指令后面跟的内容当做参数作为ENTRYPOINT指令指定的运行命令的参数,ENTRYPOINT 指定的linux命令一般是不会被覆盖的。

 

Shell 和 Exec 格式

我们可用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令: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

 

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 则两种格式都可以。

 

 

RUN

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

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

RUN 有两种格式:

  1. Shell 格式:RUN

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

下面是使用 RUN 安装多个包的例子:

RUN apt-get update && apt-get install -y \  

 bzr \

 cvs \

 git \

 mercurial \

 subversion

 

注意:apt-get update 和 apt-get install 被放在一个 RUN 指令中执行,这样能够保证每次安装的是最新的包。如果 apt-get install 在单独的 RUN 中执行,则会使用 apt-get update 创建的镜像层,而这一层可能是很久以前缓存的。

CMD

CMD 指令允许用户指定容器的默认执行的命令。

此命令会在容器启动且 docker run 没有指定其他命令时运行。

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

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

CMD 有三种格式:

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

  2. CMD ["param1","param2"] 为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT 必须使用 Exec 格式。

  3. Shell 格式:CMD command param1 param2

Exec 和 Shell 格式前面已经介绍过了。
第二种格式 CMD ["param1","param2"] 要与 Exec 格式 的 ENTRYPOINT 指令配合使用,其用途是为 ENTRYPOINT 设置默认的参数。我们将在后面讨论 ENTRYPOINT 时举例说明。

下面看看 CMD 是如何工作的。Dockerfile 片段如下:

CMD echo "Hello world"

 

运行容器 docker run -it [image] 将输出:

Hello world

 

但当后面加上一个命令,比如 docker run -it [image] /bin/bash,CMD 会被忽略掉,命令 bash 将被执行:

root@10a32dc7d3d3:/#

 

ENTRYPOINT

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

ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执行的命令及其参数。不同的地方在于 ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。

ENTRYPOINT 有两种格式:

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

  2. Shell 格式:ENTRYPOINT command param1 param2

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

Exec 格式

ENTRYPOINT 的 Exec 格式用于设置要执行的命令及其参数,同时可通过 CMD 提供额外的参数。

ENTRYPOINT 中的参数始终会被使用,而 CMD 的额外参数可以在容器启动时动态替换掉。

比如下面的 Dockerfile 片段:

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

CMD ["world"]

 

当容器通过 docker run -it [image] 启动时,输出为:

Hello world

 

而如果通过 docker run -it [image] CloudMan 启动,则输出为:

Hello CloudMan

FROM ubuntu
ENTRYPOINT ["/bin/echo", "Hello"]  
CMD ["world"]

Shell 格式

ENTRYPOINT 的 Shell 格式会忽略任何 CMD 或 docker run 提供的参数。

最佳实践

  1. 使用 RUN 指令安装应用和软件包,构建镜像。

  2. 如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。

  3. 如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。

关于docker 中 entrypoint 和 CMD 的执行总结docker cmd与entrypoint的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Docker -- entrypoint与cmd解析、Docker CMD 指令与 ENTRYPOINT 指令的使用与区别、Docker ENTRYPOINT变量未结转到CMD中、docker RUN CMD ENTRYPOINT 区别的相关信息,请在本站寻找。

本文标签: