在扭曲脚本上终止SIGTERM上的Docker容器

时间:2018-11-07 20:47:05

标签: python docker subprocess background-process

我有以下Python脚本,可扭曲docker容器运行:

import subprocess
import sys
import signal

container_id = None

def catch_term(signum, frame):
    sys.stderr.write('Caught SIGTERM. Stopping container\n')
    if container_id != None:
        cmd = ['docker', 'rm', '-f', container_id]
        subprocess.call(cmd)
    sys.exit(143)

signal.signal(signal.SIGTERM, catch_term)
cmd = ['docker', 'run', '--cidfile', cidfile, '-i', image_name, container_process_cmd]
p = subprocess.Popen(cmd)
# This function waits for the file to contain 64 bytes and then reads the container id from it
container_id = get_container_id_from_cidfile(cidfile)
p.communicate()
sys.exit(p.returncode)

当我在交互模式下运行Python进程,并在运行期间杀死该翘曲脚本(kill <PID>)时,会调用catch_term函数并删除容器。然后我的进程退出。

但是 ,当我在后台(即my_warping_script_above.py &)运行变形过程并以相同的方式杀死它时,catch_term函数根本没有被调用,我的脚本一直在运行,包括容器在内。

  • 有什么主意,即使脚本在后台运行也如何调用catch_term函数?

  • 我认为docker run是一个“受保护的”过程。它只能使用docker命令(例如docker rm -f <CONTAINER ID>或使用Ctrl+C(如果与-i一起调用)被杀死。这就是为什么我试图捕获TERM信号并调用docker rm的原因,但是当脚本在后台运行时我的函数没有被调用...(我认为它试图先杀死子进程,然后杀死它失败,它无法达到调用我的注册函数的阶段。

1 个答案:

答案 0 :(得分:0)

回答自己:

此技巧解决了我的问题:在preexec_fn=os.setsid函数中添加subprocess.Popen

p = subprocess.Popen(cmd, preexec_fn=os.setsid)