Docker系列(三)-容器启动讨论
Contents
ENTRYPOINT vs CMD
其实网上已经有许多关于entrypoint与cmd的比较介绍了, 英文中我主要参考了官方文档解释与docker-run-vs-cmd-vs-entrypoint.
文档中是这么说的:
| 1 | An ENTRYPOINT allows you to configure a container that will run as an executable. | 
允许你将容器变成类似可执行文件的运行方式.
| 1 | Command line arguments to docker run <image> will be appended after all elements in an exec form ENTRYPOINT, and will override all elements specified using CMD. | 
docker run <image>之后的参数都会作为entrypoint的参数并且把CMD命令覆盖掉.
下面将会举几个例子, 其中也会包含一些操作:
只有entrypoint
| 1 | FROM debian:buster-slim | 
可以使用下面两个命令对比下效果
| 1 | docker run -ti test | 
CMD与entrypoint配合使用
| 1 | FROM debian:buster-slim | 
直接运行该容器, 效果其实是和
htop -C一样的.
| 1 | docker run -ti test | 
当然也有人这样用:
| 1 | ENTRYPOINT ["echo", "hello"] | 
当然会得到hello world这样的结果, 你可以理解为ENTRYPOINT和CMD共同组成了一条命令, 我们在使用docker run时, 镜像名后面的会被认为是CMD并将Dockerfile中的默认CMD替换掉.
那么, 现在就有一个问题了, 怎么替换entrypoint呢?
启动时替换entrypoint
答案是--entrypoint参数, 注意写在镜像名称前面, 写在后面会被当成是CMD.
| 1 | docker run -ti --entrypoint=/bin/bash <image> | 
一般什么时候会替换CMD或是ENTRYPOINT呢?
这样的用法一般用于调试镜像.
- 编写完Dockerfile后, 无法确定自己的entrypoint与cmd命令正确与否 
- 对于某些无法直接运行的镜像, 需要hack进入镜像, 然后手动的执行命令, 相比于 看日志, 这个应该调试起来更快. 
一个比较简单的ENTRYPOINT写法
从上面的描述中已经可以看出, Docker默认的运行方式是依靠ENTRYPOINT与CMD结合使用的. 所以我们在编写ENTRYPOINT时, 顺便考虑一下CMD的运行可能更好.
下面是我常用的一个entrypoint.sh:
| 1 | 
 | 
这个entrypoint.sh主要用于在运行时确保某个目录被挂载, 而后的exec "$@"会直接运行CMD.