Ddockerfile里的CMD和ENTRYPOINT的区别(图文介绍,超详细)

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

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

1。在Dockerfile中,只能有一个ENTRYPOINT指令,如果有多个ENTRYPOINT指令则以最后一个为准。
2。在Dockerfile中,只能有一个CMD指令,如果有多个CMD指令则以最后一个为准。
3。在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 … 的参数都将被忽略。

采用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

CMD

意思是,cmd给出的是一个容器的默认的可执行体。也就是容器启动以后,默认的执行的命令。重点就是这个“默认”。意味着,如果docker run没有指定任何的执行命令或者dockerfile里面也没有entrypoint,那么,就会使用cmd指定的默认的执行命令执行。同时也从侧面说明了entrypoint的含义,它才是真正的容器启动以后要执行命令。
所以这句话就给出了cmd命令的一个角色定位,它主要作用是默认的容器启动执行命令。(注意不是“全部”作用)

这也是为什么大多数网上博客论坛说的“cmd会被覆盖”,其实为什么会覆盖?因为cmd的角色定位就是默认,如果你不额外指定,那么就执行cmd的命令,否则呢?只要你指定了,那么就不会执行cmd,也就是cmd会被覆盖。

shell form,即没有中括号的形式。那么命令command默认是在“/bin/sh -c”下执行的。比如下面的dockerfile:
	FROM centos
 
	CMD echo "美少女万华镜"

在这里插入图片描述
如果带中括号的话,这时,命令没有再任何shell终端环境下,我们要执行shell,就必须加入到中括号中。
需要注意,采用中括号形式,那么第一个参数必须是命令的全路径才行。而且,一个dockerfile至多只能有一个cmd,如果有多个,只有最后一个生效。
官网推荐采用这种方法。

	FROM centos
	ENV name=美少女万华镜之罪与罚
	CMD ["/bin/echo","hello,$name"]

在这里插入图片描述
如果再run后面添加了参数,那么默认的CMD就会被覆盖
在这里插入图片描述
命令行和shell。
先看命令行模式,也就是带中括号的。和cmd的中括号形式是一致的,但是这里貌似是在shell的环境下执行的,与cmd有区别。

2。如果run后面没有额外的参数,但是cmd有,那么cmd的全部内容会作为entrypoint的参数

FROM centos
CMD ["勿忘草与永远的少女"]
ENTRYPOINT ["echo"]

在这里插入图片描述

1。如果run命令后面有参数,那么run后面的全部都会作为entrypoint的参数

```bash
FROM centos
CMD ["勿忘草与永远的少女"]
ENTRYPOINT ["echo"]

在这里插入图片描述
这同时是cmd的第二种用法。这也是网上说的entrypoint不会被覆盖。当然如果要在run里面覆盖,也是有办法的,使用–entrypoint即可。

1。加了中括号为exec写法(如图)

该写法不能实现变量

在这里插入图片描述

结果:

在这里插入图片描述

2。不加中括号为shell写法(如图)

该写法可以实现变量

在这里插入图片描述

结果:

在这里插入图片描述

3。如果用exec写法还想实现变量,就需要在里面加shell写法(如图)

注意,这里先说下思路,但在理清思路之前先看下sh -c的作用sh -c的必要性不懂的可以点击蓝色字体看一下。

很明显中括号里面的参数使用引号包起来的,空格之间用逗号隔开,然后需要实现变量的话,是把shell命令放在同一个引号内

在这里插入图片描述

结果

在这里插入图片描述

喜欢的话,记得点赞哟,23333

在这里插入图片描述

发布了13 篇原创文章 · 获赞 8 · 访问量 578
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章