我有一个简单的 Python 进程在 Docker 容器中运行:
Dockerfile:
FROM ubuntu:18.04
RUN apt -y update && apt -y install python3
COPY app.py /app/
WORKDIR /app
ENTRYPOINT ["./app.py"]
应用程序.py:
#!/usr/bin/env python3
if __name__ == '__main__':
while True:
pass
它运行得很好。但是,我注意到该过程不受SIGTERM
. IE,
# In container
kill -s TERM `pgrep python3`
没有做任何事情。然而,
kill -s INT `pgrep python3`
KeyboardInterrupt
正如预期的那样,在此过程中提出了 a 。
我跑了
grep Sig /proc/`pgrep python3`/status
在容器中得到
SigQ: 1/127222
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000001001000
SigCgt: 0000000180000002
SIGTERM
已经15了,为什么还没有通过呢?如果我在我的主机(也是 Ubuntu)中运行 Python 脚本,则会SIGTERM
按预期杀死它。
答案1
由于 Docker 容器没有init
进程,因此 Python 进程以 PID 1 运行。根据man 2 kill
,
唯一可以发送到进程 ID 1(即 init 进程)的信号是 init 已显式安装信号处理程序的信号。这样做是为了确保系统不会意外崩溃。
之所以SIGINT
有效,是因为 Python 为该信号注册了一个处理程序。所以,你可以做类似的事情:
#!/usr/bin/env python3
import signal
def handler(signum, frame):
print('Exiting')
exit(0)
if __name__ == '__main__':
signal.signal(signal.SIGTERM, handler)
while True:
pass
或者,您可以告诉 Docker 使用进程运行容器init
:
docker run -it --init my_image