www.icesr.com
IT运维工程师的摇篮

[置顶] 优雅的终止docker容器

起因:

本文受到参考资料1的启发
我们线上的服务有不少都是部署在docker中,部署涉及的机器多大几十台,
服务发布时,要求前一个版本的容器必须优雅的退出。
docker容器中的进程是一个任务消费者。不断得从任务队列中取任务,然后进行执行(执行时间较长)

假定docker容器的name为test_v1
docker容器中的进程名为atm
也就是说不能简单的

<code>docker rm -vf test_v1
docker <span class="hljs-command">run</span> -d <span class="hljs-comment">--name test_v1 test:v1</span></code>

解决方案

1)方案1

首先,我想到的办法是在docker容器外部使用

<code>ps -ef| <span class="hljs-keyword">grep</span> atm |<span class="hljs-keyword">grep</span> -v <span class="hljs-keyword">grep</span> |awk <span class="hljs-string">'{print $2}'</span>|xargs <span class="hljs-keyword">kill</span> -<span class="hljs-number">15</span></code>

容器中的进程捕获 SIGTERM 信号,优雅的退出,发现所有容器中的进程都退出后再执行发布逻辑

缺点:
这个方案肯定是没有问题的,但是如果进程同名,很有可能会导致误杀,而且从docker容器外部,传信号给容器内部的进程,感觉有点奇怪

2)方案2

幸运的看到了参考资料1

<code>root<span class="hljs-variable">@xxxx</span><span class="hljs-symbol">:~/test/docker/test_dk</span><span class="hljs-variable">$ </span>docker stop --help

<span class="hljs-constant">Usage</span><span class="hljs-symbol">:</span> docker stop [<span class="hljs-constant">OPTIONS</span>] <span class="hljs-constant">CONTAINER</span> [<span class="hljs-constant">CONTAINER</span>...]

<span class="hljs-constant">Stop</span> a running container by sending <span class="hljs-constant">SIGTERM</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">then</span> <span class="hljs-constant">SIGKILL</span> after a
grace period

  --help=<span class="hljs-keyword">false</span>       <span class="hljs-constant">Print</span> usage
  -t, --time=<span class="hljs-number">10</span>      <span class="hljs-constant">Seconds</span> to wait <span class="hljs-keyword">for</span> stop before killing it</code>

在docker stop命令执行的时候,会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认的10秒,会继续发送SIGKILL的系统信号强行kill掉进程。在容器中的应用程序,可以选择忽略和不处理SIGTERM信号,不过一旦达到超时时间,程序就会被系统强行kill掉,因为SIGKILL信号是直接发往系统内核的,应用程序没有机会去处理它。在使用docker stop命令的时候,我们唯一能控制的是超时时间,比如设置为20秒超时:

<code>docker <span class="hljs-keyword">stop</span> --<span class="hljs-built_in">time</span>=<span class="hljs-number">20</span> container_name</code>

既然docker 提供了stop命令,那完全可以利用stop命令来实现整个服务的优雅退出
整个demo
https://github.com/vearne/graceful_docker

1. 构建测试docker image
<code><span class="hljs-tag">docker</span> <span class="hljs-tag">pull</span> <span class="hljs-tag">ubuntu</span><span class="hljs-pseudo">:14</span><span class="hljs-class">.04</span>
<span class="hljs-tag">sh</span> <span class="hljs-tag">build</span><span class="hljs-class">.sh</span></code>
2. 程序入口文件
<code><span class="hljs-shebang">#!/bin/sh</span>
<span class="hljs-comment"># 实际运行的工作程序</span>
<span class="hljs-comment"># my test program</span>
nohup python /data/atm.py &amp;

<span class="hljs-function"><span class="hljs-title">prog_exit</span></span>()
{
    ps -ef| grep atm |grep -v grep |awk <span class="hljs-string">'{print $2}'</span>|xargs kill -<span class="hljs-number">15</span>

}
<span class="hljs-comment"># 注册中断处理函数</span>
trap <span class="hljs-string">"prog_exit"</span> <span class="hljs-number">15</span>

flag=<span class="hljs-number">1</span>
<span class="hljs-keyword">while</span> [ <span class="hljs-variable">$flag</span> <span class="hljs-operator">-ne</span> <span class="hljs-number">0</span> ];<span class="hljs-keyword">do</span>
    sleep <span class="hljs-number">3</span>;
    flag=`ps -ef| grep atm |grep -v grep | wc <span class="hljs-operator">-l</span>`
<span class="hljs-keyword">done</span>;</code>
3. 启动容器
<code>sh deploy<span class="hljs-preprocessor">.sh</span></code>

4. 测试是否优雅退出

<code>root<span class="hljs-variable">@xxx</span><span class="hljs-symbol">:~/test/docker/test_dk</span><span class="hljs-variable">$ </span>time docker stop -t <span class="hljs-number">1000</span> test_v1
test_v1

real    0m15.<span class="hljs-number">567</span>s
user    0m<span class="hljs-number">0</span>.<span class="hljs-number">012</span>s
sys 0m<span class="hljs-number">0</span>.<span class="hljs-number">013</span>s</code>

test_v1正常停止

参考资料:

  1. 优雅的终止docker容器

未经允许不得转载:冰点网络 » [置顶] 优雅的终止docker容器

分享到:更多 ()

评论 抢沙发

评论前必须登录!