Dockerfile中的CMD和ENTRYPOINT有什么区别?

本文翻译自:What is the difference between CMD and ENTRYPOINT in a Dockerfile?

In Dockerfiles there are two commands that look similar to me: CMD and ENTRYPOINT . 在Dockerfiles中,有两个与我相似的命令: CMDENTRYPOINT But I guess that there is a (subtle?) difference between them - otherwise it would not make any sense to have two commands for the very same thing. 但是我想它们之间有一个(细微的?)差异-否则对于同一件事有两个命令是没有任何意义的。

The documentation states for CMD CMD的文档状态

The main purpose of a CMD is to provide defaults for an executing container. CMD的主要目的是为执行中的容器提供默认值。

and for ENTRYPOINT : 对于ENTRYPOINT

An ENTRYPOINT helps you to configure a container that you can run as an executable. ENTRYPOINT帮助您配置可以作为可执行文件运行的容器。

So, what's the difference between those two commands? 那么,这两个命令有什么区别?


#1楼

参考:https://stackoom.com/question/1SR0j/Dockerfile中的CMD和ENTRYPOINT有什么区别


#2楼

Yes, that is a good question. 是的,这是一个好问题。 I don't understand it fully yet, but: 我尚不完全了解,但是:

I understand that ENTRYPOINT is the binary that is being executed. 我了解ENTRYPOINT是正在执行的二进制文件。 You can overide entrypoint by --entrypoint="". 您可以通过--entrypoint =“”覆盖入口点。

docker run -t -i --entrypoint="/bin/bash" ubuntu

CMD is the default argument to container. CMD是容器的默认参数。 Without entrypoint, default argument is command that is executed. 没有入口点,默认参数是执行的命令。 With entrypoint, cmd is passed to entrypoint as argument. 使用入口点,cmd作为参数传递到入口点。 You can emulate a command with entrypoint. 您可以使用入口点模拟命令。

# no entrypoint
docker run ubuntu /bin/cat /etc/passwd

# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd

So, main advantage is that with entrypoint you can pass arguments (cmd) to your container. 因此,主要优点是可以通过入口点将参数(cmd)传递到容器。 To accomplish this, you need to use both: 为此,您需要同时使用以下两者:

# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]

and

docker build -t=cat .

then you can use: 那么您可以使用:

docker run cat /etc/passwd
#              ^^^^^^^^^^^
#                   CMD
#          ^^^      
#          image (tag)- using the default ENTRYPOINT

#3楼

Docker has a default entrypoint which is /bin/sh -c but does not have a default command. Docker的默认入口点是/bin/sh -c但没有默认命令。

When you run docker like this: docker run -i -t ubuntu bash the entrypoint is the default /bin/sh -c , the image is ubuntu and the command is bash . 当您像这样运行docker时: docker run -i -t ubuntu bash入口点是默认的/bin/sh -c ,映像是ubuntu ,命令是bash

The command is run via the entrypoint. 该命令通过入口点运行。 ie, the actual thing that gets executed is /bin/sh -c bash . 即,实际执行的是/bin/sh -c bash This allowed Docker to implement RUN quickly by relying on the shell's parser. 这使Docker可以依靠Shell的解析器快速实现RUN

Later on, people asked to be able to customize this, so ENTRYPOINT and --entrypoint were introduced. 后来,人们要求能够对其进行自定义,因此引入了ENTRYPOINT--entrypoint

Everything after ubuntu in the example above is the command and is passed to the entrypoint. 上例中ubuntu之后的所有内容均为命令,并传递给入口点。 When using the CMD instruction, it is exactly as if you were doing docker run -i -t ubuntu <cmd> . 使用CMD指令时,就像您在执行docker run -i -t ubuntu <cmd> <cmd> will be the parameter of the entrypoint. <cmd>将是入口点的参数。

You will also get the same result if you instead type this command docker run -i -t ubuntu . 如果您改为输入此命令docker run -i -t ubuntu也会得到相同的结果。 You will still start a bash shell in the container because of the ubuntu Dockerfile specified a default CMD: CMD ["bash"] 由于ubuntu Dockerfile指定了默认的CMD,因此您仍将在容器中启动bash shell: CMD ["bash"]

As everything is passed to the entrypoint, you can have a very nice behavior from your images. 当所有内容都传递到入口点时,您的图像会表现出很好的行为。 @Jiri example is good, it shows how to use an image as a "binary". @Jiri示例很好,它显示了如何将图像用作“二进制”。 When using ["/bin/cat"] as entrypoint and then doing docker run img /etc/passwd , you get it, /etc/passwd is the command and is passed to the entrypoint so the end result execution is simply /bin/cat /etc/passwd . 当使用["/bin/cat"]作为入口点,然后执行docker run img /etc/passwd ,会得到/etc/passwd是命令并传递到入口点,因此最终结果执行是/bin/cat /etc/passwd

Another example would be to have any cli as entrypoint. 另一个示例是将任何cli作为入口点。 For instance, if you have a redis image, instead of running docker run redisimg redis -H something -u toto get key , you can simply have ENTRYPOINT ["redis", "-H", "something", "-u", "toto"] and then run like this for the same result: docker run redisimg get key . 例如,如果您有一个redis映像,而不是docker run redisimg redis -H something -u toto get key ,则只需ENTRYPOINT ["redis", "-H", "something", "-u", "toto"] ,然后像这样docker run redisimg get key相同的结果: docker run redisimg get key


