终于搞清楚了。
RUN 用在参与构建镜像过程中,每次运行 RUN 都会形成一个镜像层。比如:
dockerfileRUN apt update && apt -y install apache2
CMD 用于指定启动一个容器时,默认执行的命令。它可以被docker run
所指定的命令行覆盖,比如:
dockerfileCMD ["apache2ctl", "-DFOREGROUND"]
当在命令行中运行docker run -it <image> /bin/bash
时,实际上会执行 bash 而不是 apache2ctl。
ENTRYPOINT 用于指定默认的可执行文件,docker run
中提供的命令行都会追加给 ENTRYPOINT。可以使用--entrypoint
来覆盖默认的 ENTRYPOINT。
dockerfileENTRYPOINT ["my_script"]
CMD 可以作为 ENTRYPOINT 的默认参数,但是要使用 exec 形式。
dockerfileENTRYPOINT ["python", "/app/my_script.py"] CMD ["--default-arg"]
如果用户想要覆盖默认参数,可以这样docker run myimage --user-arg
,这样实际在执行python /app/my_script.py --user-arg
。
exec 形式:CMD ["executable","param1","param2"]
shell 形式:CMD command param1 param2
shell 形式其实是利用/bin/sh -c
启动一个 subshell 来运行命令,优点是可以在参数中使用变量扩展,缺点是导致 shell 成为容器中 pid 为 1 的进程,而大多数 shell 不会转发信号给子进程,那么目标程序无法处理信号,比如SIGTERM
。
pid 1 的进程负责管理其他进程和处理来自 Docker host 的信号。
exec 形式其实是直接执行指定的可执行文件,由于其就是 pid 为 1 的进程,可以处理信号。
本文作者:jdxj
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!