在docker中出现的僵尸进程怎么处理
- GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
一、发现问题
小玲是一名数据库测试人员,这一天她尝试在docker环境中部署GreatDB集群,结果在对greatsqld进程进行kill操作后,意外发现greatsqld进程变成了僵尸进程(如下图所示)。

由于小玲成为测试人员的时间较短,她没有遇见过这种情况,所以无法第一时间判断这个现象,是她的操作失误导致的合理现象,还是一个新发现的bug。
于是她进行了以下尝试:
- 1.在物理机上重复上述操作,并没有出现僵尸进程。
- 2.在docker内,对MySQL的mysqld进程进行相同操作,出现了僵尸进程。
通过这样的尝试,小玲初步判断出docker环境才是产生僵尸进程的根源,但具体是什么原因,又该如何避免,还需要小玲的进一步探索。
二、僵尸进程简介
首先需要搞清楚的是:
僵尸进程是什么?
僵尸进程又是如何形成的?
以下定义内容和解决办法来自维基百科。
僵尸进程:
在类UNIX系统中,僵尸进程是指完成执行(通过exit系统调用,或运行时发生致命错误或收到终止信号所致),但在操作系统的进程表中仍然存在其进程控制块(PCB),处于"终止状态"的进程。
僵尸进程不能被杀死,因为它们已经死亡,只等待它们的父进程回收它们。
通过这样的概念,和其他一些相关材料,小玲了解了僵尸进程的出现,问题多半是出现僵尸进程的父进程上。
这时,小玲看到了一个比较简单粗暴的解决办法,就是直接将僵尸进程的父进程杀死。她立刻去实践了一番,可惜她又失败了。


在docker中,她kill产生的僵尸进程的父进程PID是1,而1这个进程在docker内部是kill不掉的;如果在docker外部的物理机找到1的对应进程进行kill,则会将整个容器杀死。
三、孤儿进程的出现
小玲并不气馁,她继续通过搜索引擎进行探索学习,很快她就了解到更多的概念。
当进程的父进程id变为1的时候,这个进程也有了专门定义的称谓,叫做孤儿进程。
孤儿进程:
父进程结束后仍在运行的子进程。
没有了父进程总要有人“照顾”它。
在类UNIX操作系统中,为避免孤儿进程退出时无法释放所占用的资源而僵死,任何孤儿进程产生时都会立即被系统进程init或systemd自动接收为子进程,这一过程也被称为“收养”。
在此需注意,虽然事实上该进程已有init作为其父进程,但由于创建该进程的进程已不存在,所以仍应称之为“孤儿进程”。
根据上面的解释,又引出来一个概念,init 进程。我们也来看下它的定义。
init进程:
是 Unix 和 类Unix 系统中用来产生其它所有进程的程序。它以守护进程的方式存在,其进程号为1。
init进程是特殊的:它不获得它不想处理的信号,因此它可以忽略SIGKILL。
这里又有个新概念,SIGKILL信号。
一般我们kill进程是发信号给进程,然后被进程捕获之后执行对应操作。主要需要了解的信号有下面3种。都是来终止进程使用的。

四、整理现象发生的过程
小玲已经清楚这个现象跟GreatDB和MySQL都没有关系了,于是使用sleep命令继续尝试。
进入容器,执行命令。此时子进程PID是61,父进程PID是44,父进程是bash。

退出容器,再进入容器。PID是44的bash进程因为退出容器的操作被杀死,子进程61就被init收养了,父进程的PID就变成了1。

杀掉这个进程61,然后查看这个进程状态,发现它已经成为一个僵尸进程。

