在 Dockerfiles 中有两个和我类似的命令: CMD
和 ENTRYPOINT
。但我猜想它们之间存在(细微的?)差异——否则对于同一件事有两个命令是没有任何意义的。
CMD
-
CMD 的主要目的是为执行容器提供默认值。
对于 ENTRYPOINT
:
ENTRYPOINT 可帮助您配置可以作为可执行文件运行的容器。
那么,这两个命令有什么区别呢?
原文由 Golo Roden 发布,翻译遵循 CC BY-SA 4.0 许可协议
在 Dockerfiles 中有两个和我类似的命令: CMD
和 ENTRYPOINT
。但我猜想它们之间存在(细微的?)差异——否则对于同一件事有两个命令是没有任何意义的。
CMD
-
CMD 的主要目的是为执行容器提供默认值。
对于 ENTRYPOINT
:
ENTRYPOINT 可帮助您配置可以作为可执行文件运行的容器。
那么,这两个命令有什么区别呢?
原文由 Golo Roden 发布,翻译遵循 CC BY-SA 4.0 许可协议
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
现在,使用参数运行图像将 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
作为比较,如果您的 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/
原文由 Daishi 发布,翻译遵循 CC BY-SA 3.0 许可协议
2 回答2.5k 阅读✓ 已解决
2 回答856 阅读✓ 已解决
1 回答1.5k 阅读✓ 已解决
2 回答1.4k 阅读
2 回答1.3k 阅读
1 回答1.6k 阅读
1.1k 阅读
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 isubuntu
and the command isbash
.该命令通过入口点运行。即,实际执行的是
/bin/sh -c bash
。这使得 Docker 能够依靠 shell 的解析器快速实现RUN
。后来,人们要求能够定制这个,所以引入了
ENTRYPOINT
和--entrypoint
。在上面的示例中,图像名称
ubuntu
之后的所有内容都是命令并被传递到入口点。当使用CMD
指令时,就好像你正在执行docker run -i -t ubuntu <cmd>
入口点的参数是
<cmd>
。如果您改为键入此命令
docker run -i -t ubuntu
,您也会得到相同的结果:bash shell 将在容器中启动,因为在 ubuntu Dockerfile 中指定了默认值CMD
:CMD ["bash"]
。当一切都传递到入口点时,您可以从图像中获得非常好的行为。 @Jiri 示例很好,它展示了如何将图像用作“二进制”。当使用
["/bin/cat"]
作为入口点,然后执行docker run img /etc/passwd
,你明白了,/bin/cat /etc/passwd
/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
。