sleep 当然,它是大多数复杂过程的替代品。
这个 Dockerfile(如您所见,使用 exec 形式,因此只有一个进程在运行,并且没有 的子进程bash):
FROM busybox
CMD ["/bin/sleep", "100000"]
Run Code Online (Sandbox Code Playgroud)
创建一个不间断的容器:
docker build -t kill-sleep .
docker run --rm --name kill-sleep kill-sleep
Run Code Online (Sandbox Code Playgroud)
当我试图阻止它时:
time docker stop kill-sleep
kill-sleep
real 0m10.449s
user 0m0.021s
sys 0m0.027s
Run Code Online (Sandbox Code Playgroud)
命令在容器被杀死前 10 秒超时。
问题不在于sleep不处理信号,因为如果我在主机上运行它:
sleep 100000
# in another shell
ps faxww | grep sleep
kill -TERM 31333 # the PID
Run Code Online (Sandbox Code Playgroud)
该过程立即停止。
问题可能与它在容器中作为 PID 1 运行的事实有关,但我还没有看到相关的参考文档。
当你运行时docker stop ...,会发生一些事情:
docker将 a 发送SIGTERM到容器的主进程。该进程能够屏蔽/忽略 a SIGTERM,如果它这样做(或在不终止的情况下处理它)“什么都不会发生”。docker向SIGKILL主进程发送一个。该信号不能被进程屏蔽,因此它立即死亡,没有机会执行关闭程序。理想情况下,在其中运行的进程docker将SIGTERM及时响应,在终止之前处理所有内务。
如果您知道该进程要么没有任何内务要执行(例如:)sleep,要么不会正确响应SIGTERM,您可以使用-t标志指定更短(或更长)的超时:
Run Code Online (Sandbox Code Playgroud)-t, --time=10 Seconds to wait for stop before killing it
例如,在您的情况下,您可能希望运行docker stop -t 0 ${CONTAINER}.
此信号行为不同的原因是由于在sleepPID = 1 下运行。
通常(例如:以 PID != 1 运行),进程未明确处理的任何信号都会导致进程终止 - 尝试发送sleepa SIGUSR1。
但是,当以 PID = 1 运行时,未处理的信号将被忽略,否则最终会出现内核恐慌:
Kernel panic - not syncing: Attempted to kill init!
Run Code Online (Sandbox Code Playgroud)
您可以使用 docker 工具向 docker 容器发送信号,例如:
docker kill -s TERM kill-sleep
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,这没有达到预期的效果,而这样做:
docker kill -s KILL kill-sleep
Run Code Online (Sandbox Code Playgroud)
-t, --time=10
Seconds to wait for stop before killing it
Run Code Online (Sandbox Code Playgroud)
Kernel panic - not syncing: Attempted to kill init!
Run Code Online (Sandbox Code Playgroud)
现在,运行
docker kill -s TERM kill-sleep
Run Code Online (Sandbox Code Playgroud)
这在另一个终端中:
docker kill -s KILL kill-sleep
Run Code Online (Sandbox Code Playgroud)
我们观察到相同的 10 秒延迟/超时。
现在让我们处理SIGTERM. Backgrounding和wait荷兰国际集团为sleep是由于POSIX外壳手柄信号是如何(见这为更多)。
FROM busybox
COPY run.sh /run.sh
RUN chmod +x /run.sh
CMD "/run.sh"
Run Code Online (Sandbox Code Playgroud)
再次运行命令,我们就会看到我们所追求的!
#!/bin/sh
echo "sleeping"
sleep 100000
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16921 次 |
| 最近记录: |