我正在一个Windows docker容器内运行Python循环的非常基础的示例,我希望能够实现优雅停止。
在我的dockerfile中,脚本是这样启动的:
CMD [ "python.exe" , "./test.py"]
在Docker文档中,它说会向主要命令发送SIGTERM信号,因此我尝试以如下方式捕获它:
import signal
import time
import logging, sys
class GracefulKiller:
kill_now = False
def __init__(self):
signal.signal(signal.SIGINT, self.exit_gracefully)
signal.signal(signal.SIGTERM, self.exit_gracefully)
def exit_gracefully(self,signum, frame):
self.kill_now = True
if __name__ == '__main__':
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
killer = GracefulKiller()
while True:
time.sleep(1)
logging.info("doing something in a loop ...")
if killer.kill_now:
break
logging.info("End of the program. I was killed gracefully :)")
在理论上,信号应该被处理程序捕获,布尔值应该切换并且循环应该退出并显示我的最后一个日志行。但事实并非如此,它只是在信号被发出时(或者稍后2-3秒)就停止了整个过程。C:\Users\Administrator\Documents\Projects\test>docker-compose up
Recreating test_1 ... done
Attaching to test_1
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
test_1 | INFO:root:doing something in a loop ...
Gracefully stopping... (press Ctrl+C again to force)
Stopping test_1 ... done
我的最后一行日志从未到达。有人知道发生了什么吗?这是Python特定问题,Docker特定还是Windows特定?
我还尝试使用docker logs检查停止的容器,最后一条日志也不在这里。尝试添加延迟后,结果相同。
谢谢,
docker-compose
让这个工作了吗? - Gino Mempin