到这里,小玲就已经很接近问题的真相了:docker容器在默认的参数配置下,其init进程并没有处理孤儿进程的能力。
对于这个问题,docker的开发者们已经考虑到了。
五、如何处理docker中的僵尸进程
有两个解决办法可以让docker的init进程能够处理孤儿进程。
1.启动docker容器时,指定init进程为bash,由bash进程对孤儿进程的资源进行回收。
2.增加专门的 init 进程,比如 tini。
我们可以去docker官方文档找到答案:
The container’s main process is responsible for managing all processes that it starts.
In some cases, the main process isn’t well-designed, and doesn’t handle “reaping” (stopping) child processes gracefully when the container exits.
If your process falls into this category, you can use the --init option when you run the container.
The --init flag inserts a tiny init-process into the container as the main process, and handles reaping of all processes when the container exits.
Handling such processes this way is superior to using a full-fledged init process such as sysvinit, upstart, or systemd to handle process lifecycle within your container.
根据文档建议,可以在启动容器时候加上 --init 参数,开始使用tini。这样会有一个tiny的进程来负责进程"收养"之后的处理工作。
接下来我们分别对两种方法进行验证。
5.1 bash 处理
我们尝试将启动容器的命令指定为bash来启动一个容器test01,来看下这个容器会不会出现文章开头的问题。
启动容器,指定命令为bash。这个镜像基于CentOS 7的镜像,装了一些常用的包。

进入test01,确认id为1的进程。

执行sleep 700s &,然后查看父进程id为16,子进程id为33。

退出,重新登录容器test01,查看进程33的父进程,已经被init进程“领养”。

kill 进程33。然后check进程33。发现33没有成为僵尸,已经彻底被终止了。

从上面步骤来看,指定启动命令为bash确实可以解决我们遇到的问题。
5.2 tini 处理
再来试下tini,它是使用C语言写的一个tiny级的init进程,github对此有详细的介绍。
这是一个相当轻量级的init系统,相比较传统的Upstart、Systemd、SysV init 之类的大型系统使用起来更加的优秀。
现在我们在启动docker容器时时候加上--init参数,来看下效果。
加上init参数,启动容器test02,启动命令使用tail -f /dev/null,然后登录查看进程情况。

登录test02,执行sleep 700s &。查看父子进程id。

退出登录。

再次登录之后,查看进程的父进程id。

kill进程,检查进程是否彻底终止。已经看到没有僵尸进程。

