前言:
嗯哼,前段时间公司搞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的安装,大家可以看看我以前的文章,这里就不再复述了 !
docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE <none> <none> def2e0b08cbc About an hour ago 1.37 GB spider latest f0bec095f291 2 hours ago 614.6 MB gitlab latest bf5c375d9057 3 days ago 635.1 MB <none> <none> 9cbaf023786c 3 days ago 192.8 MB sameersbn/postgresql latest 24a6064fa4cd 10 days ago 142.1 MB <none> <none> 48648094d099 5 weeks ago 997.9 MB <none> <none> 195fa62e92a8 6 weeks ago 496.4 MB training/webapp latest 31fa814ba25a 4 months ago 278.8 MB ..... .... ....
大家会看到,我启动了一个容器,但是查看状态是 Exited (0)
docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 05ded2b898c9 test:supervisor-v1 "/bin/gorun 22 seconds ago Exited (0) 21 seconds ago hungry_engelbart
如果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下,也有类似的监听方式:
#!/bin/bash #from xiaorui.cc echo starting up function shut_down() { echo shutting down pid=(ps -e | grep xiaorui.cc | grep -v grep| awk '{print1}') kill -SIGTERM pid } trap "shut_down" SIGKILL SIGTERM SIGHUP SIGINT EXIT flag=1 while [flag -ne 0 ];do sleep 3; flag=`ps -ef| grep xiaorui.cc |grep -v grep | wc -l` done; # xiaorui.cc
如果不想自己控制信号,那么可以用supervisord或者是monit来控制,强烈推荐使用supervisord,原因是配置相当简单,可以控制进程的数目. 另外如果你是python应用,可以使用下我写的Master Worker进程管理模块,他功能跟supervisord类似,都可以保护好真正的worker进程。
ProcessHandler进程管理模块的地址: https://github.com/rfyiamcool/ProcessHandler
monit的是使用教程:
简单说下supervisord的用法:
编辑Dockerfile vim Dockerfile FROM ubuntu:14.04 MAINTAINER debugo@sina.com RUN apt-get update RUN apt-get install -y openssh-server supervisor RUN mkdir -p /var/run/sshd RUN mkdir -p /var/log/supervisor COPY supervisord.conf /etc/supervisor/supervisord.conf EXPOSE 22 80 CMD ["/usr/bin/supervisord"] 编辑supervisord配置文件 vim supervisord.conf [supervisord] nodaemon=true [program:sshd] command=/usr/sbin/sshd -D autorestart=unexpected autostart=true
Linux的Signal信号列表
kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
2017-10-10 更新:
同事朱伟写了一个docker优雅退出的demo,用shell脚本做enterpoint, 请移步到 https://github.com/vearne/graceful_docker
END .
-d 参数为啥不用呢,峰云大神。
没看明白
顶起来!!不好碰到的好文章
我现在用docker启动jetty 但是不知道怎么用jetty来启动一个java程序,是把java的war放进jetyy所在的容器里 是这样吗 在线等或者1078030014qq在线等您老指点
在吗大神求助一下 docker
真叼!!
大神!
大神你好 自从看了你的博客后 我终于找到了一个2000一月的网管工作了 感谢大神
傻逼呀,上次还4000多
上次那个 被开了 你说的这些 都没用上
麻痹呀,没提我的名字?
提了,给的更少了
看来你是没有提我的名字
峰云来我们这里吧