当我的Dockerfile结束时
CMD node .
docker使用命令运行该容器/bin/sh -c "node ."
而不是简单node .
(我知道,我可以这样做CMD ["node", "."]
).
我认为,这种行为其实是不错的,因为这意味着容器内部PID1
的/bin/sh
,而不是我谦虚节点脚本.
如果我理解正确PID1
负责收割孤儿僵尸进程,我真的不想对此负责......所以如果/bin/sh
能做到这一点,那就太好了.(我实际上认为这就是为什么docker会重写我的原因CMD
).
问题是,当我向SIGTERM
容器发送(开始/bin/sh -c "node ."
)时,无论是通过docker-composer stop
还是docker-composer kill -s SIGTERM
,信号都没有到达我的node
进程,因此每次SIGKILL
在10秒宽限期后都会被强制杀死.不太好.
有没有办法让某人管理我的僵尸并让我的节点实例接收由docker发送的信号?
我认为你必须理解和的角色,ENTRYPOINT
并在你的角色中CMD
使用ENTRYPOINT
(exec形式)方式Dockerfile
.
ENTRYPOINT
,指定容器的起始可执行文件,是Docker容器的核心部分.每个容器必须有一个入口点来决定从哪里开始.默认情况下,该值为/bin/bash -c
.此外,设置的所有内容都CMD
将ENTRYPOINT
作为参数附加.
因此,如果您未能ENTRYPOINT
在您的指定中指定Dockerfile
实际的入口点,那么/bin/bash -c {your_command_in_CMD}
遗憾的是它不会传递信号.
ENTRYPOINT
有两种形式:exec形式和shell形式
exec形式:ENTRYPOINT ["executable","param1","param2"]
shell form:命令param1 param2
正如Docker引用所指出的那样:建议使用exec表单,而shell表单的缺点是命令执行/bin/bash -c
,这可能不适用于信号:
所述壳形式防止任何
CMD
或run
被使用命令行参数,但是具有你的缺点ENTRYPOINT
将被开始作为一个子命令/bin/sh -c
,其不通过信号.这意味着可执行文件不会是容器PID 1
- 并且不会收到Unix信号 - 因此您的可执行文件将不会收到SIGTERM
来自docker stop
.