六、总结
在使用tail -f /dev/null作为docker容器的init进程时,如果不加上--init参数,就会因为init进程没有处理孤儿进程的能力,而导致僵尸进程的出现。
在这种情况下,我们可以将tail -f /dev/null替换成bash,或是加上--init来解决这个问题。
文章推荐:
GreatSQL MGR FAQ
https://mp.weixin.qq.com/s/J6wkUpGXw3YkyEUJXiZ9xA
万答#12,MGR整个集群挂掉后,如何才能自动选主,不用手动干预
https://mp.weixin.qq.com/s/07o1poO44zwQIvaJNKEoPA
『2021数据技术嘉年华·ON LINE』:《MySQL高可用架构演进及实践》
https://mp.weixin.qq.com/s/u7k99y6i7riq7ScYs7ySnA
一条sql语句慢在哪之抓包分析
https://mp.weixin.qq.com/s/AYibbzl860D90rOeyjB6IQ
万答#15,都有哪些情况可能导致MGR服务无法启动
https://mp.weixin.qq.com/s/inSGpd0Q_XIl2Mb-VsvNsA
技术分享 | 为什么MGR一致性模式不推荐AFTER
https://mp.weixin.qq.com/s/rNeq479RNsklY1BlfKOsYg
关于 GreatSQL
GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。
Gitee:
https://gitee.com/GreatSQL/GreatSQL
GitHub:
https://github.com/GreatSQL/GreatSQL
Bilibili:
https://space.bilibili.com/1363850082/video
微信&QQ群:
可搜索添加GreatSQL社区助手微信好友,发送验证信息“加群”加入GreatSQL/MGR交流微信群
QQ群:533341697
微信小助手:wanlidbc
本文由博客一文多发平台 OpenWrite 发布!
在docker中出现的僵尸进程怎么处理的更多相关文章
- Linux 系统中僵尸进程
Linux 系统中僵尸进程和现实中僵尸(虽然我也没见过)类似,虽然已经死了,但是由于没人给它们收尸,还能四处走动.僵尸进程指的是那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸.配图源 ...
- 【转】Linux杀死fork产生的子进程的僵尸进程defunct
僵尸进程 就是 已经结束,但是还没有清理出去的.用kill -9 $PID 也无法杀死. 所以程序中应该避免出现僵尸进程. 用fork之后,父进程如果没有wait /waitpid 等待子进程的话,子 ...
- linux清理僵尸进程
查看服务器时发现好3个僵尸进程,僵尸进程存在好多天了,一直不会处理,留到了今天,顺便清理下僵尸进程吧 top命令中统计了僵尸进程,是第二行最后一项3 zombie. 或者使用下面的命令得到僵尸进程数量 ...
- Perl进程:僵尸进程和孤儿进程
概念 僵尸进程:当子进程退出时,父进程还没有(使用wait或waitpid)接收其退出状态时,子进程就成了僵尸进程 孤儿进程:当子进程还在运行时,父进程先退出了,子进程就会成为孤儿进程被pid=1的i ...
- Linux 僵尸进程
Linux 允许进程查询内核以获得其父进程的 PID,或者其任何子进程的执行状态.例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止.如果子进 ...
- Linux上寻找并杀死僵尸进程
转载: http://blog.csdn.net/shanzhizi/article/details/47320595 linux服务器上,多少会出现一些僵尸进程,下面介绍如何快速寻找和消灭这些僵尸进 ...
- Linux 僵尸进程如何处理
Linux 允许进程查询内核以获得其父进程的 PID,或者其任何子进程的执行状态.例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止.如果子进 ...
- 【zombie】如何查看并杀死僵尸进程?
[zombie]如何查看并杀死僵尸进程? 赏金Micheal关注 2019.03.31 19:40:15字数 1,016阅读 4,373 僵尸进程定义 In UNIX System terminolo ...
- Linux 性能分析调优 (四)——案例篇:系统中出现大量不可中断进程和僵尸进程怎么办
之前讲到 CPU 使用率的类型.除了上一节提到的用户 CPU 之外,它还包括系统 CPU(比如上下文切换).等待 I/O 的 CPU(比如等待磁盘的响应)以及中断 CPU(包括软中断和硬中断)等. 在 ...
随机推荐
- CentOS下安装与配置Maven
安装Maven 当前系统 [root@141 ~]# cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) 下载 http://ma ...
- 150_1秒获取Power BI Pro帐号
博客:www.jiaopengzi.com 请点击[阅读原文]获取帐号 一.背景 当你来到这篇文章的时候,我想你已经在网上搜索了一圈了.网上有一大把教你如何注册Power BI帐号的方法,我们这里就不 ...
- AMS 新闻视频广告的云原生容器化之路
作者 卓晓光,腾讯广告高级开发工程师,负责新闻视频广告整体后台架构设计,有十余年高性能高可用海量后台服务开发和实践经验.目前正带领团队完成云原生技术栈的全面转型. 吴文祺,腾讯广告开发工程师,负责新闻 ...
- 【算法】Floyd算法
什么是Floyd Floyd用于求最短路程.举个栗子,给你一张图,让你求出点[1]到点[5]的最短路程,你会怎么求? (画图工具:CS Academy) 如上图,有向边分别是 1->2 1-& ...
- Groovy基础语法
Groovy 基础语法 变量定义 1.支持动态类型,使用def关键字定义变量 // Java中定义变量的方式 int age = 18; String name = "张三"; / ...
- Training loop Run Builder
以下内容来自deeplizard pyorch_P31
- 一文澄清网上对 ConcurrentHashMap 的一个流传甚广的误解!
大家好,我是坤哥 上周我在极客时间某个课程看到某个讲师在讨论 ConcurrentHashMap(以下简称 CHM)是强一致性还是弱一致性时,提到这么一段话 这个解释网上也是流传甚广,那么到底对不对呢 ...
- 《ECMAScript 6 入门》【二、变量的解构赋值】(持续更新中……)
前言: 让我们看下es6的新语法解构,跟模式匹配类似.一.数组的解构赋值 举个例子给多个变量赋值的写法: var a =1;var b =2;var c =3; 需要写多个变量特别麻烦,我们先使用以前 ...
- Python量化-如何获取实时股票信息
如何获取实时股票信息 股票信息的接口有很多,之前大家常用的是新浪的,但在年初的时候,新浪的接口突然不能使用,给大家造成了很大的困扰,为此网上也有很多教程教大家如何从新浪获取数据,跟着教程弄了半天也不行 ...
- 论文解读(LG2AR)《Learning Graph Augmentations to Learn Graph Representations》
论文信息 论文标题:Learning Graph Augmentations to Learn Graph Representations论文作者:Kaveh Hassani, Amir Hosein ...