優雅的終止docker容器

重要
我的博客從今天起開始陸續遷移到
http://vearne.cc
敬請關注

起因:

本文受到參考資料1的啓發
我們線上的服務有不少都是部署在docker中,部署涉及的機器多大幾十臺,
服務發佈時,要求前一個版本的容器必須優雅的退出。
docker容器中的進程是一個任務消費者。不斷得從任務隊列中取任務,然後進行執行(執行時間較長)

假定docker容器的name爲test_v1
docker容器中的進程名爲atm
也就是說不能簡單的

docker rm -vf test_v1
docker run -d --name test_v1 test:v1

解決方案

1)方案1

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

ps -ef| grep atm |grep -v grep |awk '{print $2}'|xargs kill -15

容器中的進程捕獲 SIGTERM 信號,優雅的退出,發現所有容器中的進程都退出後再執行發佈邏輯

缺點:
這個方案肯定是沒有問題的,但是如果進程同名,很有可能會導致誤殺,而且從docker容器外部,傳信號給容器內部的進程,感覺有點奇怪

2)方案2

幸運的看到了參考資料1

root@xxxx:~/test/docker/test_dk$ docker stop --help

Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]

Stop a running container by sending SIGTERM and then SIGKILL after a
grace period

  --help=false       Print usage
  -t, --time=10      Seconds to wait for stop before killing it

在docker stop命令執行的時候,會先向容器中PID爲1的進程發送系統信號SIGTERM,然後等待容器中的應用程序終止執行,如果等待時間達到設定的超時時間,或者默認的10秒,會繼續發送SIGKILL的系統信號強行kill掉進程。在容器中的應用程序,可以選擇忽略和不處理SIGTERM信號,不過一旦達到超時時間,程序就會被系統強行kill掉,因爲SIGKILL信號是直接發往系統內核的,應用程序沒有機會去處理它。在使用docker stop命令的時候,我們唯一能控制的是超時時間,比如設置爲20秒超時:

docker stop --time=20 container_name

既然docker 提供了stop命令,那完全可以利用stop命令來實現整個服務的優雅退出
整個demo
https://github.com/vearne/graceful_docker

1. 構建測試docker image
docker pull ubuntu:14.04
sh build.sh
2. 程序入口文件
#!/bin/sh
# 實際運行的工作程序
# my test program
nohup python /data/atm.py &

prog_exit()
{
    ps -ef| grep atm |grep -v grep |awk '{print $2}'|xargs kill -15

}
# 註冊中斷處理函數
trap "prog_exit" 15

flag=1
while [ $flag -ne 0 ];do
    sleep 3;
    flag=`ps -ef| grep atm |grep -v grep | wc -l`
done;
3. 啓動容器
sh deploy.sh

4. 測試是否優雅退出

root@xxx:~/test/docker/test_dk$ time docker stop -t 1000 test_v1
test_v1

real    0m15.567s
user    0m0.012s
sys 0m0.013s

test_v1正常停止

參考資料:

  1. 優雅的終止docker容器

重要
我的博客從今天起開始陸續遷移到
http://vearne.cc
敬請關注

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章