通过信号解决docker启动容器后Exited退出的问题

前言:

      嗯哼,前段时间公司搞Docker的那位架构师走了,我们公司用40台实体服务器做了Docker的服务组,量级不是太大,上面的容器在600个左右。 现在被遗弃的Elasticsearch和docker是兵强接手,这大神以前是百度做底层开发的,水平很nb。。。  

嗯,最近总是有网站爬取我的文章,标注下原文地址,http://xiaorui.cc   

    因为我这边有个业务是buzz爬虫相关的。 计划把几百个 proxy端和爬虫端放在docker上运行,避免以前用openstack iaas那样,浪费了虚拟os的消耗 ~     上次搞docker的时候还是在乐视,现在隔了半年再玩docker,发现很多东西都忘了…. 甚至是基本的运行的概念…. 伤不起,所以这次把遇到的docker启动后总是退出的问题描述下。   


下篇文章会写 爬虫的ip轮训技术,避免因为某个ip过度的访问某个站点,被封杀… …

这是我的docker测试环境,ubuntu 14.04,具体的docker的安装,大家可以看看我以前的文章,这里就不再复述了 !

大家会看到,我启动了一个容器,但是查看状态是 Exited (0)

如果gorun 是个python daemon写的服务端,如果run 执行,他的状态肯定是exited退出的? 为啥? docker只是能监控一个服务, 如果这个服务退出了,没有往前台扔数据的话,对于docker来说,他还是会判断你的程序是退出的。 


那么怎么解决 ~

可以在gorun里面加上一条while 1;do sleep 1;done的语句, 这样你再执行的时候,docker会锁定最后一个命令,因为最后一个命令是死循环,所以容器也就不会退出了。

那么问题来了?  

注释: docker stop命令向Docker容器进程发送SIGTERM信号。如果你想快速停止某个容器,也可以使用docker kill命令向容器进程
Usage: docker kill CONTAINER [CONTAINER...]
杀死一个正在运行的容器(发送终止信号)
Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
关闭一个容器
-t=10: 等待停止容器需要的时间
这个容器主进程接收终止进程信号,在一段时间内,终止

接着上面的那个场景, 如果你docker stop 651ed2b898c9 停止这个容器,docker其实会运行的是给刚才的那个命令(while sleep)传递一个SIGTERM信号,他接收到后会退出。  但是和while同时执行的那几个命令就很有可能成为僵尸程序了… …因为他不是正常退出的

那么docker因为退出的问题,引起的僵尸进程问题我们该如何解决?

可以自己写个python程序,当 sudo docker run -t -i centos:centos6 /bin/gorun的时候,gorun 调用subprocess的模块调用第三方的脚本,然后取出pid进程号,紧接着做signal的信号监听。  当接受到外面进来的信号,可以是各种信号,再进行kill处理 !

shell下,也有类似的监听方式:

如果不想自己控制信号,那么可以用supervisord或者是monit来控制,强烈推荐使用supervisord,原因是配置相当简单,可以控制进程的数目.  另外如果你是python应用,可以使用下我写的Master Worker进程管理模块,他功能跟supervisord类似,都可以保护好真正的worker进程。

ProcessHandler进程管理模块的地址:   https://github.com/rfyiamcool/ProcessHandler

monit的是使用教程:

http://xiaorui.cc/2014/07/13/%E4%BD%BF%E7%94%A8monit%E5%AE%9E%E7%8E%B0%E8%BF%9B%E7%A8%8B%E7%9B%91%E6%8E%A7%E7%AE%A1%E7%90%86/

简单说下supervisord的用法:

Linux的Signal信号列表


2017-10-10 更新:

同事朱伟写了一个docker优雅退出的demo,用shell脚本做enterpoint,  请移步到 https://github.com/vearne/graceful_docker 



END .


对Golang感兴趣的朋友可以加群: 278517979 !!!
另外如果大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码, 感谢!
另外再次标注博客原地址  xiaorui.cc

14 Responses

  1. 上海蝎子 2015年12月3日 / 下午4:22

    -d 参数为啥不用呢,峰云大神。

  2. Docker小白 2015年11月13日 / 下午4:56

    没看明白

  3. 磊磊 2015年7月22日 / 下午12:33

    我现在用docker启动jetty 但是不知道怎么用jetty来启动一个java程序,是把java的war放进jetyy所在的容器里 是这样吗 在线等或者1078030014qq在线等您老指点

  4. 磊磊 2015年7月22日 / 下午12:31

    在吗大神求助一下 docker

  5. 沈灿 2015年1月11日 / 下午5:14

    大神你好 自从看了你的博客后 我终于找到了一个2000一月的网管工作了 感谢大神

    • 峰云 2015年1月11日 / 下午6:52

      傻逼呀,上次还4000多

      • 沈灿 2015年1月11日 / 下午9:44

        上次那个 被开了 你说的这些 都没用上

        • 峰云 2015年1月12日 / 上午10:37

          麻痹呀,没提我的名字?

          • 默默无言 2015年8月18日 / 下午12:00

            提了,给的更少了

          • 传说 2016年11月15日 / 下午2:17

            看来你是没有提我的名字

  6. 挖墙脚 2015年1月9日 / 下午10:13

    峰云来我们这里吧

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">