Linux入门教程:Dockerfile参考(12) – ENTRYPOINT配置创建容器后执行的容器命令,filebeat配置 例如,下面的示例将


ENTRYPOINT有两种形式:

ENTRYPOINT [“executable”, “param1”, “param2”] [exec形式,首选] ENTRYPOINT command param1 param2 [shell形式]

ENTRYPOINT指令用来配置创建容器时执行的容器命令。
例如,下面的示例将以默认页启动nginx,在80端口监听:

docker run -i -t --rm -p 80:80 nginx

docker run [image]的命令行参数会附加到exec形式ENTRYPOINT所有元素的后面,且会覆盖使用CMD指定的所有元素。这允许命令行参数能够传递到entry point。如docker run [image] -d会传递-d参数到entry point。你可以你使用docker run –entrypoint标志来覆盖ENTRYPOINT指令。
shell形式的ENTRYPOINT能够阻止使用任何CMD或run命令行参数,不过不好的地方是ENTRYPOINT将以/bin/sh -c的子命令执行,且ENTRYPOINT收不到信号。意味着执行的命令的PID不是容器的PID 1 – 收不到来自主机的Unix信号 – 所以无法使用docker stop [container]停止容器。
仅是Dockerfile的最后一个ENTRYPOINT指令起作用。

exec形式ENTRYPOINT示例

你可以使用ENTRYPOINT的exec形式设置稳定的默认命令和参数,然后使用同样形式的CMD设置额外的可以修改的默认参数。

FROM ubuntu ENTRYPOINT ["top", "-b"] CMD ["-c"]

当你运行容器,你会看到top是唯一的进程:

$ docker run -it --rm --name test  top -H top - 08:25:00 up  7:27,  0 users,  load average: 0.00, 0.01, 0.05 Threads:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie %Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st KiB Mem:   2056668 total,  1616832 used,   439836 free,    99352 buffers KiB Swap:  1441840 total,        0 used,  1441840 free.  1324440 cached Mem     PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND     1 root      20   0   19744   2336   2080 R  0.0  0.1   0:00.04 top

我们再看到top的具体参数:

$ docker exec -it test ps aux USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND root         1  2.6  0.1  19752  2352 ?        Ss+  08:24   0:00 top -b -H root         7  0.0  0.1  15572  2164 ?        R+   08:25   0:00 ps aux

并且可以使用docker stop test来停止这个容器。
下面的Dockerfile显示了使用ENTRYPOINT来在前台运行Apache[作为PID 1运行]:

FROM debian:stable RUN apt-get update && apt-get install -y --force-yes apache2 EXPOSE 80 443 VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"] ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

如果你需要为单个可执行程序编辑一个启动脚本,你可以使用exec和gosu命令来确保最终的执行程序能收到Unix信号:

#!/bin/bash set -e   if [ "$1" = 'postgres' ]; then     chown -R postgres "$PGDATA"       if [ -z "$(ls -A "$PGDATA")" ]; then         gosu postgres initdb     fi       exec gosu postgres "$@" fi   exec "$@"

最后,如果你需要在关闭或协调多个可执行程序时做些额外的清理工作,你需要确保ENTRPOINT脚本能够收到Unix信号,捕获它们并做些额外的工作:

#!/bin/sh # Note: I've written this using sh so it works in the busybox container too   # USE the trap if you need to also do manual cleanup after the service is stopped, #     or need to start multiple services in the one container trap "echo TRAPed signal" HUP INT QUIT TERM   # start service in background here /usr/sbin/apachectl start   echo "[hit enter key to exit] or run 'docker stop <container>'" read   # stop service and clean up here echo "stopping apache" /usr/sbin/apachectl stop   echo "exited $0"

如果使用docker run -it –rm -p 80:80 –name test apache运行镜像,可以用docker exec或docker top来检查容器进程,然后请求脚本停止Apache:

$ docker exec -it test ps aux USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND root         1  0.1  0.0   4448   692 ?        Ss+  00:42   0:00 /bin/sh /run.sh 123 cmd cmd2 root        19  0.0  0.2  71304  4440 ?        Ss   00:42   0:00 /usr/sbin/apache2 -k start www-data    20  0.2  0.2 360468  6004 ?        Sl   00:42   0:00 /usr/sbin/apache2 -k start www-data    21  0.2  0.2 360468  6000 ?        Sl   00:42   0:00 /usr/sbin/apache2 -k start root        81  0.0  0.1  15572  2140 ?        R+   00:44   0:00 ps aux $ docker top test PID                 USER                COMMAND 10035               root                {run.sh} /bin/sh /run.sh 123 cmd cmd2 10054               root                /usr/sbin/apache2 -k start 10055               33                  /usr/sbin/apache2 -k start 10056               33                  /usr/sbin/apache2 -k start $ /usr/bin/time docker stop test test real    0m 0.27s user    0m 0.03s sys 0m 0.03s

注意:你可以使用–entrypoint来覆盖ENTRPOINT的设置,不过仅可以二进制到exec,如/usr/sbin/apache2 -k start[不仅调用sh -c执行]

shell形式ENTRYPOINT示例

可以为ENTRYPOINT指定一个纯字符串,它将运行在/bin/sh -c。这种形式将使用shell处理shell环境变量替换,将忽略任何的CMD或docker run命令行参数。为了确保docker stop能够正确发送信号到ENTRPOINT的可执行程序,记得使用exec执行:

FROM ubuntu ENTRYPOINT exec top -b

运行这个镜像后,将会看到这个进程的PID为1:

$ docker run -it --rm --name test top Mem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached CPU:   5% usr   0% sys   0% nic  94% idle   0% io   0% irq   0% sirq Load average: 0.08 0.03 0.05 2/98 6   PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND     1     0 root     R     3164   0%   0% top -b

且可以使用docker stop停止进程:

$ /usr/bin/time docker stop test test real    0m 0.20s user    0m 0.02s sys 0m 0.04s

如果忘记使用exec执行命令:

FROM ubuntu ENTRYPOINT top -b CMD --ignored-param1

然后运行:

$ docker run -it --name test top --ignored-param2 Mem: 1704184K used, 352484K free, 0K shrd, 0K buff, 140621524238337K cached CPU:   9% usr   2% sys   0% nic  88% idle   0% io   0% irq   0% sirq Load average: 0.01 0.02 0.05 2/101 7   PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND     1     0 root     S     3168   0%   0% /bin/sh -c top -b cmd cmd2     7     1 root     R     3164   0%   0% top -b

可以看到top进程的PID为是1了。
并且使用docker stop test不能停止进程:

$ docker exec -it test ps aux PID   USER     COMMAND     1 root     /bin/sh -c top -b cmd cmd2     7 root     top -b     8 root     ps aux $ /usr/bin/time docker stop test test real    0m 10.19s user    0m 0.04s sys 0m 0.03s

ENTRYPOINT和CMD使用建议

1.Dockerfile应该至少指定一个CMD或ENTRYPOINT指令。
2.当使用容器作为可执行程序时,应该定义ENTRYPOINT。
3.CMD应该用来设置ENTRYPOINT的默认参数。
4.当运行容器带有额外参数时,将会覆盖CMD的参数。

相关内容