Shell形式的ENTRYPOINT示例

可以使用ENTRYPOINT指定一个纯字符串形式的命令,它会在/bin/sh -c中执行。这样形式将使用shell处理来进行环境变量的替换,并且它会忽视任何在CMDdocker run命令行中指定的参数。为了确保docker stop可以给长期运行的ENTRYPOINT可执行程序正确发送信号,我们需要记住通过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

如果我们忘记在shell形式的ENTRYPOINT中添加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,容器并不会干净地退出。当退出超时以后,stop命令将强制发送一个SIGKILL信号来终止进程:

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

Last updated