尽管`-t 120`设置,Docker几乎立即停止关闭容器

时间:2017-09-10 03:26:05

标签: docker

这就是我构建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()

1 个答案:

答案 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