这就是我构建docker图像的方式:
docker build -f Dockerfile -t python-trapterm .
这就是我如何运行它:
docker run -t python-trapterm:latest
我尝试用
来阻止它 docker stop -t 120 sharp_jones
我希望在容器关闭之前有大约2分钟的运行时间。但它几乎立即关闭?为什么呢?
这是容器进程的输出:
> docker run -t python-trapterm:latest
Setting traps...
* Starting NTP server ntpd [ OK ]
2017-09-10 06:43:02,501 pid 26 tid 140693944227584 INFO greatapp Registering signal handler
2017-09-10 06:43:02,502 pid 26 tid 140693944227584 INFO greatapp Hello!
2017-09-10 06:43:04,507 pid 26 tid 140693944227584 INFO greatapp Checking every 2s...
2017-09-10 06:43:06,510 pid 26 tid 140693944227584 INFO greatapp Checking every 2s...
2017-09-10 06:43:08,512 pid 26 tid 140693944227584 INFO greatapp Checking every 2s...
[snip]
2017-09-10 06:44:12,629 pid 26 tid 140693944227584 INFO greatapp Checking every 2s...
2017-09-10 06:44:14,631 pid 26 tid 140693944227584 INFO greatapp Checking every 2s...
Sending term to 26...
2017-09-10 06:44:16,537 pid 26 tid 140693944227584 INFO greatapp Handling shutdown...15
2017-09-10 06:44:16,538 pid 26 tid 140693944227584 INFO greatapp Checking every 2s...
2017-09-10 06:44:16,539 pid 26 tid 140693944227584 INFO greatapp Handling shutdown...10
2017-09-10 06:44:16,539 pid 26 tid 140693944227584 INFO greatapp Checking every 2s...
您可以在06:44:16左右收到TERM信号,但是工作已经在06:44:14左右关闭,但是在06:44:16之后该过程终止了。没有等待10秒钟。
这是我的泊坞文件:
FROM ubuntu:16.04
RUN apt-get update --fix-missing && apt-get install -y \
git \
python \
python-pip \
ntp \
curl vim screen lsof
RUN mkdir -p /app
COPY ./app /app
CMD ["/app/start-app.sh"]
以下是app
目录中的两个文件:
应用/ start-app.sh
#!/bin/bash
set -eo pipefail
echo "Setting traps..."
trap 'cleanup_term' TERM
trap 'cleanup_kill' KILL
cleanup_term() {
echo "Sending term to `jobs -p`..."
kill -TERM `jobs -p`
kill -USR1 `jobs -p`
}
cleanup_kill() {
echo "Received kill..."
kill -TERM `jobs -p`
}
service ntp start
cd /app
python -m greatapp &
wait
和
应用/ greatapp.py
import os
import time
import logging
import signal
LOG_FORMAT = "%(asctime)-15s pid %(process)d tid %(thread)4d %(levelname)-8s" \
" %(module)-8s %(message)s"
logging.basicConfig(format=LOG_FORMAT)
LOG = logging.getLogger(__file__)
LOG.setLevel(logging.DEBUG)
def docker_shutdown_handler(_signum, _frame):
LOG.info("Handling shutdown...%s", _signum)
# sys.exit()
LOG.info('Registering signal handler')
signal.signal(signal.SIGTERM, docker_shutdown_handler)
signal.signal(signal.SIGUSR1, docker_shutdown_handler)
def main():
LOG.info("Hello!")
sleep_time = 2
while True:
time.sleep(sleep_time)
LOG.info("Checking every %ds...", sleep_time)
if __name__ == '__main__':
main()
答案 0 :(得分:1)
您的shell脚本正在退出。当发生这种情况时,由于它是pid 1,容器会立即退出。如果将以下内容添加到脚本顶部,则可以看到此内容:
trap 'echo Script exiting' EXIT
很可能这是bash中SIGKILL的默认操作,因为它在最后一次等待之后没有运行任何命令。快速解决此问题的方法是向清理函数添加等待,以便信号处理程序挂起:
cleanup_term() {
echo "Sending term to `jobs -p`..."
kill -TERM `jobs -p`
kill -USR1 `jobs -p`
echo "waiting again"
wait
echo "cleanup_term done"
}
或者我建议只执行python脚本,以便直接处理信号并消除pid 1中的bash。然后start-app.sh看起来像:
#!/bin/bash
set -eo pipefail
service ntp start
cd /app
exec python -m greatapp