#4楼

The ENTRYPOINT specifies a command that will always be executed when the container starts. ENTRYPOINT指定在容器启动时将始终执行的命令。

The CMD specifies arguments that will be fed to the ENTRYPOINT . CMD指定将提供给ENTRYPOINT

If you want to make an image dedicated to a specific command you will use ENTRYPOINT ["/path/dedicated_command"] 如果要使图像专用于特定命令,则将使用ENTRYPOINT ["/path/dedicated_command"]

Otherwise, if you want to make an image for general purpose, you can leave ENTRYPOINT unspecified and use CMD ["/path/dedicated_command"] as you will be able to override the setting by supplying arguments to docker run . 否则,如果要制作通用图像,则可以不指定ENTRYPOINT并使用CMD ["/path/dedicated_command"]因为您可以通过向docker run提供参数来覆盖设置。

For example, if your Dockerfile is: 例如,如果您的Dockerfile是:

FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]

Running the image without any argument will ping the localhost: 运行不带任何参数的映像将对localhost进行ping:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms

Now, running the image with an argument will ping the argument: 现在,使用参数运行图像将对参数进行ping:

$ docker run -it test google.com
PING google.com (173.194.45.70): 48 data bytes
56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
^C--- google.com ping statistics ---
5 packets transmitted, 3 packets received, 40% packet loss
round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms

For comparison, if your Dockerfile is: 为了进行比较,如果您的Dockerfile是:

FROM debian:wheezy
CMD ["/bin/ping", "localhost"]

Running the image without any argument will ping the localhost: 运行不带任何参数的映像将对localhost进行ping:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms

But running the image with an argument will run the argument: 但是使用参数运行图像将运行参数:

docker run -it test bash
root@e8bb7249b843:/#

See this article from Brian DeHamer for even more details: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/ 有关更多详细信息,请参阅Brian DeHamer的这篇文章: https ://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/


#5楼

CMD: CMD:

  • CMD ["executable","param1","param2"] : ["executable","param1","param2"] is the first process. CMD ["executable","param1","param2"]["executable","param1","param2"]是第一个过程。
  • CMD command param1 param2 : /bin/sh -c CMD command param1 param2 is the first process. CMD command param1 param2/bin/sh -c CMD command param1 param2是第一个过程。 CMD command param1 param2 is forked from the first process. CMD command param1 param2是从第一个进程派生的。
  • CMD ["param1","param2"] : This form is used to provide default arguments for ENTRYPOINT . CMD ["param1","param2"] :此格式用于为ENTRYPOINT提供默认参数。

ENTRYPOINT (The following list does not consider the case where CMD and ENTRYPOINT are used together): ENTRYPOINT(以下列表未考虑将CMD和ENTRYPOINT一起使用的情况):

  • ENTRYPOINT ["executable", "param1", "param2"] : ["executable", "param1", "param2"] is the first process. ENTRYPOINT ["executable", "param1", "param2"]["executable", "param1", "param2"]是第一个过程。
  • ENTRYPOINT command param1 param2 : /bin/sh -c command param1 param2 is the first process. ENTRYPOINT command param1 param2/bin/sh -c command param1 param2是第一个进程。 command param1 param2 is forked from the first process. command param1 param2是从第一个进程派生的。

As creack said, CMD was developed first. 正如creack所说,CMD是最早开发的。 Then ENTRYPOINT was developed for more customization. 然后开发了ENTRYPOINT以进行更多的自定义。 Since they are not designed together, there are some functionality overlaps between CMD and ENTRYPOINT, which often confuse people. 由于它们不是一起设计的,因此CMD和ENTRYPOINT之间存在一些功能重叠,这通常会使人们感到困惑。


#6楼

Comments on EntryPoint function in code 代码中对EntryPoint函数的注释

// ENTRYPOINT /usr/sbin/nginx. // ENTRYPOINT / usr / sbin / nginx。

// Set the entrypoint (which defaults to sh -c) to /usr/sbin/nginx. //将入口点(默认为sh -c)设置为/ usr / sbin / nginx。

// Will accept the CMD as the arguments to /usr/sbin/nginx. //将接受CMD作为/ usr / sbin / nginx的参数。

Another reference from documents 文件中的另一个参考

You can use the exec form of ENTRYPOINT to set fairly stable default commands and arguments and then use CMD to set additional defaults that are more likely to be changed. 您可以使用ENTRYPOINT的exec形式设置相当稳定的默认命令和参数 ,然后使用CMD设置更可能被更改的其他默认值。

Example: 例:

FROM ubuntu:14.04.3
ENTRYPOINT ["/bin/ping"]
CMD ["localhost", "-c", "2"]

Build : sudo docker build -t ent_cmd . 构建 :sudo docker build -t ent_cmd。

CMD arguments are easy to override.

NO argument (sudo docker -it ent_cmd)                :  ping localhost 
argument    (sudo docker run -it ent_cmd google.com) :  ping google.com

.

To override EntryPoint argument, you need to supply entrypoint
sudo docker run -it --entrypoint="/bin/bash" ent_cmdd

ps: In presence of EntryPoint, CMD will hold arguments to fed to EntryPoint. ps:在存在EntryPoint的情况下,CMD将保存要馈送到EntryPoint的参数。 In absense of EntryPoint, CMD will be the command which will be run. 在缺少EntryPoint的情况下,将运行CMD。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值