Dockerfile中的CMD和ENTRYPOINT有什么区别?
在Dockerfiles中有两个看起来类似于我的命令: CMD
和ENTRYPOINT
。 但我猜他们之间有一个(微妙的)区别 - 否则就同一事物而言,有两个命令是没有意义的。
该文件规定了CMD
CMD的主要目的是为执行容器提供默认值。
和ENTRYPOINT
:
ENTRYPOINT可帮助您配置可作为可执行文件运行的容器。
那么,这两个命令有什么区别?
Docker的默认入口点是/bin/sh -c
但没有默认命令。
当你像这样运行docker时: docker run -i -t ubuntu bash
入口点是默认的/bin/sh -c
,映像是ubuntu
,命令是bash
。
该命令通过入口点运行。 即,执行的实际内容是/bin/sh -c bash
。 这允许Docker依靠shell的解析器快速实现RUN
。
后来,人们要求能够自定义这个,所以引入了ENTRYPOINT
和--entrypoint
。
在上面的例子中, ubuntu
之后的所有东西都是命令并传递给入口点。 当使用CMD
指令时,就像你在做docker run -i -t ubuntu <cmd>
。 <cmd>
将是入口点的参数。
如果你输入这个命令docker run -i -t ubuntu
你也会得到相同的结果。 由于Ubuntu的Dockerfile指定了一个默认的CMD: CMD ["bash"]
你仍然会在容器中启动一个bash shell。
随着一切都传递到入口点,您可以从图像中获得非常好的行为。 @Jiri示例很好,它显示了如何将图像用作“二进制”。 当使用["/bin/cat"]
作为入口点,然后执行docker run img /etc/passwd
,就会得到它, /etc/passwd
是命令并传递到入口点,因此最终结果执行只是/bin/cat /etc/passwd
。
另一个例子是将任何cli作为入口点。 例如,如果你有一个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
。
ENTRYPOINT
指定一个在容器启动时总是执行的命令。
CMD
指定将被馈送到进入点的ENTRYPOINT
。
如果要制作专用于特定命令的图像,您将使用ENTRYPOINT ["/path/dedicated_command"]
否则,如果要为通用目的制作图像,可以不指定ENTRYPOINT
并使用CMD ["/path/dedicated_command"]
因为您可以通过向docker run
提供参数来覆盖设置。
例如,如果你的Dockerfile是:
FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["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
现在,运行带有参数的图像将平息该参数:
$ 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
为了比较,如果你的Dockerfile是:
FROM debian:wheezy
CMD ["/bin/ping", "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
但用参数运行映像将运行该参数:
docker run -it test bash
root@e8bb7249b843:/#
有关更多详细信息,请参阅Brian DeHamer撰写的这篇文章:https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/
是的,这是一个很好的问题。 我还没有完全理解它,但是:
我知道ENTRYPOINT
是正在执行的二进制文件。 您可以通过--entrypoint =“”来覆盖入口点。
docker run -t -i --entrypoint="/bin/bash" ubuntu
CMD是容器的默认参数。 没有入口点,默认参数是执行的命令。 通过入口点,cmd作为参数传递给入口点。 您可以使用入口点模拟命令。
# no entrypoint
docker run ubuntu /bin/cat /etc/passwd
# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd
所以,主要的好处是通过入口点你可以将参数(cmd)传递给你的容器。 要做到这一点,你需要使用两个:
# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]
和
docker build -t=cat .
那么你可以使用:
docker run cat /etc/passwd
# ^^^^^^^^^^^
# CMD
# ^^^
# image (tag)- using the default ENTRYPOINT
链接地址: http://www.djcxy.com/p/30133.html
上一篇: What is the difference between CMD and ENTRYPOINT in a Dockerfile?
下一篇: In Docker, what's the difference between a container and an image?